From 8303597a865400a363ae574ccde819302495f498 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 2 Apr 2013 18:41:01 +0200 Subject: Just put everything new in. Conflict resolution will be later --- .../ClientFiles/FlightGear/win32/start_fg.bat | 1 + facetracknoir/ClientFiles/Tir4Fun/readme.txt | 18 +- facetracknoir/facetracknoir.cpp | 1572 +++++++++----------- facetracknoir/facetracknoir.h | 177 ++- facetracknoir/facetracknoir.ico | Bin 0 -> 23558 bytes facetracknoir/facetracknoir.rc | 84 +- facetracknoir/ftnoir_curves.ui | 930 +++++++----- facetracknoir/ftnoir_fsuipccontrols.ui | 4 +- facetracknoir/ftnoir_ftnservercontrols.ui | 2 +- facetracknoir/ftnoir_keyboardshortcuts.ui | 316 +--- facetracknoir/ftnoir_preferences.ui | 2 +- facetracknoir/global-settings.cpp | 142 ++ facetracknoir/global-settings.h | 85 ++ facetracknoir/global-shortcuts.cpp | 135 ++ facetracknoir/images/facetracknoir.ico | Bin 0 -> 23558 bytes facetracknoir/main.cpp | 20 +- facetracknoir/posix-version-script.txt | 8 + facetracknoir/rotation.cpp | 2 +- facetracknoir/rotation.h | 2 +- facetracknoir/spot.h | 27 + facetracknoir/tracker.cpp | 1186 ++++----------- facetracknoir/tracker.h | 278 ++-- facetracknoir/tracker_types.h | 6 +- facetracknoir/uielements/facetracknoir.ico | Bin 0 -> 23558 bytes facetracknoir/uielements/setupfacetracknoir.jpg | Bin 0 -> 21508 bytes 25 files changed, 2219 insertions(+), 2778 deletions(-) create mode 100644 facetracknoir/ClientFiles/FlightGear/win32/start_fg.bat create mode 100644 facetracknoir/facetracknoir.ico create mode 100644 facetracknoir/global-settings.cpp create mode 100644 facetracknoir/global-settings.h create mode 100644 facetracknoir/global-shortcuts.cpp create mode 100644 facetracknoir/images/facetracknoir.ico create mode 100644 facetracknoir/posix-version-script.txt create mode 100644 facetracknoir/spot.h create mode 100644 facetracknoir/uielements/facetracknoir.ico create mode 100644 facetracknoir/uielements/setupfacetracknoir.jpg (limited to 'facetracknoir') diff --git a/facetracknoir/ClientFiles/FlightGear/win32/start_fg.bat b/facetracknoir/ClientFiles/FlightGear/win32/start_fg.bat new file mode 100644 index 00000000..cd9829b5 --- /dev/null +++ b/facetracknoir/ClientFiles/FlightGear/win32/start_fg.bat @@ -0,0 +1 @@ +fgfs --generic=socket,in,25,localhost,5550,udp,headtracker --generic=socket,out,10,localhost,5551,udp,headtracker --prop:browser=/sim/headtracker "c:\Program Files\FlightGear\data\Nasal\headtracker.xml" \ No newline at end of file diff --git a/facetracknoir/ClientFiles/Tir4Fun/readme.txt b/facetracknoir/ClientFiles/Tir4Fun/readme.txt index 010510db..d64af301 100644 --- a/facetracknoir/ClientFiles/Tir4Fun/readme.txt +++ b/facetracknoir/ClientFiles/Tir4Fun/readme.txt @@ -1,9 +1,9 @@ -What is TIR4FUN? - -TIR4FUN is a free utility for dedicated gamers. It enables 6DOF POV control with mouse and joystick axes. - -Software is provided as it is. Configuration is straightforward. GUI says it all! - -Installation: - -Copy all files to a directory. Launch tir4fun.exe to bring up the GUI. +What is TIR4FUN? + +TIR4FUN is a free utility for dedicated gamers. It enables 6DOF POV control with mouse and joystick axes. + +Software is provided as it is. Configuration is straightforward. GUI says it all! + +Installation: + +Copy all files to a directory. Launch tir4fun.exe to bring up the GUI. diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index cd4e0a4d..5afdbc6d 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -23,7 +23,6 @@ *********************************************************************************/ /* Modifications (last one on top): - 20130201 - WVR: Load FreeTrack 2.0 protocol instead of fake TrackIR (which is now obsolete). 20130101 - WVR: Added "None" to filter-listbox to remove "use advanced filtering". 20121209 - WVR: Pre-v170 DLLs will not be added to the Listbox. Initial selection was changed (made case-insensitive). 20121014 - WVR: Added second Tracker Source for Arduino solution. The two will be mutually exclusive. @@ -33,7 +32,7 @@ Also disable combo and buttons after 'Start'. 20120917 - WVR: Added Mouse-buttons to ShortKeys. 20120717 - WVR: FunctionConfig is now used for the Curves, instead of BezierConfig. - 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled ´statically´. Now, a Dir() of the + 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled 'statically'. Now, a Dir() of the EXE-folder is done, to locate Protocol-DLLs. The Icons were also moved to the DLLs 20120317 - WVR: The Filter and Tracker-code was moved to separate DLLs. The calling-method was changed accordingly. The save() and LoadSettings() functions were adapted. @@ -46,21 +45,158 @@ 20110207 - WVR: RadioButtons for 'Stop engine' added. It is now possible to choose Stop or Keep tracking. 20110109 - WVR: Added minimizeTaskBar option added. It is now possible to choose minimized or tray. */ -#include "FaceTrackNoIR.h" +#include "facetracknoir.h" #include "tracker.h" +#include +#include + +#if defined(__WIN32) || defined(_WIN32) +# include +#endif + +#if defined(__APPLE__) +# define SONAME "dylib" +#elif defined(_WIN32) || defined(__WIN32) +# define SONAME "dll" +#else +# define SONAME "so" +#endif + +#include + +#if defined(__WIN32) || defined(_WIN32) +#define DIRECTINPUT_VERSION 0x0800 +#include +#include + +KeybindingWorkerDummy::~KeybindingWorkerDummy() { + if (dinkeyboard) { + dinkeyboard->Unacquire(); + dinkeyboard->Release(); + } + if (din) + din->Release(); +} + +KeybindingWorkerDummy::KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter, Key keyInhibit, Key keyStartStop, Key keyZero) +: kCenter(keyCenter), kInhibit(keyInhibit), kStartStop(keyStartStop), kZero(keyZero), window(w), should_quit(true), din(0), dinkeyboard(0) +{ + if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&din, NULL) != DI_OK) { + qDebug() << "setup DirectInput8 Creation failed!" << GetLastError(); + return; + } + if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) { + din->Release(); + din = 0; + qDebug() << "setup CreateDevice function failed!" << GetLastError(); + return; + } + if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) { + qDebug() << "setup SetDataFormat function failed!" << GetLastError(); + dinkeyboard->Release(); + dinkeyboard = 0; + din->Release(); + din = 0; + } + + if (dinkeyboard->SetCooperativeLevel(window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) { + dinkeyboard->Release(); + din->Release(); + din = 0; + dinkeyboard = 0; + qDebug() << "setup SetCooperativeLevel function failed!" << GetLastError(); + return; + } + if (dinkeyboard->Acquire() != DI_OK) + { + dinkeyboard->Release(); + din->Release(); + din = 0; + dinkeyboard = 0; + qDebug() << "setup dinkeyboard Acquire failed!" << GetLastError(); + return; + } + qDebug() << "keycodes bound:" << kCenter.keycode << kInhibit.keycode << kStartStop.keycode << kZero.keycode; + should_quit = false; +} + +#define PROCESS_KEY(k, s) \ + if (isKeyPressed(&k, keystate) && (!k.ever_pressed ? (k.timer.start(), k.ever_pressed = true) : k.timer.restart() > 100)) \ + window.s(); + +static bool isKeyPressed( const Key *key, const BYTE *keystate ) { + bool shift; + bool ctrl; + bool alt; + + if (keystate[key->keycode] & 0x80) { + shift = ( (keystate[DIK_LSHIFT] & 0x80) || (keystate[DIK_RSHIFT] & 0x80) ); + ctrl = ( (keystate[DIK_LCONTROL] & 0x80) || (keystate[DIK_RCONTROL] & 0x80) ); + alt = ( (keystate[DIK_LALT] & 0x80) || (keystate[DIK_RALT] & 0x80) ); + + // + // If one of the modifiers is needed and not pressed, return false. + // + if (key->shift && !shift) return false; + if (key->ctrl && !ctrl) return false; + if (key->alt && !alt) return false; + + // + // All is well! + // + return true; + } + return false; +} -//#define USE_VISAGE +void KeybindingWorkerDummy::run() { + BYTE keystate[256]; + while (!should_quit) + { + if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) { + qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError(); + Sleep(25); + continue; + } + + PROCESS_KEY(kCenter, shortcutRecentered); + PROCESS_KEY(kInhibit, shortcutInhibit); + PROCESS_KEY(kZero, shortcutZero); + PROCESS_KEY(kStartStop, shortcutStartStop); + + Sleep(25); + } +} +#else +#endif + +#ifdef _MSC_VER +# define LIB_PREFIX "" +#else +# define LIB_PREFIX "lib" +#endif // // Setup the Main Dialog // FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WFlags flags) : -QMainWindow(parent, flags), -pTrackerDialog(NULL), -pSecondTrackerDialog(NULL), -pProtocolDialog(NULL), -pFilterDialog(NULL) + QMainWindow(parent, flags), + pTrackerDialog(NULL), + pSecondTrackerDialog(NULL), + pProtocolDialog(NULL), + pFilterDialog(NULL), + trayIcon(NULL), + trayIconMenu(NULL), +#if defined(__WIN32) || defined(_WIN32) + keybindingWorker(NULL), +#endif + keyCenter(), + keyZero(), + keyStartStop(), + keyInhibit(), + looping(false) { + GlobalPose = new HeadPoseData(); cameraDetected = false; // @@ -86,7 +222,7 @@ pFilterDialog(NULL) startTracker(); } - Q_INIT_RESOURCE(PoseWidget); + //Q_INIT_RESOURCE(PoseWidget); _pose_display = new GLWidget(ui.widget4logo, 0); _pose_display->rotateBy(0, 0, 0); @@ -107,8 +243,11 @@ pFilterDialog(NULL) /** sets up all objects and connections to buttons */ void FaceTrackNoIR::setupFaceTrackNoIR() { - - ui.setupUi(this); + ui.setupUi(this); + + // if we simply place a global variable with THeadPoseData, + // it gets initialized and pulls in QSettings before + // main() starts. program can and will crash. ui.headPoseWidget->show(); ui.video_frame->hide(); @@ -152,9 +291,6 @@ void FaceTrackNoIR::setupFaceTrackNoIR() { connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(startTracker())); connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stopTracker())); - // Connect slider for smoothing - connect(ui.slideSmoothing, SIGNAL(valueChanged(int)), this, SLOT(setSmoothing(int))); - //read the camera-name, using DirectShow GetCameraNameDX(); @@ -163,11 +299,14 @@ void FaceTrackNoIR::setupFaceTrackNoIR() { createActions(); createTrayIcon(); - connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); + if (trayIcon) + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); //Load the tracker-settings, from the INI-file loadSettings(); - trayIcon->show(); + + if (trayIcon) + trayIcon->show(); connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); connect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int))); @@ -183,7 +322,7 @@ void FaceTrackNoIR::setupFaceTrackNoIR() { connect(timUpdateHeadPose, SIGNAL(timeout()), this, SLOT(showHeadPose())); ui.txtTracking->setVisible(false); ui.txtAxisReverse->setVisible(false); - ui.gameName->setText(""); + settingsDirty = false; } /** destructor stops the engine and quits the faceapi **/ @@ -217,15 +356,6 @@ FaceTrackNoIR::~FaceTrackNoIR() { } } -// -// Get the ProgramName from a connected game and display it. -// -void FaceTrackNoIR::getGameProgramName() { - if ( tracker != NULL ) { - ui.gameName->setText( tracker->getGameProgramName() ); - } -} - // // Update the Settings, after a value has changed. This way, the Tracker does not have to re-start. // @@ -238,68 +368,14 @@ void FaceTrackNoIR::updateSettings() { // // Get a pointer to the video-widget, to use in the DLL // -QFrame *FaceTrackNoIR::getVideoWidget() { +QFrame *FaceTrackNoIR::get_video_widget() { return ui.video_frame; } -// -// Return the name of the Protocol-DLL -// -QString FaceTrackNoIR::getCurrentProtocolName() -{ - if (ui.iconcomboProtocol->currentIndex() < 0) { - return QString(""); - } - else { - return protocolFileList.at(ui.iconcomboProtocol->currentIndex()); - } -} - -// -// Return the name of the Filter-DLL -// -QString FaceTrackNoIR::getCurrentFilterName() -{ - qDebug() << "getCurrentFilterName says: " << ui.iconcomboFilter->currentIndex(); - if (ui.iconcomboFilter->currentIndex() <= 0) { - return QString("None"); - } - else { - return filterFileList.at(ui.iconcomboFilter->currentIndex() - 1 ); - } -} - -// -// Return the name of the Tracker-DLL -// -QString FaceTrackNoIR::getCurrentTrackerName() -{ - if (ui.iconcomboTrackerSource->currentIndex() < 0) { - return QString(""); - } - else { - qDebug() << "FaceTrackNoIR::getCurrentTrackerName libName = " << trackerFileList.at(ui.iconcomboTrackerSource->currentIndex()); - return trackerFileList.at(ui.iconcomboTrackerSource->currentIndex()); - } -} - -// -// Return the name of the second Tracker-DLL -// -QString FaceTrackNoIR::getSecondTrackerName() -{ - if (ui.cbxSecondTrackerSource->currentIndex() <= 0) { - return QString("None"); - } - else { - return trackerFileList.at(ui.cbxSecondTrackerSource->currentIndex() - 1 ); - } -} - /** read the name of the first video-capturing device at start up **/ /** FaceAPI can only use this first one... **/ void FaceTrackNoIR::GetCameraNameDX() { - +#if 0 //// ui.widget->setCameraName("No video-capturing device was found in your system: check if it's connected!"); ui.cameraName->setText("No video-capturing device was found in your system: check if it's connected!"); @@ -356,7 +432,7 @@ void FaceTrackNoIR::GetCameraNameDX() { pEnumCat->Release(); } pSysDevEnum->Release(); - +#endif } // @@ -364,26 +440,24 @@ void FaceTrackNoIR::GetCameraNameDX() { // If succesfull, the settings in it will be read // void FaceTrackNoIR::open() { - QFileDialog::Options options; - QFileDialog::FileMode mode; - - options |= QFileDialog::DontUseNativeDialog; - mode = QFileDialog::ExistingFile; - QString selectedFilter; - QStringList fileNames = QFileDialog::getOpenFileNames( + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFile); + + QString fileName = dialog.getOpenFileName( this, tr("Select one FTNoir settings file"), - QCoreApplication::applicationDirPath() + "/Settings", - tr("Settings file (*.ini);;All Files (*)")); + QCoreApplication::applicationDirPath() + "/Settings/", + tr("Settings file (*.ini);;All Files (*)"), + NULL); // // If a file was selected, save it's name and read it's contents. // - if (! fileNames.isEmpty() ) { + if (! fileName.isEmpty() ) { QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) - settings.setValue ("SettingsFile", fileNames.at(0)); + settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath()); loadSettings(); - } + } } // @@ -397,7 +471,6 @@ void FaceTrackNoIR::save() { QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Tracking" ); - iniFile.setValue ( "Smooth", ui.slideSmoothing->value() ); iniFile.setValue ( "invertYaw", ui.chkInvertYaw->isChecked() ); iniFile.setValue ( "invertPitch", ui.chkInvertPitch->isChecked() ); iniFile.setValue ( "invertRoll", ui.chkInvertRoll->isChecked() ); @@ -407,21 +480,31 @@ void FaceTrackNoIR::save() { iniFile.endGroup (); iniFile.beginGroup ( "GameProtocol" ); - iniFile.setValue ( "Selection", ui.iconcomboProtocol->currentIndex() ); - iniFile.setValue ( "DLL", getCurrentProtocolName() ); + { + DynamicLibrary* proto = dlopen_protocols.value( ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", proto == NULL ? "" : proto->filename); + } iniFile.endGroup (); iniFile.beginGroup ( "TrackerSource" ); - iniFile.setValue ( "Selection", ui.iconcomboTrackerSource->currentIndex() ); - iniFile.setValue ( "DLL", getCurrentTrackerName() ); - iniFile.setValue ( "2ndDLL", getSecondTrackerName() ); + { + DynamicLibrary* tracker = dlopen_trackers.value( ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", tracker == NULL ? "" : tracker->filename); + } + { + DynamicLibrary* tracker = dlopen_trackers.value( ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL); + iniFile.setValue ( "2ndDLL", tracker == NULL ? "" : tracker->filename); + } iniFile.endGroup (); // // Save the name of the filter in the INI-file. // iniFile.beginGroup ( "Filter" ); - iniFile.setValue ( "DLL", getCurrentFilterName() ); + { + DynamicLibrary* filter = dlopen_filters.value( ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", filter == NULL ? "" : filter->filename); + } iniFile.endGroup (); settingsDirty = false; @@ -484,18 +567,21 @@ void FaceTrackNoIR::saveAs() // Load the current Settings from the currently 'active' INI-file. // void FaceTrackNoIR::loadSettings() { - + if (looping) + return; + looping = true; qDebug() << "loadSettings says: Starting "; QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + qDebug() << "Config file now" << currentFile; QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // // Put the filename in the window-title. // QFileInfo pathInfo ( currentFile ); - setWindowTitle ( "FaceTrackNoIR (1.7) - " + pathInfo.fileName() ); + setWindowTitle ( "FaceTrackNoIR (1.8 pre-alpha) - " + pathInfo.fileName() ); // // Get a List of all the INI-files in the (currently active) Settings-folder. @@ -509,22 +595,19 @@ void FaceTrackNoIR::loadSettings() { // // Add strings to the Listbox. // - disconnect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int))); ui.iconcomboProfile->clear(); for ( int i = 0; i < iniFileList.size(); i++) { - ui.iconcomboProfile->addItem(QIcon(":/images/Settings16.png"), iniFileList.at(i)); + ui.iconcomboProfile->addItem(QIcon(":/images/settings16.png"), iniFileList.at(i)); if (iniFileList.at(i) == pathInfo.fileName()) { - ui.iconcomboProfile->setItemIcon(i, QIcon(":/images/SettingsOpen16.png")); + ui.iconcomboProfile->setItemIcon(i, QIcon(":/images/settingsopen16.png")); ui.iconcomboProfile->setCurrentIndex( i ); } } - connect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int))); qDebug() << "loadSettings says: iniFile = " << currentFile; iniFile.beginGroup ( "Tracking" ); - ui.slideSmoothing->setValue (iniFile.value ( "Smooth", 10 ).toInt()); - ui.chkInvertYaw->setChecked (iniFile.value ( "invertYaw", 0 ).toBool()); + ui.chkInvertYaw->setChecked (iniFile.value ( "invertYaw", 0 ).toBool()); ui.chkInvertPitch->setChecked (iniFile.value ( "invertPitch", 0 ).toBool()); ui.chkInvertRoll->setChecked (iniFile.value ( "invertRoll", 0 ).toBool()); ui.chkInvertX->setChecked (iniFile.value ( "invertX", 0 ).toBool()); @@ -537,117 +620,61 @@ void FaceTrackNoIR::loadSettings() { // If the setting "DLL" isn't found (pre-1.7 version of INI), then the setting 'Selection' is evaluated. // iniFile.beginGroup ( "GameProtocol" ); + QString selectedProtocolName = iniFile.value ( "DLL", "" ).toString(); + iniFile.endGroup (); - QString selectedProtocolName = iniFile.value ( "DLL", "" ).toString(); - qDebug() << "loadSettings says: selectedProtocolName = " << selectedProtocolName; - - if (selectedProtocolName.length() == 0) { - int index = iniFile.value ( "Selection", 0 ).toInt(); - switch ( index ) { - case TRACKIR: - case FREE_TRACK: - selectedProtocolName = QString("FTNoIR_Protocol_FT.dll"); - break; - - case SIMCONNECT: - selectedProtocolName = QString("FTNoIR_Protocol_SC.dll"); - break; - - case PPJOY: - selectedProtocolName = QString("FTNoIR_Protocol_PPJOY.dll"); - break; - - case FSUIPC: - selectedProtocolName = QString("FTNoIR_Protocol_FSUIPC.dll"); - break; - - case FLIGHTGEAR: - selectedProtocolName = QString("FTNoIR_Protocol_FG.dll"); - break; - - case FTNOIR: - selectedProtocolName = QString("FTNoIR_Protocol_FTN.dll"); - break; - - case MOUSE: - selectedProtocolName = QString("FTNoIR_Protocol_MOUSE.dll"); - break; - - default: - selectedProtocolName = QString("FTNoIR_Protocol_MOUSE.dll"); - break; - } - } - iniFile.endGroup (); - - // + // // Find the Index of the DLL and set the selection. // - for ( int i = 0; i < protocolFileList.size(); i++) { - if (protocolFileList.at(i).compare( selectedProtocolName, Qt::CaseInsensitive ) == 0) { + for ( int i = 0; i < dlopen_protocols.size(); i++) { + if (dlopen_protocols.at(i)->filename.compare( selectedProtocolName, Qt::CaseInsensitive ) == 0) { ui.iconcomboProtocol->setCurrentIndex( i ); break; } } - // - // Read the currently selected Tracker from the INI-file. - // If the setting "DLL" isn't found (pre-1.7 version), then the setting 'Selection' is evaluated. - // - iniFile.beginGroup ( "TrackerSource" ); - QString selectedTrackerName = iniFile.value ( "DLL", "" ).toString(); - qDebug() << "loadSettings says: selectedTrackerName = " << selectedTrackerName; - if (selectedTrackerName.length() == 0) { - int index = iniFile.value ( "Selection", 0 ).toInt(); - switch ( index ) { - case 0: // Face API - selectedTrackerName = "FTNoIR_Tracker_SM.dll"; - break; - case 1: // FTNoir server - selectedTrackerName = "FTNoIR_Tracker_UDP.dll"; - break; - default: - selectedTrackerName = "FTNoIR_Tracker_SM.dll"; - break; - } - } - QString secondTrackerName = iniFile.value ( "2ndDLL", "None" ).toString(); - qDebug() << "loadSettings says: secondTrackerName = " << secondTrackerName; - - iniFile.endGroup (); - - disconnect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - disconnect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - for ( int i = 0; i < trackerFileList.size(); i++) { - if (trackerFileList.at(i).compare( selectedTrackerName, Qt::CaseInsensitive ) == 0) { + // + // Read the currently selected Tracker from the INI-file. + // If the setting "DLL" isn't found (pre-1.7 version), then the setting 'Selection' is evaluated. + // + iniFile.beginGroup ( "TrackerSource" ); + QString selectedTrackerName = iniFile.value ( "DLL", "" ).toString(); + qDebug() << "loadSettings says: selectedTrackerName = " << selectedTrackerName; + QString secondTrackerName = iniFile.value ( "2ndDLL", "None" ).toString(); + qDebug() << "loadSettings says: secondTrackerName = " << secondTrackerName; + iniFile.endGroup (); + + for ( int i = 0; i < dlopen_trackers.size(); i++) { + DynamicLibrary* foo = dlopen_trackers.at(i); + if (foo && foo->filename.compare( selectedTrackerName, Qt::CaseInsensitive ) == 0) { ui.iconcomboTrackerSource->setCurrentIndex( i ); } - if (trackerFileList.at(i).compare( secondTrackerName, Qt::CaseInsensitive ) == 0) { - ui.cbxSecondTrackerSource->setCurrentIndex( i + 1 ); // The first value = "None", so add 1 + if (foo && foo->filename.compare( secondTrackerName, Qt::CaseInsensitive ) == 0) { + ui.cbxSecondTrackerSource->setCurrentIndex( i + 1 ); } } - connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - connect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); // // Read the currently selected Filter from the INI-file. // iniFile.beginGroup ( "Filter" ); - QString selectedFilterName = iniFile.value ( "DLL", "FTNoIR_Filter_EWMA2.dll" ).toString(); + QString selectedFilterName = iniFile.value ( "DLL", "" ).toString(); qDebug() << "createIconGroupBox says: selectedFilterName = " << selectedFilterName; iniFile.endGroup (); // // Find the Index of the DLL and set the selection. // - for ( int i = 0; i < filterFileList.size(); i++) { - if (filterFileList.at(i).compare( selectedFilterName, Qt::CaseInsensitive ) == 0) { - ui.iconcomboFilter->setCurrentIndex( i + 1 ); // The first value = "None", so add 1 + for ( int i = 0; i < dlopen_filters.size(); i++) { + DynamicLibrary* foo = dlopen_filters.at(i); + if (foo && foo->filename.compare( selectedFilterName, Qt::CaseInsensitive ) == 0) { + ui.iconcomboFilter->setCurrentIndex( i ); break; } } settingsDirty = false; + looping = false; } /** show support page in web-browser **/ @@ -660,7 +687,6 @@ void FaceTrackNoIR::openurl_donation() { QDesktopServices::openUrl(QUrl("http://facetracknoir.sourceforge.net/information_links/donate.htm", QUrl::TolerantMode)); } - /** show about dialog **/ void FaceTrackNoIR::about() { @@ -676,11 +702,12 @@ void FaceTrackNoIR::about() { aboutDialog.setMinimumWidth(270); aboutDialog.setMinimumHeight(440); - aboutDialog.setStyleSheet("background:#fff url(:/UIElements/aboutFaceTrackNoIR.png) no-repeat;"); + aboutDialog.setStyleSheet("background:#fff url(:/uielements/aboutfacetracknoir.png) no-repeat;"); } /** start tracking the face **/ void FaceTrackNoIR::startTracker( ) { + bindKeyboardShortcuts(); // // Disable buttons @@ -694,14 +721,34 @@ void FaceTrackNoIR::startTracker( ) { // // Create the Tracker and setup // + + if (Libraries) + delete Libraries; + Libraries = new SelectedLibraries(this); + + if (!Libraries->correct) + { + QMessageBox::warning(this, "Something went wrong", "Tracking can't be initialized, probably protocol prerequisites missing", QMessageBox::Ok, QMessageBox::NoButton); + stopTracker(); + return; + } + +#if defined(_WIN32) || defined(__WIN32) + keybindingWorker = new KeybindingWorker(*this, keyCenter, keyInhibit, keyStartStop, keyZero); + keybindingWorker->start(); +#endif + + if (tracker) { + tracker->wait(); + delete tracker; + } + tracker = new Tracker ( this ); // // Setup the Tracker and send the settings. // This is necessary, because the events are only triggered 'on change' // - tracker->setup(); - tracker->setSmoothing ( ui.slideSmoothing->value() ); tracker->setInvertYaw (ui.chkInvertYaw->isChecked() ); tracker->setInvertPitch (ui.chkInvertPitch->isChecked() ); tracker->setInvertRoll (ui.chkInvertRoll->isChecked() ); @@ -709,13 +756,13 @@ void FaceTrackNoIR::startTracker( ) { tracker->setInvertY (ui.chkInvertY->isChecked() ); tracker->setInvertZ (ui.chkInvertZ->isChecked() ); - tracker->start( QThread::TimeCriticalPriority ); + tracker->start(); // // Register the Tracker instance with the Tracker Dialog (if open) // - if (pTrackerDialog) { - pTrackerDialog->registerTracker( tracker->getTrackerPtr() ); + if (pTrackerDialog && Libraries->pTracker) { + pTrackerDialog->registerTracker( Libraries->pTracker ); } ui.headPoseWidget->show(); @@ -728,7 +775,7 @@ void FaceTrackNoIR::startTracker( ) { ui.iconcomboTrackerSource->setEnabled ( false ); ui.cbxSecondTrackerSource->setEnabled ( false ); ui.iconcomboProtocol->setEnabled ( false ); -// ui.btnShowServerControls->setEnabled ( false ); + ui.btnShowServerControls->setEnabled ( false ); ui.iconcomboFilter->setEnabled ( false ); // @@ -736,7 +783,6 @@ void FaceTrackNoIR::startTracker( ) { // GetCameraNameDX(); - // // Get the TimeOut value for minimizing FaceTrackNoIR // Only start the Timer if value > 0 @@ -760,7 +806,7 @@ void FaceTrackNoIR::startTracker( ) { // // Start the timer to update the head-pose (digits and 'man in black') // - timUpdateHeadPose->start(50); + timUpdateHeadPose->start(40); ui.lblX->setVisible(true); ui.lblY->setVisible(true); @@ -780,13 +826,21 @@ void FaceTrackNoIR::startTracker( ) { /** stop tracking the face **/ void FaceTrackNoIR::stopTracker( ) { +#if defined(_WIN32) || defined(__WIN32) + if (keybindingWorker) + { + keybindingWorker->should_quit = true; + keybindingWorker->wait(); + delete keybindingWorker; + keybindingWorker = NULL; + } +#endif // // Stop displaying the head-pose. // timUpdateHeadPose->stop(); _pose_display->rotateBy(0, 0, 0); - ui.lblX->setVisible(false); ui.lblY->setVisible(false); ui.lblZ->setVisible(false); @@ -803,25 +857,33 @@ void FaceTrackNoIR::stopTracker( ) { ui.txtTracking->setVisible(false); ui.txtAxisReverse->setVisible(false); - // - // UnRegister the Tracker instance with the Tracker Dialog (if open) - // - if (pTrackerDialog) { - pTrackerDialog->unRegisterTracker(); - } - if (pProtocolDialog) { - pProtocolDialog->unRegisterProtocol(); - } - // // Delete the tracker (after stopping things and all). // - if ( tracker ) { + if ( tracker ) { + qDebug() << "Done with tracking"; + tracker->should_quit = true; + tracker->wait(); + qDebug() << "stopTracker says: Deleting tracker!"; delete tracker; qDebug() << "stopTracker says: Tracker deleted!"; tracker = 0; + if (Libraries) { + delete Libraries; + Libraries = NULL; + } } + + // + // UnRegister the Tracker instance with the Tracker Dialog (if open) + // + if (pTrackerDialog) { + pTrackerDialog->unRegisterTracker(); + } + if (pProtocolDialog) { + pProtocolDialog->unRegisterProtocol(); + } ui.btnStartTracker->setEnabled ( true ); ui.btnStopTracker->setEnabled ( false ); // ui.btnShowEngineControls->setEnabled ( false ); @@ -845,42 +907,47 @@ void FaceTrackNoIR::stopTracker( ) { // Stop the timer, so it won't go off again... // timMinimizeFTN->stop(); - } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertYaw( int invert ) { - Tracker::setInvertYaw ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertYaw ( (invert != 0)?true:false ); settingsDirty = true; } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertPitch( int invert ) { - Tracker::setInvertPitch ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertPitch ( (invert != 0)?true:false ); settingsDirty = true; } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertRoll( int invert ) { - Tracker::setInvertRoll ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertRoll ( (invert != 0)?true:false ); settingsDirty = true; } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertX( int invert ) { - Tracker::setInvertX ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertX ( (invert != 0)?true:false ); settingsDirty = true; } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertY( int invert ) { - Tracker::setInvertY ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertY ( (invert != 0)?true:false ); settingsDirty = true; } /** set the invert from the checkbox **/ void FaceTrackNoIR::setInvertZ( int invert ) { - Tracker::setInvertZ ( (invert != 0)?true:false ); + if (tracker) + tracker->setInvertZ ( (invert != 0)?true:false ); settingsDirty = true; } @@ -902,74 +969,39 @@ THeadPoseData newdata; ui.lcdNumOutputRotY->setVisible(true); ui.lcdNumOutputRotZ->setVisible(true); - if (!isMinimized()) { - - // - // Get the pose and also display it. - // Updating the pose from within the Tracker-class caused crashes... - // - Tracker::getHeadPose(&newdata); - ui.lcdNumX->display(QString("%1").arg(newdata.x, 0, 'f', 1)); - ui.lcdNumY->display(QString("%1").arg(newdata.y, 0, 'f', 1)); - ui.lcdNumZ->display(QString("%1").arg(newdata.z, 0, 'f', 1)); - - ui.lcdNumRotX->display(QString("%1").arg(newdata.yaw, 0, 'f', 1)); - ui.lcdNumRotY->display(QString("%1").arg(newdata.pitch, 0, 'f', 1)); - ui.lcdNumRotZ->display(QString("%1").arg(newdata.roll, 0, 'f', 1)); - - ui.txtTracking->setVisible(Tracker::getTrackingActive()); - ui.txtAxisReverse->setVisible(Tracker::getAxisReverse()); - - // - // Get the output-pose and also display it. - // - if (_pose_display) { - Tracker::getOutputHeadPose(&newdata); - _pose_display->rotateBy(newdata.pitch, newdata.yaw, newdata.roll); - - ui.lcdNumOutputPosX->display(QString("%1").arg(newdata.x, 0, 'f', 1)); - ui.lcdNumOutputPosY->display(QString("%1").arg(newdata.y, 0, 'f', 1)); - ui.lcdNumOutputPosZ->display(QString("%1").arg(newdata.z, 0, 'f', 1)); + // + // Get the pose and also display it. + // Updating the pose from within the Tracker-class caused crashes... + // + tracker->getHeadPose(&newdata); + ui.lcdNumX->display(QString("%1").arg(newdata.x, 0, 'f', 1)); + ui.lcdNumY->display(QString("%1").arg(newdata.y, 0, 'f', 1)); + ui.lcdNumZ->display(QString("%1").arg(newdata.z, 0, 'f', 1)); - ui.lcdNumOutputRotX->display(QString("%1").arg(newdata.yaw, 0, 'f', 1)); - ui.lcdNumOutputRotY->display(QString("%1").arg(newdata.pitch, 0, 'f', 1)); - ui.lcdNumOutputRotZ->display(QString("%1").arg(newdata.roll, 0, 'f', 1)); - } + ui.lcdNumRotX->display(QString("%1").arg(newdata.yaw, 0, 'f', 1)); + ui.lcdNumRotY->display(QString("%1").arg(newdata.pitch, 0, 'f', 1)); + ui.lcdNumRotZ->display(QString("%1").arg(newdata.roll, 0, 'f', 1)); - // - // Update the video-widget. - // Requested by Stanislaw - // - if (tracker) { - ITracker * theTracker = tracker->getTrackerPtr(); - if (theTracker) { - theTracker->refreshVideo(); - } - } - // Tracker::doRefreshVideo(); + ui.txtTracking->setVisible(tracker->getTrackingActive()); + ui.txtAxisReverse->setVisible(tracker->getAxisReverse()); - if (_curve_config) { - _curve_config->update(); - } - } - //else { - // qDebug() << "FaceTrackNoIR::showHeadPose status: window = minimized."; - //} -} - -/** set the smoothing from the slider **/ -void FaceTrackNoIR::setSmoothing( int smooth ) { - // - // Pass the smoothing setting, if the Tracker exists. + // Get the output-pose and also display it. // - if ( tracker ) { - tracker->setSmoothing ( smooth ); - settingsDirty = true; + if (_pose_display) { + tracker->getOutputHeadPose(&newdata); + _pose_display->rotateBy(newdata.pitch, newdata.yaw, newdata.roll); + + ui.lcdNumOutputPosX->display(QString("%1").arg(newdata.x, 0, 'f', 1)); + ui.lcdNumOutputPosY->display(QString("%1").arg(newdata.y, 0, 'f', 1)); + ui.lcdNumOutputPosZ->display(QString("%1").arg(newdata.z, 0, 'f', 1)); + + ui.lcdNumOutputRotX->display(QString("%1").arg(newdata.yaw, 0, 'f', 1)); + ui.lcdNumOutputRotY->display(QString("%1").arg(newdata.pitch, 0, 'f', 1)); + ui.lcdNumOutputRotZ->display(QString("%1").arg(newdata.roll, 0, 'f', 1)); } } - /** toggles Video Widget **/ void FaceTrackNoIR::showVideoWidget() { if(ui.video_frame->isHidden()) @@ -988,195 +1020,74 @@ void FaceTrackNoIR::showHeadPoseWidget() { /** toggles Engine Controls Dialog **/ void FaceTrackNoIR::showTrackerSettings() { -importGetTrackerDialog getIT; -QLibrary *trackerLib; -QString libName; - - qDebug() << "FaceTrackNoIR::showTrackerSettings started."; - - // - // Delete the existing QDialog - // if (pTrackerDialog) { delete pTrackerDialog; pTrackerDialog = NULL; } - // Show the appropriate Tracker Settings - libName.clear(); - libName = getCurrentTrackerName(); - - // - // Load the Server-settings dialog (if any) and show it. - // - if (!libName.isEmpty()) { - trackerLib = new QLibrary(libName); - -// qDebug() << "FaceTrackNoIR::showTrackerSettings Loaded trackerLib." << trackerLib; - - getIT = (importGetTrackerDialog) trackerLib->resolve("GetTrackerDialog"); - -// qDebug() << "FaceTrackNoIR::showTrackerSettings resolved." << getIT; - - if (getIT) { - ITrackerDialog *ptrXyz(getIT()); - if (ptrXyz) - { - pTrackerDialog = ptrXyz; - pTrackerDialog->Initialize( this ); -// qDebug() << "FaceTrackNoIR::showTrackerSettings GetTrackerDialog Function Resolved!"; - if (tracker) { - pTrackerDialog->registerTracker( tracker->getTrackerPtr() ); -// qDebug() << "FaceTrackNoIR::showTrackerSettings RegisterTracker Function Executed"; - } - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } + DynamicLibrary* lib = dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); + if (lib) { + pTrackerDialog = (ITrackerDialog*) lib->Dialog(); + if (pTrackerDialog) { + pTrackerDialog->Initialize(this); + if (Libraries && Libraries->pTracker) + pTrackerDialog->registerTracker(Libraries->pTracker); + } + } } // Show the Settings dialog for the secondary Tracker void FaceTrackNoIR::showSecondTrackerSettings() { -importGetTrackerDialog getIT; -QLibrary *trackerLib; -QString libName; - - qDebug() << "FaceTrackNoIR::showSecondTrackerSettings started."; - - // - // Delete the existing QDialog - // - if (pSecondTrackerDialog) { - delete pSecondTrackerDialog; - pSecondTrackerDialog = NULL; - } - - // Show the appropriate Tracker Settings - libName.clear(); - libName = getSecondTrackerName(); - - // - // Load the Server-settings dialog (if any) and show it. - // - if ((!libName.isEmpty()) && (libName != "None")) { - trackerLib = new QLibrary(libName); - -// qDebug() << "FaceTrackNoIR::showTrackerSettings Loaded trackerLib." << trackerLib; - - getIT = (importGetTrackerDialog) trackerLib->resolve("GetTrackerDialog"); - -// qDebug() << "FaceTrackNoIR::showTrackerSettings resolved." << getIT; + if (pSecondTrackerDialog) { + delete pSecondTrackerDialog; + pSecondTrackerDialog = NULL; + } - if (getIT) { - ITrackerDialog *ptrXyz(getIT()); - if (ptrXyz) - { - pSecondTrackerDialog = ptrXyz; - pSecondTrackerDialog->Initialize( this ); -// qDebug() << "FaceTrackNoIR::showTrackerSettings GetTrackerDialog Function Resolved!"; - if (tracker) { - pSecondTrackerDialog->registerTracker( tracker->getSecondTrackerPtr() ); -// qDebug() << "FaceTrackNoIR::showTrackerSettings RegisterTracker Function Executed"; - } - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } + DynamicLibrary* lib = dlopen_trackers.value(ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL); + if (lib) { + pSecondTrackerDialog = (ITrackerDialog*) lib->Dialog(); + if (pSecondTrackerDialog) { + pSecondTrackerDialog->Initialize(this); + if (Libraries && Libraries->pSecondTracker) + pSecondTrackerDialog->registerTracker(Libraries->pSecondTracker); + } + } } /** toggles Server Controls Dialog **/ void FaceTrackNoIR::showServerControls() { -importGetProtocolDialog getIT; -QLibrary *protocolLib; -QString libName; - - // - // Delete the existing QDialog - // - if (pProtocolDialog) { - delete pProtocolDialog; - } - - // Show the appropriate Protocol-server Settings - libName.clear(); - libName = getCurrentProtocolName(); + if (pProtocolDialog) { + delete pProtocolDialog; + pProtocolDialog = NULL; + } - // - // Load the Server-settings dialog (if any) and show it. - // - if (!libName.isEmpty()) { - protocolLib = new QLibrary(libName); + DynamicLibrary* lib = dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); - getIT = (importGetProtocolDialog) protocolLib->resolve("GetProtocolDialog"); - if (getIT) { - IProtocolDialogPtr ptrXyz(getIT()); - if (ptrXyz) - { - pProtocolDialog = ptrXyz; - pProtocolDialog->Initialize( this ); - if (tracker) { - pProtocolDialog->registerProtocol( tracker->getProtocolPtr() ); - qDebug() << "FaceTrackNoIR::showServerControls RegisterProtocol Function Executed"; - } - qDebug() << "FaceTrackNoIR::showServerControls GetProtocolDialog Function Resolved!"; - } - else { - qDebug() << "FaceTrackNoIR::showServerControls Function NOT Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } + if (lib && lib->Dialog) { + pProtocolDialog = (IProtocolDialog*) lib->Dialog(); + if (pProtocolDialog) { + pProtocolDialog->Initialize(this); + } + } } /** toggles Filter Controls Dialog **/ void FaceTrackNoIR::showFilterControls() { -importGetFilterDialog getIT; -QLibrary *filterLib; -QString libName; - - // - // Delete the existing QDialog - // - if (pFilterDialog) { - delete pFilterDialog; - pFilterDialog = NULL; - } - - // Get the currently selected Filter - libName.clear(); - libName = getCurrentFilterName(); + if (pFilterDialog) { + delete pFilterDialog; + pFilterDialog = NULL; + } - // - // Load the Filter-settings dialog (if any) and show it. - // - if (!libName.isEmpty()) { - filterLib = new QLibrary(libName); + DynamicLibrary* lib = dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); - getIT = (importGetFilterDialog) filterLib->resolve("GetFilterDialog"); - if (getIT) { - IFilterDialogPtr ptrXyz(getIT()); - if (ptrXyz) - { - pFilterDialog = ptrXyz; - pFilterDialog->Initialize( this, Tracker::getFilterPtr() ); - qDebug() << "FaceTrackNoIR::showFilterControls GetFilterDialog Function Resolved!"; - } - else { - qDebug() << "FaceTrackNoIR::showFilterControls Function NOT Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } + if (lib && lib->Dialog) { + pFilterDialog = (IFilterDialog*) lib->Dialog(); + if (pFilterDialog) { + pFilterDialog->Initialize(this, Libraries ? Libraries->pFilter : NULL); + } + } } /** toggles FaceTrackNoIR Preferences Dialog **/ @@ -1237,160 +1148,84 @@ void FaceTrackNoIR::exit() { // void FaceTrackNoIR::createIconGroupBox() { -importGetProtocolDll getProtocol; -IProtocolDllPtr pProtocolDll; // Pointer to Protocol info instance (in DLL) -importGetFilterDll getFilter; -IFilterDllPtr pFilterDll; // Pointer to Filter info instance (in DLL) -importGetTrackerDll getTracker; -ITrackerDll *pTrackerDll; // Pointer to Tracker info instance (in DLL) -QStringList listDLLs; // List of specific DLLs - - QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) - - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - - // - // Get a List of all the Protocol-DLL-files in the Program-folder. - // QDir settingsDir( QCoreApplication::applicationDirPath() ); - QStringList filters; - filters.clear(); - filters << "FTNoIR_Protocol_*.dll"; - protocolFileList.clear(); - listDLLs.clear(); - listDLLs = settingsDir.entryList( filters, QDir::Files, QDir::Name ); - - // - // Add strings to the Listbox. - // - disconnect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); - ui.iconcomboProtocol->clear(); - for ( int i = 0; i < listDLLs.size(); i++) { - - // Try to load the DLL and get the Icon and Name - QLibrary *protocolLib = new QLibrary(listDLLs.at(i)); - QString *protocolName = new QString(""); - QIcon *protocolIcon = new QIcon(); - - getProtocol = (importGetProtocolDll) protocolLib->resolve("GetProtocolDll"); - if (getProtocol) { - IProtocolDllPtr ptrXyz(getProtocol()); - if (ptrXyz) - { - pProtocolDll = ptrXyz; - pProtocolDll->getFullName( protocolName ); - pProtocolDll->getIcon( protocolIcon ); - - // - // Add the Icon and the Name to the Listbox and update the fileList - // - ui.iconcomboProtocol->addItem(*protocolIcon, *protocolName ); - protocolFileList.append(listDLLs.at(i)); - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Protocol-DLL not loaded, please check if the DLL is version 1.7 \nand all dependencies are installed. \n(" + listDLLs.at(i) + ")",QMessageBox::Ok,QMessageBox::NoButton); - } - - } - connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); - - // - // Get a List of all the Filter-DLL-files in the Program-folder. - // - filters.clear(); - filters << "FTNoIR_Filter_*.dll"; - filterFileList.clear(); - listDLLs.clear(); - listDLLs = settingsDir.entryList( filters, QDir::Files, QDir::Name ); - - // - // Add strings to the Listbox. - // - disconnect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); - ui.iconcomboFilter->clear(); - ui.iconcomboFilter->addItem("None"); - - for ( int i = 0; i < listDLLs.size(); i++) { - - // Try to load the DLL and get the Icon and Name - QLibrary *filterLib = new QLibrary(listDLLs.at(i)); - QString *filterName = new QString(""); - QIcon *filterIcon = new QIcon(); - - getFilter = (importGetFilterDll) filterLib->resolve("GetFilterDll"); - if (getFilter) { - IFilterDllPtr ptrXyz(getFilter()); - if (ptrXyz) - { - pFilterDll = ptrXyz; - pFilterDll->getFullName( filterName ); - pFilterDll->getIcon( filterIcon ); - - // - // Add the Icon and the Name to the Listbox and update the fileList - // - ui.iconcomboFilter->addItem(*filterIcon, *filterName ); - filterFileList.append(listDLLs.at(i)); - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Filter-DLL not loaded, please check if the DLL is version 1.7 \nand all dependencies are installed. \n(" + listDLLs.at(i) + ")",QMessageBox::Ok,QMessageBox::NoButton); - } - } - connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); - - // - // Get a List of all the Tracker-DLL-files in the Program-folder. - // - filters.clear(); - filters << "FTNoIR_Tracker_*.dll"; - trackerFileList.clear(); - listDLLs.clear(); - listDLLs = settingsDir.entryList( filters, QDir::Files, QDir::Name ); - - // - // Add strings to the Listbox(es). - // - disconnect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - ui.iconcomboTrackerSource->clear(); - - disconnect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - ui.cbxSecondTrackerSource->clear(); - ui.cbxSecondTrackerSource->addItem("None"); - - for ( int i = 0; i < listDLLs.size(); i++) { - - // Try to load the DLL and get the Icon and Name - QLibrary *trackerLib = new QLibrary(listDLLs.at(i)); - QString *trackerName = new QString(""); - QIcon *trackerIcon = new QIcon(); + { + QStringList protocols = settingsDir.entryList( QStringList() << (LIB_PREFIX "ftnoir-proto-*." SONAME), QDir::Files, QDir::Name ); + for ( int i = 0; i < protocols.size(); i++) { + QIcon icon; + QString longName; + QString str = protocols.at(i); + DynamicLibrary* lib = new DynamicLibrary(str.toLatin1().constData()); + qDebug() << "Loading" << str; + std::cout.flush(); + Metadata* meta; + if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) + { + delete lib; + continue; + } + meta->getFullName(&longName); + meta->getIcon(&icon); + delete meta; + dlopen_protocols.push_back(lib); + ui.iconcomboProtocol->addItem(icon, longName); + } + } - getTracker = (importGetTrackerDll) trackerLib->resolve("GetTrackerDll"); - if (getTracker) { - ITrackerDll *ptrXyz(getTracker()); - if (ptrXyz) - { - pTrackerDll = ptrXyz; - pTrackerDll->getFullName( trackerName ); - pTrackerDll->getIcon( trackerIcon ); + { + ui.cbxSecondTrackerSource->addItem(QIcon(), "None"); + QStringList trackers = settingsDir.entryList( QStringList() << (LIB_PREFIX "ftnoir-tracker-*." SONAME), QDir::Files, QDir::Name ); + for ( int i = 0; i < trackers.size(); i++) { + QIcon icon; + QString longName; + QString str = trackers.at(i); + DynamicLibrary* lib = new DynamicLibrary(str.toLatin1().constData()); + qDebug() << "Loading" << str; + std::cout.flush(); + Metadata* meta; + if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) + { + delete lib; + continue; + } + meta->getFullName(&longName); + meta->getIcon(&icon); + delete meta; + dlopen_trackers.push_back(lib); + ui.iconcomboTrackerSource->addItem(icon, longName); + ui.cbxSecondTrackerSource->addItem(icon, longName); + } + } - // - // Add the Icon and the Name to the Listbox and update the fileList - // - ui.iconcomboTrackerSource->addItem(*trackerIcon, *trackerName ); - ui.cbxSecondTrackerSource->addItem(*trackerIcon, *trackerName ); - trackerFileList.append(listDLLs.at(i)); - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Tracker-DLL not loaded, please check if the DLL is version 1.7 \nand all dependencies are installed. \n(" + listDLLs.at(i) + ")",QMessageBox::Ok,QMessageBox::NoButton); - } + { + dlopen_filters.push_back((DynamicLibrary*) NULL); + ui.iconcomboFilter->addItem(QIcon(), "None"); + QStringList filters = settingsDir.entryList( QStringList() << (LIB_PREFIX "ftnoir-filter-*." SONAME), QDir::Files, QDir::Name ); + for ( int i = 0; i < filters.size(); i++) { + QIcon icon; + QString fullName; + QString str = filters.at(i); + DynamicLibrary* lib = new DynamicLibrary(str.toLatin1().constData()); + qDebug() << "Loading" << str; + std::cout.flush(); + Metadata* meta; + if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) + { + delete lib; + continue; + } + meta->getFullName(&fullName); + meta->getIcon(&icon); + delete meta; + dlopen_filters.push_back(lib); + ui.iconcomboFilter->addItem(icon, fullName); + } + } - } - connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); + connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); + connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); + connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); connect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); } @@ -1427,7 +1262,7 @@ void FaceTrackNoIR::createTrayIcon() trayIcon = new QSystemTrayIcon(this); trayIcon->setContextMenu(trayIconMenu); - trayIcon->setIcon(QIcon(QCoreApplication::applicationDirPath() + "/images/FaceTrackNoIR.ico")); + //trayIcon->setIcon(QIcon(QCoreApplication::applicationDirPath() + "/images/FaceTrackNoIR.png")); } } @@ -1468,8 +1303,9 @@ void FaceTrackNoIR::protocolSelected(int index) trayIcon->show(); trayIcon->showMessage( "FaceTrackNoIR", ui.iconcomboProtocol->itemText(index)); } - setWindowIcon(QIcon(":/images/FaceTrackNoIR.ico")); - ui.btnShowServerControls->setIcon(icon); + //setWindowIcon(QIcon(":/images/FaceTrackNoIR.png")); + //breaks with transparency -sh + //ui.btnShowServerControls->setIcon(icon);] } // @@ -1496,7 +1332,7 @@ void FaceTrackNoIR::profileSelected(int index) // // Save the name of the INI-file in the Registry. // - settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + iniFileList.at(ui.iconcomboProfile->currentIndex())); + settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + iniFileList.value(ui.iconcomboProfile->currentIndex(), "")); loadSettings(); } @@ -1645,27 +1481,22 @@ QWidget( parent , f) connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); connect(ui.cbxCenterKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); - connect(ui.cbxCenterMouseKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); connect(ui.chkCenterShift, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkCenterCtrl, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkCenterAlt, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.cbxGameZeroKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); - connect(ui.cbxGameZeroMouseKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); connect(ui.chkGameZeroShift, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkGameZeroCtrl, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkGameZeroAlt, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.cbxStartStopKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); - connect(ui.cbxStartStopMouseKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); connect(ui.chkStartStopShift, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkStartStopCtrl, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkStartStopAlt, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.radioSetZero, SIGNAL(toggled(bool)), this, SLOT(keyChanged(bool))); - connect(ui.radioSetEngineStop, SIGNAL(toggled(bool)), this, SLOT(keyChanged(bool))); connect(ui.cbxInhibitKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); - connect(ui.cbxInhibitMouseKey, SIGNAL(currentIndexChanged(int)), this, SLOT(keyChanged( int ))); connect(ui.chkInhibitShift, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkInhibitCtrl, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkInhibitAlt, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); @@ -1678,168 +1509,18 @@ QWidget( parent , f) connect(ui.chkInhibitY, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); connect(ui.chkInhibitZ, SIGNAL(stateChanged(int)), this, SLOT(keyChanged(int))); - // // Clear the Lists with key-descriptions and keycodes and build the Lists // The strings will all be added to the ListBoxes for each Shortkey // - stringList.clear(); - stringList.append("NONE"); - stringList.append("F1"); - stringList.append("F2"); - stringList.append("F3"); - stringList.append("F4"); - stringList.append("F5"); - stringList.append("F6"); - stringList.append("F7"); - stringList.append("F8"); - stringList.append("F9"); - stringList.append("F10"); - stringList.append("F11"); - stringList.append("F12"); - stringList.append("MINUS"); - stringList.append("EQUALS"); - stringList.append("BACK"); - stringList.append("A"); - stringList.append("B"); - stringList.append("C"); - stringList.append("D"); - stringList.append("E"); - stringList.append("F"); - stringList.append("G"); - stringList.append("H"); - stringList.append("I"); - stringList.append("J"); - stringList.append("K"); - stringList.append("L"); - stringList.append("M"); - stringList.append("N"); - stringList.append("O"); - stringList.append("P"); - stringList.append("Q"); - stringList.append("R"); - stringList.append("S"); - stringList.append("T"); - stringList.append("U"); - stringList.append("V"); - stringList.append("W"); - stringList.append("X"); - stringList.append("Y"); - stringList.append("Z"); - stringList.append("NUMPAD0"); - stringList.append("NUMPAD1"); - stringList.append("NUMPAD2"); - stringList.append("NUMPAD3"); - stringList.append("NUMPAD4"); - stringList.append("NUMPAD5"); - stringList.append("NUMPAD6"); - stringList.append("NUMPAD7"); - stringList.append("NUMPAD8"); - stringList.append("NUMPAD9"); - stringList.append("HOME"); - stringList.append("UP"); - stringList.append("PGUP"); /* PgUp on arrow keypad */ - stringList.append("LEFT"); - stringList.append("RIGHT"); - stringList.append("END"); - stringList.append("DOWN"); - stringList.append("PGDWN"); /* PgDn on arrow keypad */ - stringList.append("INSERT"); - stringList.append("DELETE"); - - keyList.clear(); - keyList.append(0); // NONE = 0 - keyList.append(DIK_F1); - keyList.append(DIK_F2); - keyList.append(DIK_F3); - keyList.append(DIK_F4); - keyList.append(DIK_F5); - keyList.append(DIK_F6); - keyList.append(DIK_F7); - keyList.append(DIK_F8); - keyList.append(DIK_F9); - keyList.append(DIK_F10); - keyList.append(DIK_F11); - keyList.append(DIK_F12); - keyList.append(DIK_MINUS); - keyList.append(DIK_EQUALS); - keyList.append(DIK_BACK); - keyList.append(DIK_A); - keyList.append(DIK_B); - keyList.append(DIK_C); - keyList.append(DIK_D); - keyList.append(DIK_E); - keyList.append(DIK_F); - keyList.append(DIK_G); - keyList.append(DIK_H); - keyList.append(DIK_I); - keyList.append(DIK_J); - keyList.append(DIK_K); - keyList.append(DIK_L); - keyList.append(DIK_M); - keyList.append(DIK_N); - keyList.append(DIK_O); - keyList.append(DIK_P); - keyList.append(DIK_Q); - keyList.append(DIK_R); - keyList.append(DIK_S); - keyList.append(DIK_T); - keyList.append(DIK_U); - keyList.append(DIK_V); - keyList.append(DIK_W); - keyList.append(DIK_X); - keyList.append(DIK_Y); - keyList.append(DIK_Z); - keyList.append(DIK_NUMPAD0); - keyList.append(DIK_NUMPAD1); - keyList.append(DIK_NUMPAD2); - keyList.append(DIK_NUMPAD3); - keyList.append(DIK_NUMPAD4); - keyList.append(DIK_NUMPAD5); - keyList.append(DIK_NUMPAD6); - keyList.append(DIK_NUMPAD7); - keyList.append(DIK_NUMPAD8); - keyList.append(DIK_NUMPAD9); - keyList.append(DIK_HOME); - keyList.append(DIK_UP); - keyList.append(DIK_PRIOR); /* PgUp on arrow keypad */ - keyList.append(DIK_LEFT); - keyList.append(DIK_RIGHT); - keyList.append(DIK_END); - keyList.append(DIK_DOWN); - keyList.append(DIK_NEXT); /* PgDn on arrow keypad */ - keyList.append(DIK_INSERT); - keyList.append(DIK_DELETE); - // // Add strings to the Listboxes. // - for ( int i = 0; i < stringList.size(); i++) { - ui.cbxCenterKey->addItem(stringList.at(i)); - ui.cbxGameZeroKey->addItem(stringList.at(i)); - ui.cbxStartStopKey->addItem(stringList.at(i)); - ui.cbxInhibitKey->addItem(stringList.at(i)); - } - - // - // Clear the Lists with key-descriptions and keycodes and build the Lists - // The strings will all be added to the ListBoxes for each Shortkey - // - stringListMouse.clear(); - stringListMouse.append("NONE"); - stringListMouse.append("LEFT"); - stringListMouse.append("RIGHT"); - stringListMouse.append("MIDDLE"); - stringListMouse.append("BACK"); - stringListMouse.append("FORWARD"); - // - // Add strings to the Listboxes. - // - for ( int i = 0; i < stringListMouse.size(); i++) { - ui.cbxCenterMouseKey->addItem(stringListMouse.at(i)); - ui.cbxGameZeroMouseKey->addItem(stringListMouse.at(i)); - ui.cbxStartStopMouseKey->addItem(stringListMouse.at(i)); - ui.cbxInhibitMouseKey->addItem(stringListMouse.at(i)); + for ( int i = 0; i < global_key_sequences.size(); i++) { + ui.cbxCenterKey->addItem(global_key_sequences.at(i)); + ui.cbxGameZeroKey->addItem(global_key_sequences.at(i)); + ui.cbxStartStopKey->addItem(global_key_sequences.at(i)); + ui.cbxInhibitKey->addItem(global_key_sequences.at(i)); } // Load the settings from the current .INI-file @@ -1859,6 +1540,7 @@ KeyboardShortcutDialog::~KeyboardShortcutDialog() { void KeyboardShortcutDialog::doOK() { save(); this->close(); + mainApp->bindKeyboardShortcuts(); } // override show event @@ -1899,12 +1581,140 @@ void KeyboardShortcutDialog::doCancel() { } } +void FaceTrackNoIR::bindKeyboardShortcuts() +{ + QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + iniFile.beginGroup ( "KB_Shortcuts" ); + int idxCenter = iniFile.value("Key_index_Center", 0).toInt(); + int idxGameZero = iniFile.value("Key_index_GameZero", 0).toInt(); + int idxStartStop = iniFile.value("Key_index_StartStop", 0).toInt(); + int idxInhibit = iniFile.value("Key_index_Inhibit", 0).toInt(); + +#if !defined(_WIN32) && !defined(__WIN32) + if (keyCenter) { + delete keyCenter; + keyCenter = NULL; + } + + if (keyZero) { + delete keyZero; + keyZero = NULL; + } + + if (keyStartStop) { + delete keyStartStop; + keyStartStop = NULL; + } + + if (keyInhibit) { + delete keyInhibit; + keyInhibit = NULL; + } + + if (idxCenter > 0) + { + QString seq(global_key_sequences.value(idxCenter, "")); + if (!seq.isEmpty()) + { + if (iniFile.value("Shift_Center", false).toBool()) + seq = "Shift+" + seq; + if (iniFile.value("Alt_Center", false).toBool()) + seq = "Alt+" + seq; + if (iniFile.value("Ctrl_Center", false).toBool()) + seq = "Ctrl+" + seq; + keyCenter = new QxtGlobalShortcut(QKeySequence(seq)); + connect(keyCenter, SIGNAL(activated()), this, SLOT(shortcutRecentered())); + } + } + + if (idxGameZero > 0) + { + QString seq(global_key_sequences.value(idxGameZero, "")); + if (!seq.isEmpty()) + { + if (iniFile.value("Shift_GameZero", false).toBool()) + seq = "Shift+" + seq; + if (iniFile.value("Alt_GameZero", false).toBool()) + seq = "Alt+" + seq; + if (iniFile.value("Ctrl_GameZero", false).toBool()) + seq = "Ctrl+" + seq; + } + keyZero = new QxtGlobalShortcut(QKeySequence(seq)); + connect(keyZero, SIGNAL(activated()), this, SLOT(shortcutZero())); + } + + if (idxStartStop > 0) + { + QString seq(global_key_sequences.value(idxStartStop, "")); + if (!seq.isEmpty()) + { + if (iniFile.value("Shift_StartStop", false).toBool()) + seq = "Shift+" + seq; + if (iniFile.value("Alt_StartStop", false).toBool()) + seq = "Alt+" + seq; + if (iniFile.value("Ctrl_StartStop", false).toBool()) + seq = "Ctrl+" + seq; + } + keyStartStop = new QxtGlobalShortcut(QKeySequence(seq)); + connect(keyStartStop, SIGNAL(activated()), this, SLOT(shortcutStartStop())); + } + + if (idxInhibit > 0) + { + QString seq(global_key_sequences.value(idxInhibit, "")); + if (!seq.isEmpty()) + { + if (iniFile.value("Shift_Inhibit", false).toBool()) + seq = "Shift+" + seq; + if (iniFile.value("Alt_Inhibit", false).toBool()) + seq = "Alt+" + seq; + if (iniFile.value("Ctrl_Inhibit", false).toBool()) + seq = "Ctrl+" + seq; + } + keyInhibit = new QxtGlobalShortcut(QKeySequence(seq)); + connect(keyInhibit, SIGNAL(activated()), this, SLOT(shortcutInhibit())); + } +#else + keyCenter.keycode = keyZero.keycode = keyInhibit.keycode = keyStartStop.keycode = 0; + keyCenter.shift = keyCenter.alt = keyCenter.ctrl = 0; + keyZero.shift = keyZero.alt = keyZero.ctrl = 0; + keyInhibit.shift = keyInhibit.alt = keyInhibit.ctrl = 0; + keyStartStop.shift = keyStartStop.alt = keyStartStop.ctrl = 0; + if (idxCenter > 0 && idxCenter < global_windows_key_sequences.size()) + keyCenter.keycode = global_windows_key_sequences[idxCenter]; + if (idxGameZero > 0 && idxCenter < global_windows_key_sequences.size()) + keyZero.keycode = global_windows_key_sequences[idxGameZero]; + if (idxInhibit > 0 && idxInhibit < global_windows_key_sequences.size()) + keyInhibit.keycode = global_windows_key_sequences[idxInhibit]; + if (idxStartStop > 0 && idxStartStop < global_windows_key_sequences.size()) + keyStartStop.keycode = global_windows_key_sequences[idxStartStop]; + + keyCenter.shift = iniFile.value("Shift_Center", false).toBool(); + keyCenter.alt = iniFile.value("Alt_Center", false).toBool(); + keyCenter.ctrl = iniFile.value("Ctrl_Center", false).toBool(); + + keyInhibit.shift = iniFile.value("Shift_Inhibit", false).toBool(); + keyInhibit.alt = iniFile.value("Alt_Inhibit", false).toBool(); + keyInhibit.ctrl = iniFile.value("Ctrl_Inhibit", false).toBool(); + + keyZero.shift = iniFile.value("Shift_GameZero", false).toBool(); + keyZero.alt = iniFile.value("Alt_GameZero", false).toBool(); + keyZero.ctrl = iniFile.value("Ctrl_GameZero", false).toBool(); + + keyStartStop.shift = iniFile.value("Shift_StartStop", false).toBool(); + keyStartStop.alt = iniFile.value("Alt_StartStop", false).toBool(); + keyStartStop.ctrl = iniFile.value("Ctrl_StartStop", false).toBool(); +#endif + iniFile.endGroup (); +} + // // Load the current Settings from the currently 'active' INI-file. // void KeyboardShortcutDialog::loadSettings() { -int keyindex; - qDebug() << "loadSettings says: Starting "; QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) @@ -1915,62 +1725,29 @@ int keyindex; iniFile.beginGroup ( "KB_Shortcuts" ); - // Center key - ui.cbxCenterMouseKey->setCurrentIndex( iniFile.value ( "MouseKey_Center", 0 ).toInt() ); - keyindex = keyList.indexOf ( iniFile.value ( "Keycode_Center", DIK_HOME ).toInt() ); - if ( keyindex > 0 ) { - ui.cbxCenterKey->setCurrentIndex( keyindex ); - } - else { - ui.cbxCenterKey->setCurrentIndex( 0 ); - } - ui.chkCenterShift->setChecked (iniFile.value ( "Shift_Center", 0 ).toBool()); + ui.chkCenterShift->setChecked (iniFile.value ( "Shift_Center", 0 ).toBool()); ui.chkCenterCtrl->setChecked (iniFile.value ( "Ctrl_Center", 0 ).toBool()); ui.chkCenterAlt->setChecked (iniFile.value ( "Alt_Center", 0 ).toBool()); - ui.chkDisableBeep->setChecked (iniFile.value ( "Disable_Beep", 0 ).toBool()); - // GameZero key - ui.cbxGameZeroMouseKey->setCurrentIndex( iniFile.value ( "MouseKey_GameZero", 0 ).toInt() ); - keyindex = keyList.indexOf ( iniFile.value ( "Keycode_GameZero", 1 ).toInt() ); - if ( keyindex > 0 ) { - ui.cbxGameZeroKey->setCurrentIndex( keyindex ); - } - else { - ui.cbxGameZeroKey->setCurrentIndex( 0 ); - } + ui.cbxCenterKey->setCurrentIndex(iniFile.value("Key_index_Center", 0).toInt()); + ui.chkGameZeroShift->setChecked (iniFile.value ( "Shift_GameZero", 0 ).toBool()); ui.chkGameZeroCtrl->setChecked (iniFile.value ( "Ctrl_GameZero", 0 ).toBool()); ui.chkGameZeroAlt->setChecked (iniFile.value ( "Alt_GameZero", 0 ).toBool()); + ui.cbxGameZeroKey->setCurrentIndex(iniFile.value("Key_index_GameZero", 0).toInt()); - // Start/stop key - ui.cbxStartStopMouseKey->setCurrentIndex( iniFile.value ( "MouseKey_StartStop", 0 ).toInt() ); - keyindex = keyList.indexOf ( iniFile.value ( "Keycode_StartStop", DIK_END ).toInt() ); - if ( keyindex > 0 ) { - ui.cbxStartStopKey->setCurrentIndex( keyindex ); - } - else { - ui.cbxStartStopKey->setCurrentIndex( 0 ); - } ui.chkStartStopShift->setChecked (iniFile.value ( "Shift_StartStop", 0 ).toBool()); ui.chkStartStopCtrl->setChecked (iniFile.value ( "Ctrl_StartStop", 0 ).toBool()); ui.chkStartStopAlt->setChecked (iniFile.value ( "Alt_StartStop", 0 ).toBool()); + ui.cbxStartStopKey->setCurrentIndex(iniFile.value("Key_index_StartStop", 0).toInt()); + ui.radioSetZero->setChecked (iniFile.value ( "SetZero", 1 ).toBool()); ui.radioSetFreeze->setChecked(!ui.radioSetZero->isChecked()); - ui.radioSetEngineStop->setChecked (iniFile.value ( "SetEngineStop", 1 ).toBool()); - ui.radioSetKeepTracking->setChecked(!ui.radioSetEngineStop->isChecked()); - - // Axis-inhibitor key - ui.cbxInhibitMouseKey->setCurrentIndex( iniFile.value ( "MouseKey_Inhibit", 0 ).toInt() ); - keyindex = keyList.indexOf ( iniFile.value ( "Keycode_Inhibit", 1 ).toInt() ); - if ( keyindex > 0 ) { - ui.cbxInhibitKey->setCurrentIndex( keyindex ); - } - else { - ui.cbxInhibitKey->setCurrentIndex( 0 ); - } + ui.chkInhibitShift->setChecked (iniFile.value ( "Shift_Inhibit", 0 ).toBool()); ui.chkInhibitCtrl->setChecked (iniFile.value ( "Ctrl_Inhibit", 0 ).toBool()); ui.chkInhibitAlt->setChecked (iniFile.value ( "Alt_Inhibit", 0 ).toBool()); + ui.cbxInhibitKey->setCurrentIndex(iniFile.value("Key_index_Inhibit", 0).toInt()); ui.chkInhibitPitch->setChecked (iniFile.value ( "Inhibit_Pitch", 0 ).toBool()); ui.chkInhibitYaw->setChecked (iniFile.value ( "Inhibit_Yaw", 0 ).toBool()); @@ -2005,29 +1782,23 @@ void KeyboardShortcutDialog::save() { QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "KB_Shortcuts" ); - iniFile.setValue ( "MouseKey_Center", ui.cbxCenterMouseKey->currentIndex()); - iniFile.setValue ( "Keycode_Center", keyList.at( ui.cbxCenterKey->currentIndex() ) ); + iniFile.setValue ( "Key_index_Center", ui.cbxCenterKey->currentIndex() ); iniFile.setValue ( "Shift_Center", ui.chkCenterShift->isChecked() ); iniFile.setValue ( "Ctrl_Center", ui.chkCenterCtrl->isChecked() ); iniFile.setValue ( "Alt_Center", ui.chkCenterAlt->isChecked() ); - iniFile.setValue ( "Disable_Beep", ui.chkDisableBeep->isChecked() ); - iniFile.setValue ( "MouseKey_GameZero", ui.cbxGameZeroMouseKey->currentIndex()); - iniFile.setValue ( "Keycode_GameZero", keyList.at( ui.cbxGameZeroKey->currentIndex() ) ); + iniFile.setValue ( "Key_index_GameZero", ui.cbxGameZeroKey->currentIndex() ); iniFile.setValue ( "Shift_GameZero", ui.chkGameZeroShift->isChecked() ); iniFile.setValue ( "Ctrl_GameZero", ui.chkGameZeroCtrl->isChecked() ); iniFile.setValue ( "Alt_GameZero", ui.chkGameZeroAlt->isChecked() ); - iniFile.setValue ( "MouseKey_StartStop", ui.cbxStartStopMouseKey->currentIndex()); - iniFile.setValue ( "Keycode_StartStop", keyList.at( ui.cbxStartStopKey->currentIndex() ) ); + iniFile.setValue ( "Key_index_StartStop", ui.cbxStartStopKey->currentIndex() ); iniFile.setValue ( "Shift_StartStop", ui.chkStartStopShift->isChecked() ); iniFile.setValue ( "Ctrl_StartStop", ui.chkStartStopCtrl->isChecked() ); iniFile.setValue ( "Alt_StartStop", ui.chkStartStopAlt->isChecked() ); iniFile.setValue ( "SetZero", ui.radioSetZero->isChecked() ); - iniFile.setValue ( "SetEngineStop", ui.radioSetEngineStop->isChecked() ); - iniFile.setValue ( "MouseKey_Inhibit", ui.cbxInhibitMouseKey->currentIndex()); - iniFile.setValue ( "Keycode_Inhibit", keyList.at( ui.cbxInhibitKey->currentIndex() ) ); + iniFile.setValue ( "Key_index_Inhibit", ui.cbxInhibitKey->currentIndex() ); iniFile.setValue ( "Shift_Inhibit", ui.chkInhibitShift->isChecked() ); iniFile.setValue ( "Ctrl_Inhibit", ui.chkInhibitCtrl->isChecked() ); iniFile.setValue ( "Alt_Inhibit", ui.chkInhibitAlt->isChecked() ); @@ -2077,25 +1848,51 @@ QWidget( parent , f) QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - ui.qFunctionX->setConfig(Tracker::X.curvePtr, currentFile); - connect(ui.qFunctionX, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - ui.qFunctionY->setConfig(Tracker::Y.curvePtr, currentFile); - connect(ui.qFunctionY, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - ui.qFunctionZ->setConfig(Tracker::Z.curvePtr, currentFile); - connect(ui.qFunctionZ, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + ui.txconfig->setConfig(GlobalPose->X.curvePtr, currentFile); + connect(ui.txconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - ui.qFunctionYaw->setConfig(Tracker::Yaw.curvePtr, currentFile); - connect(ui.qFunctionYaw, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - // - // There are 2 curves for Pitch: Up and Down. Users have indicated that, to be able to use visual Flight controls, it is necessary to have a 'slow' curve for Down... - // - ui.qFunctionPitch->setConfig(Tracker::Pitch.curvePtr, currentFile); - connect(ui.qFunctionPitch, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - ui.qFunctionPitchDown->setConfig(Tracker::Pitch.curvePtrAlt, currentFile); - connect(ui.qFunctionPitchDown, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + ui.txconfig->setConfig(GlobalPose->X.curvePtr, currentFile); + connect(ui.txconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.tyconfig->setConfig(GlobalPose->Y.curvePtr, currentFile); + connect(ui.tyconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.tzconfig->setConfig(GlobalPose->Z.curvePtr, currentFile); + connect(ui.tzconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.rxconfig->setConfig(GlobalPose->Yaw.curvePtr, currentFile); + connect(ui.rxconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.ryconfig->setConfig(GlobalPose->Pitch.curvePtr, currentFile); + connect(ui.ryconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.rzconfig->setConfig(GlobalPose->Roll.curvePtr, currentFile); + connect(ui.rzconfig, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.txconfig_alt->setConfig(GlobalPose->X.curvePtrAlt, currentFile); + connect(ui.txconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - ui.qFunctionRoll->setConfig(Tracker::Roll.curvePtr, currentFile); - connect(ui.qFunctionRoll, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + ui.tyconfig_alt->setConfig(GlobalPose->Y.curvePtrAlt, currentFile); + connect(ui.tyconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.tzconfig_alt->setConfig(GlobalPose->Z.curvePtrAlt, currentFile); + connect(ui.tzconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.rxconfig_alt->setConfig(GlobalPose->Yaw.curvePtrAlt, currentFile); + connect(ui.rxconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.ryconfig_alt->setConfig(GlobalPose->Pitch.curvePtrAlt, currentFile); + connect(ui.ryconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + ui.rzconfig_alt->setConfig(GlobalPose->Roll.curvePtrAlt, currentFile); + connect(ui.rzconfig_alt, SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + + connect(ui.rx_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + connect(ui.ry_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + connect(ui.rz_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + connect(ui.tx_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + connect(ui.ty_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + connect(ui.tz_altp, SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); // Load the settings from the current .INI-file loadSettings(); @@ -2158,10 +1955,6 @@ void CurveConfigurationDialog::doCancel() { // Load the current Settings from the currently 'active' INI-file. // void CurveConfigurationDialog::loadSettings() { -int NeutralZone; -int sensYaw, sensPitch, sensRoll; -int sensX, sensY, sensZ; - qDebug() << "loadSettings says: Starting "; QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) @@ -2171,20 +1964,29 @@ int sensX, sensY, sensZ; qDebug() << "loadSettings says: iniFile = " << currentFile; iniFile.beginGroup ( "Tracking" ); - NeutralZone = iniFile.value ( "NeutralZone", 5 ).toInt(); - sensYaw = iniFile.value ( "sensYaw", 100 ).toInt(); - sensPitch = iniFile.value ( "sensPitch", 100 ).toInt(); - sensRoll = iniFile.value ( "sensRoll", 100 ).toInt(); - sensX = iniFile.value ( "sensX", 100 ).toInt(); - sensY = iniFile.value ( "sensY", 100 ).toInt(); - sensZ = iniFile.value ( "sensZ", 100 ).toInt(); - - iniFile.endGroup (); - - ui.qFunctionYaw->loadSettings(currentFile); - ui.qFunctionPitch->loadSettings(currentFile); - ui.qFunctionPitchDown->loadSettings(currentFile); - ui.qFunctionRoll->loadSettings(currentFile); + iniFile.endGroup (); + + ui.rxconfig->loadSettings(currentFile); + ui.ryconfig->loadSettings(currentFile); + ui.rzconfig->loadSettings(currentFile); + + ui.rxconfig_alt->loadSettings(currentFile); + ui.ryconfig_alt->loadSettings(currentFile); + ui.rzconfig_alt->loadSettings(currentFile); + + GlobalPose->Yaw.altp = iniFile.value("rx_alt", false).toBool(); + GlobalPose->Pitch.altp = iniFile.value("ry_alt", false).toBool(); + GlobalPose->Roll.altp = iniFile.value("rz_alt", false).toBool(); + GlobalPose->X.altp = iniFile.value("tx_alt", false).toBool(); + GlobalPose->Y.altp = iniFile.value("ty_alt", false).toBool(); + GlobalPose->Z.altp = iniFile.value("tz_alt", false).toBool(); + + ui.rx_altp->setChecked(GlobalPose->Yaw.altp); + ui.ry_altp->setChecked(GlobalPose->Pitch.altp); + ui.rz_altp->setChecked(GlobalPose->Roll.altp); + ui.tx_altp->setChecked(GlobalPose->X.altp); + ui.ty_altp->setChecked(GlobalPose->Y.altp); + ui.tz_altp->setChecked(GlobalPose->Z.altp); settingsDirty = false; @@ -2197,19 +1999,32 @@ void CurveConfigurationDialog::save() { qDebug() << "save() says: started"; - QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + + ui.rxconfig->saveSettings(currentFile); + ui.ryconfig->saveSettings(currentFile); + ui.rzconfig->saveSettings(currentFile); + ui.txconfig->saveSettings(currentFile); + ui.tyconfig->saveSettings(currentFile); + ui.tzconfig->saveSettings(currentFile); + + ui.txconfig_alt->saveSettings(currentFile); + ui.tyconfig_alt->saveSettings(currentFile); + ui.tzconfig_alt->saveSettings(currentFile); + ui.rxconfig_alt->saveSettings(currentFile); + ui.ryconfig_alt->saveSettings(currentFile); + ui.rzconfig_alt->saveSettings(currentFile); - ui.qFunctionYaw->saveSettings(currentFile); - ui.qFunctionPitch->saveSettings(currentFile); - ui.qFunctionPitchDown->saveSettings(currentFile); - ui.qFunctionRoll->saveSettings(currentFile); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - ui.qFunctionX->saveSettings(currentFile); - ui.qFunctionY->saveSettings(currentFile); - ui.qFunctionZ->saveSettings(currentFile); + iniFile.setValue("rx_alt", ui.rx_altp->checkState() != Qt::Unchecked); + iniFile.setValue("ry_alt", ui.ry_altp->checkState() != Qt::Unchecked); + iniFile.setValue("rz_alt", ui.rz_altp->checkState() != Qt::Unchecked); + iniFile.setValue("tx_alt", ui.tx_altp->checkState() != Qt::Unchecked); + iniFile.setValue("ty_alt", ui.ty_altp->checkState() != Qt::Unchecked); + iniFile.setValue("tz_alt", ui.tz_altp->checkState() != Qt::Unchecked); settingsDirty = false; @@ -2218,3 +2033,42 @@ void CurveConfigurationDialog::save() { // mainApp->updateSettings(); } + +void FaceTrackNoIR::shortcutRecentered() +{ + if (tracker) + { +#if defined(__WIN32) || defined(_WIN32) + MessageBeep(MB_OK); +#else + QApplication::beep(); +#endif + qDebug() << "Center"; + tracker->do_center = true; + } +} + +void FaceTrackNoIR::shortcutZero() +{ + if (tracker) + { + tracker->do_game_zero = true; + } +} + +void FaceTrackNoIR::shortcutStartStop() +{ + if (tracker) + { + tracker->do_tracking = !tracker->do_tracking; + qDebug() << "do-tracking" << tracker->do_tracking; + } +} + +void FaceTrackNoIR::shortcutInhibit() +{ + if (tracker) + { + tracker->do_inhibit = true; + } +} diff --git a/facetracknoir/facetracknoir.h b/facetracknoir/facetracknoir.h index 756b5867..7fd91719 100644 --- a/facetracknoir/facetracknoir.h +++ b/facetracknoir/facetracknoir.h @@ -25,7 +25,13 @@ #ifndef FaceTrackNoIR_H #define FaceTrackNoIR_H -#include +#undef FTNOIR_PROTOCOL_BASE_LIB +#undef FTNOIR_TRACKER_BASE_LIB +#undef FTNOIR_FILTER_BASE_LIB +#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT + #include #include #include @@ -34,30 +40,58 @@ #include #include #include - -#include "../FTNoIR_PoseWidget/glwidget.h" - -#include "ui_FaceTrackNoIR.h" -#include "ui_FTNoIR_KeyboardShortcuts.h" -#include "ui_FTNoIR_Preferences.h" -#include "ui_FTNoIR_Curves.h" - -#include "..\ftnoir_protocol_base\FTNoIR_Protocol_base.h" -#include "..\ftnoir_tracker_base\FTNoIR_Tracker_base.h" -#include "..\ftnoir_filter_base\FTNoIR_Filter_base.h" - -typedef ITrackerDialogPtr (WINAPI *importGetTrackerDialog)(void); -typedef ITrackerDllPtr (WINAPI *importGetTrackerDll)(void); -typedef IProtocolDialogPtr (WINAPI *importGetProtocolDialog)(void); -typedef IProtocolDllPtr (WINAPI *importGetProtocolDll)(void); -typedef IFilterDialogPtr (WINAPI *importGetFilterDialog)(void); -typedef IFilterDllPtr (WINAPI *importGetFilterDll)(void); - -#include +#include +#include +#include +#include +#if !defined(_WIN32) && !defined(__WIN32) +# include +#else +# include +#endif +#include +#include +#include + +#include "ftnoir_posewidget/glwidget.h" + +#include "ui_facetracknoir.h" +#include "ui_ftnoir_keyboardshortcuts.h" +#include "ui_ftnoir_preferences.h" +#include "ui_ftnoir_curves.h" + +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_filter_base/ftnoir_filter_base.h" + +#include "global-settings.h" class Tracker; // pre-define class to avoid circular includes +class FaceTrackNoIR; + +class KeybindingWorker; + +#if defined(__WIN32) || defined(_WIN32) +extern QList global_windows_key_sequences; +#include +struct Key { + BYTE keycode; + bool shift; + bool ctrl; + bool alt; + bool ever_pressed; + QElapsedTimer timer; +public: + Key() : keycode(0), shift(false), ctrl(false), alt(false), ever_pressed(false) + { + } +}; +#else +typedef unsigned char BYTE; +struct Key { int foo; }; +#endif -class FaceTrackNoIR : public QMainWindow +class FaceTrackNoIR : public QMainWindow, IDynamicLibraryProvider { Q_OBJECT @@ -65,29 +99,48 @@ public: FaceTrackNoIR(QWidget *parent = 0, Qt::WFlags flags = 0); ~FaceTrackNoIR(); - void getGameProgramName(); // Get the ProgramName from the game and display it. void updateSettings(); // Update the settings (let Tracker read INI-file). - QFrame *getVideoWidget(); // Get a pointer to the video-widget, to use in the DLL - QString getCurrentProtocolName(); // Get the name of the selected protocol - QString getCurrentFilterName(); // Get the name of the selected filter - QString getCurrentTrackerName(); // Get the name of the selected face-tracker - QString getSecondTrackerName(); // Get the name of the second face-tracker ("None" if no selection) + QFrame *get_video_widget(); // Get a pointer to the video-widget, to use in the DLL + Tracker *tracker; + void bindKeyboardShortcuts(); + DynamicLibrary* current_tracker1() { + return dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); + } + DynamicLibrary* current_tracker2() { + return dlopen_trackers.value(ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL); + } + DynamicLibrary* current_protocol() { + return dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); + } + DynamicLibrary* current_filter() { + return dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); + } +#if defined(_WIN32) || defined(__WIN32) + Key keyCenter, keyZero, keyStartStop, keyInhibit; + KeybindingWorker* keybindingWorker; +#else + QxtGlobalShortcut* keyCenter; + QxtGlobalShortcut* keyZero; + QxtGlobalShortcut* keyStartStop; + QxtGlobalShortcut* keyInhibit; +#endif +public slots: + void shortcutRecentered(); + void shortcutZero(); + void shortcutStartStop(); + void shortcutInhibit(); private: Ui::FaceTrackNoIRClass ui; - Tracker *tracker; QTimer *timMinimizeFTN; // Timer to Auto-minimize QTimer *timUpdateHeadPose; // Timer to display headpose QStringList iniFileList; // List of INI-files, that are present in the Settings folder - QStringList protocolFileList; // List of Protocol-DLL-files, that are present in the program-folder - QStringList filterFileList; // List of Filter-DLL-files, that are present in the program-folder - QStringList trackerFileList; // List of Tracker-DLL-files, that are present in the program-folder - ITrackerDialogPtr pTrackerDialog; // Pointer to Tracker dialog instance (in DLL) - ITrackerDialogPtr pSecondTrackerDialog; // Pointer to the second Tracker dialog instance (in DLL) - IProtocolDialogPtr pProtocolDialog; // Pointer to Protocol dialog instance (in DLL) - IFilterDialogPtr pFilterDialog; // Pointer to Filter dialog instance (in DLL) + ITrackerDialog* pTrackerDialog; // Pointer to Tracker dialog instance (in DLL) + ITrackerDialog* pSecondTrackerDialog; // Pointer to the second Tracker dialog instance (in DLL) + IProtocolDialog* pProtocolDialog; // Pointer to Protocol dialog instance (in DLL) + IFilterDialog* pFilterDialog; // Pointer to Filter dialog instance (in DLL) /** Widget variables **/ QVBoxLayout *l; @@ -120,6 +173,12 @@ private: void loadSettings(); void setupFaceTrackNoIR(); + QList dlopen_filters; + QList dlopen_trackers; + QList dlopen_protocols; + + bool looping; + private slots: //file menu void open(); @@ -159,11 +218,9 @@ private: void showHeadPose(); - //smoothing slider - void setSmoothing( int smooth ); - - void startTracker(); + void startTracker(); void stopTracker(); + }; // Widget that has controls for FaceTrackNoIR Preferences. @@ -209,9 +266,6 @@ private: /** helper **/ bool settingsDirty; FaceTrackNoIR *mainApp; - QList stringList; // List of strings, that describe the keyboard-keys - QList keyList; // List of keys, with the values of the keyboard-keys - QList stringListMouse; // List of strings, that describe the mouse-keys private slots: void doOK(); @@ -242,8 +296,41 @@ private: private slots: void doOK(); void doCancel(); - void curveChanged( bool change ) { settingsDirty = true; }; + void curveChanged( bool change ) { settingsDirty = true; } + void curveChanged( int change ) { settingsDirty = true; } }; - #endif // FaceTrackNoIR_H + +extern QList global_key_sequences; +#if defined(__WIN32) || defined(_WIN32) +class KeybindingWorkerDummy { +private: + LPDIRECTINPUT8 din; + LPDIRECTINPUTDEVICE8 dinkeyboard; + Key kCenter, kInhibit, kStartStop, kZero; + FaceTrackNoIR& window; +public: + volatile bool should_quit; + ~KeybindingWorkerDummy(); + KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter, Key keyInhibit, Key keyStartStop, Key keyZero); + void run(); +}; +#else +class KeybindingWorkerDummy { +public: + KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter, Key keyInhibit, Key keyStartStop, Key keyZero); + void run() {} +}; +#endif + +class KeybindingWorker : public QThread, public KeybindingWorkerDummy { + Q_OBJECT +public: + KeybindingWorker(FaceTrackNoIR& w, Key keyCenter, Key keyInhibit, Key keyStartStop, Key keyZero) : KeybindingWorkerDummy(w, keyCenter, keyInhibit, keyStartStop, keyZero) + { + } + void run() { + KeybindingWorkerDummy::run(); + } +}; diff --git a/facetracknoir/facetracknoir.ico b/facetracknoir/facetracknoir.ico new file mode 100644 index 00000000..5115066c Binary files /dev/null and b/facetracknoir/facetracknoir.ico differ diff --git a/facetracknoir/facetracknoir.rc b/facetracknoir/facetracknoir.rc index ed8a68c1..fcae12b3 100644 --- a/facetracknoir/facetracknoir.rc +++ b/facetracknoir/facetracknoir.rc @@ -1,84 +1,2 @@ -// Microsoft Visual C++ generated resource script. -// #include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Dutch (Neutral) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NLD) -#ifdef _WIN32 -LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "FaceTrackNoIR.ico" -#endif // Dutch (Neutral) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +IDI_ICON1 ICON "facetracknoir.ico" diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index 19c68cf0..5bbe48be 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -6,8 +6,8 @@ 0 0 - 901 - 661 + 718 + 698 @@ -15,7 +15,7 @@ - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/facetracknoir.pngimages/facetracknoir.png Qt::LeftToRight @@ -38,7 +38,7 @@ color: black; /* Specials for individual widget(s) */ QWidget#UICCurveConfigurationDialog { -background-color: #484848; +background-color: #dfdfdf; } QWidget#tabWidget { @@ -99,398 +99,538 @@ color: rgb(255, 255, 255); 0 - - - - :/images/rotation_DOFs.png:/images/rotation_DOFs.png + + + rx + + + + 0 + 0 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + + 255 + 0 + 0 + + + + + 200 + 200 + 200 + + + + + + + 0 + 280 + 166 + 21 + + + + Use alternative + + + + + + 0 + 340 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + + 255 + 0 + 0 + + + + + 200 + 200 + 200 + + + + + - Rotations + ry - + + + + 0 + 0 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + 1 + + + + 0 + 255 + 0 + + + + + 200 + 200 + 200 + + + + - 10 - 10 - 794 - 548 + 0 + 280 + 199 + 21 - - - - - - 0 - 0 - - - - - 260 - 240 - - - - - 260 - 500 - - - - 180 - - - 1 - - - - 0 - 255 - 255 - - - - - 192 - 192 - 192 - - - - Input Pitch Up (degr.) - - - Output Pitch Up (degr.) - - - - - - - - 0 - 0 - - - - - 260 - 240 - - - - - 260 - 500 - - - - 1 - - - - 0 - 255 - 0 - - - - - 192 - 192 - 192 - - - - Input Roll (degr.) - - - Output Roll (degr.) - - - - - - - - 0 - 0 - - - - - 260 - 240 - - - - - 400 - 500 - - - - 1 - - - - 255 - 170 - 0 - - - - - 192 - 192 - 192 - - - - Input Yaw (degr.) - - - Output Yaw (degr.) - - - - - - - - 0 - 0 - - - - - 260 - 240 - - - - - 260 - 500 - - - - 90 - - - 2 - - - - 0 - 255 - 255 - - - - - 192 - 192 - 192 - - - - Input Pitch Down (degr.) - - - Output Pitch Down (degr.) - - - - - - - - 16777215 - 25 - - - - Left-click the graph to place a new point, right-click a point to remove. Left-click and drag to move a point. - - - true - - - - - - - - 170 - 140 - - - - image: url(:/images/rotation_DOFs.png); - - - - + + Use alternative + + + + + + 0 + 340 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + 1 + + + + 0 + 255 + 0 + + + + + 200 + 200 + 200 + + - - - - :/images/translation_DOFs.png:/images/translation_DOFs.png + + + rz + + + + 0 + 0 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + 1 + + + + 0 + 0 + 255 + + + + + 200 + 200 + 200 + + + + + + + 0 + 280 + 271 + 21 + + + + Use alternative + + + + + + 0 + 340 + 595 + 240 + + + + 60 + + + 180 + + + 9 + + + 1 + + + + 0 + 0 + 255 + + + + + 200 + 200 + 200 + + + + + - Translations + tx - + - 30 - 10 - 794 - 390 + 0 + 0 + 595 + 260 - - - - - - 260 - 240 - - - - - 260 - 240 - - - - - 255 - 255 - 0 - - - - - 192 - 192 - 192 - - - - Left/Right Input X (cm.) - - - Output X (cm.) - - - - - - - - 260 - 240 - - - - - 260 - 240 - - - - - 85 - 0 - 255 - - - - - 192 - 192 - 192 - - - - Up/Down Input Y (cm.) - - - Output Y (cm.) - - - - - - - - 260 - 240 - - - - - 260 - 240 - - - - - 255 - 0 - 0 - - - - - 192 - 192 - 192 - - - - Forward/Backward Input Z (cm.) - - - Output Z (cm.) - - - - - - - - 16777215 - 25 - - - - Left-click the graph to place a new point, right-click a point to remove. Left-click and drag to move a point. - - - true - - - - - - - - 170 - 140 - - - - image: url(:/images/translation_DOFs.png); - - - - + + 60 + + + 200 + + + 9 + + + 1 + + + + 255 + 0 + 255 + + + + + 200 + 200 + 200 + + + + + + + 0 + 280 + 228 + 21 + + + + Use alternative + + + + + + 0 + 340 + 595 + 260 + + + + 60 + + + 200 + + + 9 + + + 1 + + + + 255 + 0 + 255 + + + + + 200 + 200 + 200 + + + + + + + ty + + + + + 0 + 0 + 595 + 260 + + + + 60 + + + 200 + + + 9 + + + 1 + + + + 255 + 255 + 0 + + + + + 200 + 200 + 200 + + + + + + + 0 + 280 + 229 + 21 + + + + Use alternative + + + + + + 0 + 340 + 595 + 260 + + + + 60 + + + 200 + + + 9 + + + 1 + + + + 255 + 255 + 0 + + + + + 200 + 200 + 200 + + + + + + + tz + + + + + 0 + 0 + 595 + 260 + + + + 60 + + + 200 + + + 9 + + + 1 + + + + 0 + 255 + 255 + + + + + 200 + 200 + 200 + + + + + + + 0 + 280 + 263 + 21 + + + + Use alternative + + + + + + 0 + 340 + 595 + 260 + + + + 60 + + + 200 + + + 9 + + + 1 + + + + 0 + 255 + 255 + + + + + 200 + 200 + 200 + + @@ -499,19 +639,6 @@ color: rgb(255, 255, 255); - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -527,7 +654,7 @@ color: rgb(255, 255, 255); - 52 + 58 0 @@ -552,7 +679,7 @@ color: rgb(255, 255, 255); - 52 + 58 0 @@ -569,17 +696,14 @@ color: rgb(255, 255, 255); - - + + Qt::Horizontal - - QSizePolicy::Fixed - - 10 + 40 20 @@ -596,9 +720,7 @@ color: rgb(255, 255, 255);
qfunctionconfigurator.h
- - - + startEngineClicked() diff --git a/facetracknoir/ftnoir_fsuipccontrols.ui b/facetracknoir/ftnoir_fsuipccontrols.ui index b6120378..e4c4963d 100644 --- a/facetracknoir/ftnoir_fsuipccontrols.ui +++ b/facetracknoir/ftnoir_fsuipccontrols.ui @@ -7,7 +7,7 @@ 0 0 541 - 127 + 131 @@ -15,7 +15,7 @@ - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/facetracknoir.pngimages/facetracknoir.png Qt::LeftToRight diff --git a/facetracknoir/ftnoir_ftnservercontrols.ui b/facetracknoir/ftnoir_ftnservercontrols.ui index 44c7e99f..3cb4bdeb 100644 --- a/facetracknoir/ftnoir_ftnservercontrols.ui +++ b/facetracknoir/ftnoir_ftnservercontrols.ui @@ -15,7 +15,7 @@ - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/FaceTrackNoIR.pngimages/FaceTrackNoIR.png Qt::LeftToRight diff --git a/facetracknoir/ftnoir_keyboardshortcuts.ui b/facetracknoir/ftnoir_keyboardshortcuts.ui index 2a5ad691..0faaf4d0 100644 --- a/facetracknoir/ftnoir_keyboardshortcuts.ui +++ b/facetracknoir/ftnoir_keyboardshortcuts.ui @@ -6,7 +6,7 @@ 0 0 - 687 + 591 438 @@ -15,7 +15,7 @@ - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/FaceTrackNoIR.pngimages/FaceTrackNoIR.png Qt::LeftToRight @@ -28,58 +28,8 @@ - - - - Disables: - - - - - - - When OFF: - - - - - - - - 0 - 0 - - - - Center - - - false - - - - - - - Axis Inhibitor - - - - - - - - 50 - 16777215 - - - - Shift - - - - - + + 50 @@ -87,12 +37,12 @@ - Shift + Alt - - + + 50 @@ -100,12 +50,12 @@ - Shift + Alt - - + + 50 @@ -130,8 +80,8 @@ - - + + 50 @@ -143,8 +93,8 @@ - - + + 50 @@ -152,21 +102,18 @@ - Alt + Shift - - - + + + - 50 - 16777215 + 90 + 0 - - Alt - @@ -185,27 +132,7 @@ - - - - - 90 - 0 - - - - - - - - - 90 - 0 - - - - - + @@ -278,7 +205,7 @@ - + @@ -330,7 +257,7 @@ - + color: rgb(0, 0, 0); @@ -397,48 +324,6 @@ - - - - - 100 - 0 - - - - color: rgb(0, 0, 0); - - - Engine tracker - - - - - 10 - 20 - 81 - 17 - - - - Stop Engine - - - - - - 10 - 40 - 91 - 17 - - - - Keep tracking - - - - @@ -542,75 +427,15 @@ - - - - - 0 - 0 - - - - Mouse - - - Qt::AlignCenter - - - false - - - - - - - - 90 - 0 - - - - Select Number - - - QComboBox::InsertAlphabetically - - - - - - - - 90 - 0 - - - - Select Number - - - QComboBox::InsertAlphabetically - - - - - - - - 90 - 0 - - - - Select Number - - - QComboBox::InsertAlphabetically + + + + Qt::Vertical - - + + 90 @@ -619,79 +444,66 @@ - - - - Qt::Vertical - - - - - - - Qt::Vertical + + + + Disables: - - - Qt::Vertical + + + When OFF: - - - - Qt::Vertical + + + + + 0 + 0 + - - - - - - Qt::Vertical + + Center - - - - - - Qt::Vertical + + false - - - - Qt::Vertical + + + + Axis Inhibitor - - - - Qt::Vertical + + + + + 50 + 16777215 + - - - - - - Qt::Vertical + + Shift - - + + - 85 + 50 16777215 - Disable Beep + Shift diff --git a/facetracknoir/ftnoir_preferences.ui b/facetracknoir/ftnoir_preferences.ui index bb440fc6..9e4bcd34 100644 --- a/facetracknoir/ftnoir_preferences.ui +++ b/facetracknoir/ftnoir_preferences.ui @@ -15,7 +15,7 @@ - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/FaceTrackNoIR.pngimages/FaceTrackNoIR.png Qt::LeftToRight diff --git a/facetracknoir/global-settings.cpp b/facetracknoir/global-settings.cpp new file mode 100644 index 00000000..f0f0413e --- /dev/null +++ b/facetracknoir/global-settings.cpp @@ -0,0 +1,142 @@ +#include "global-settings.h" + +#if !(defined(__WIN32) || defined(_WIN32)) +# include +#endif + +SelectedLibraries* Libraries = NULL; + +SelectedLibraries::~SelectedLibraries() +{ + if (pTracker) { + pTracker->WaitForExit(); + } + if (pSecondTracker) { + pSecondTracker->WaitForExit(); + } + + if (pTracker) { + delete pTracker; + pTracker = NULL; + } + + if (pSecondTracker) { + delete pSecondTracker; + pSecondTracker = NULL; + } + + if (pFilter) + delete pFilter; + + if (pProtocol) + delete pProtocol; +} + +SelectedLibraries::SelectedLibraries(IDynamicLibraryProvider* mainApp) : + pTracker(NULL), pSecondTracker(NULL), pFilter(NULL), pProtocol(NULL) +{ + correct = false; + if (!mainApp) + return; + NULLARY_DYNAMIC_FUNCTION ptr; + DynamicLibrary* lib; + + lib = mainApp->current_tracker1(); + + if (lib && lib->Constructor) { + ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor; + pTracker = (ITracker*) ptr(); + } + + lib = mainApp->current_tracker2(); + + if (lib && lib->Constructor) { + ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor; + pSecondTracker = (ITracker*) ptr(); + } + + lib = mainApp->current_protocol(); + + if (lib && lib->Constructor) { + ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor; + pProtocol = (IProtocol*) ptr(); + } + + lib = mainApp->current_filter(); + + if (lib && lib->Constructor) { + ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor; + pFilter = (IFilter*) ptr(); + } + + // Check if the Protocol-server files were installed OK. + // Some servers also create a memory-mapping, for Inter Process Communication. + // The handle of the MainWindow is sent to 'The Game', so it can send a message back. + + if (pProtocol) + if(!pProtocol->checkServerInstallationOK()) + return; + + // retrieve pointers to the User Interface and the main Application + if (pTracker) { + pTracker->StartTracker( mainApp->get_video_widget() ); + } + if (pSecondTracker) { + pSecondTracker->StartTracker( mainApp->get_video_widget() ); + } + + if (pFilter) + pFilter->Initialize(); + + if (pProtocol) + pProtocol->Initialize(); + + correct = true; +} + +DynamicLibrary::DynamicLibrary(const char* filename) +{ + this->filename = filename; + QString fullPath = QCoreApplication::applicationDirPath() + "/" + this->filename; +#if defined(__WIN32) || defined(_WIN32) + handle = new QLibrary(fullPath); + Dialog = (SETTINGS_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetDialog" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION); + Constructor = (NULLARY_DYNAMIC_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetConstructor" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION); + Metadata = (METADATA_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetMetadata" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION); +#else + handle = dlopen(fullPath.toLatin1().constData(), RTLD_NOW | +# ifdef __linux + RTLD_DEEPBIND +# else + 0 +# endif + ); + if (handle) + { + fprintf(stderr, "Error, if any: %s\n", dlerror()); + fflush(stderr); + Dialog = (SETTINGS_FUNCTION) dlsym(handle, "GetDialog"); + fprintf(stderr, "Error, if any: %s\n", dlerror()); + fflush(stderr); + Constructor = (NULLARY_DYNAMIC_FUNCTION) dlsym(handle, "GetConstructor"); + fprintf(stderr, "Error, if any: %s\n", dlerror()); + fflush(stderr); + Metadata = (METADATA_FUNCTION) dlsym(handle, "GetMetadata"); + fprintf(stderr, "Error, if any: %s\n", dlerror()); + fflush(stderr); + } else { + fprintf(stderr, "Error, if any: %s\n", dlerror()); + fflush(stderr); + } +#endif +} + +DynamicLibrary::~DynamicLibrary() +{ +#if defined(__WIN32) || defined(_WIN32) + handle->unload(); +#else + if (handle) + (void) dlclose(handle); +#endif +} diff --git a/facetracknoir/global-settings.h b/facetracknoir/global-settings.h new file mode 100644 index 00000000..62f00831 --- /dev/null +++ b/facetracknoir/global-settings.h @@ -0,0 +1,85 @@ +#pragma once + +#if defined(_WIN32) || defined(__WIN32) +# define CALLING_CONVENTION_SUFFIX_VOID_FUNCTION "@0" +# ifdef _MSC_VER +# define MAYBE_STDCALL_UNDERSCORE "_" +#else +# define MAYBE_STDCALL_UNDERSCORE "" +# endif +#else +# define CALLING_CONVENTION_SUFFIX_VOID_FUNCTION "" +# define MAYBE_STDCALL_UNDERSCORE "" +#endif + +#include +#include +#include +#include +#include +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_filter_base/ftnoir_filter_base.h" +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" + +#if defined(_WIN32) || defined(__WIN32) +# define CALLING_CONVENTION __stdcall +#else +# define CALLING_CONVENTION +#endif + +class IDynamicLibraryProvider; + +struct SelectedLibraries { +public: + ITracker* pTracker; + ITracker* pSecondTracker; + IFilter* pFilter; + IProtocol* pProtocol; + SelectedLibraries(IDynamicLibraryProvider* main = NULL); + ~SelectedLibraries(); + bool correct; +}; + +extern SelectedLibraries* Libraries; + +struct Metadata; + +extern "C" typedef void* (CALLING_CONVENTION * NULLARY_DYNAMIC_FUNCTION)(void); +extern "C" typedef Metadata* (CALLING_CONVENTION* METADATA_FUNCTION)(void); +extern "C" typedef void* (CALLING_CONVENTION* SETTINGS_FUNCTION)(void); + +class DynamicLibrary { +public: + DynamicLibrary(const char* filename); + virtual ~DynamicLibrary(); + SETTINGS_FUNCTION Dialog; + NULLARY_DYNAMIC_FUNCTION Constructor; + METADATA_FUNCTION Metadata; + QString filename; +private: +#if defined(_WIN32) || defined(__WIN32) + QLibrary* handle; +#else + void* handle; +#endif +}; + +struct Metadata +{ + Metadata() {} + virtual ~Metadata() {} + + virtual void getFullName(QString *strToBeFilled) = 0; + virtual void getShortName(QString *strToBeFilled) = 0; + virtual void getDescription(QString *strToBeFilled) = 0; + virtual void getIcon(QIcon *icon) = 0; +}; + +class IDynamicLibraryProvider { +public: + virtual DynamicLibrary* current_tracker1() = 0; + virtual DynamicLibrary* current_tracker2() = 0; + virtual DynamicLibrary* current_protocol() = 0; + virtual DynamicLibrary* current_filter() = 0; + virtual QFrame* get_video_widget() = 0; +}; diff --git a/facetracknoir/global-shortcuts.cpp b/facetracknoir/global-shortcuts.cpp new file mode 100644 index 00000000..286200c0 --- /dev/null +++ b/facetracknoir/global-shortcuts.cpp @@ -0,0 +1,135 @@ +#include "facetracknoir/facetracknoir.h" + +#if defined(__WIN32) || defined(_WIN32) +#include +#include +#include +QList global_windows_key_sequences = + QList() + << 0 + << DIK_A + << DIK_B + << DIK_C + << DIK_D + << DIK_E + << DIK_F + << DIK_G + << DIK_H + << DIK_I + << DIK_J + << DIK_K + << DIK_L + << DIK_M + << DIK_N + << DIK_O + << DIK_P + << DIK_Q + << DIK_R + << DIK_S + << DIK_T + << DIK_U + << DIK_V + << DIK_W + << DIK_X + << DIK_Y + << DIK_Z + << DIK_F1 + << DIK_F2 + << DIK_F3 + << DIK_F4 + << DIK_F5 + << DIK_F6 + << DIK_F7 + << DIK_F8 + << DIK_F9 + << DIK_F10 + << DIK_F11 + << DIK_F12 + << DIK_1 + << DIK_2 + << DIK_3 + << DIK_4 + << DIK_5 + << DIK_6 + << DIK_7 + << DIK_8 + << DIK_9 + << DIK_0 + << DIK_LEFT + << DIK_RIGHT + << DIK_UP + << DIK_DOWN + << DIK_PGUP + << DIK_DOWN + << DIK_HOME + << DIK_END + << DIK_BACK + << DIK_DELETE + << DIK_RETURN; +#endif + +QList global_key_sequences = + QList() + << "" + << "A" + << "B" + << "C" + << "D" + << "E" + << "F" + << "G" + << "H" + << "I" + << "J" + << "K" + << "L" + << "M" + << "N" + << "O" + << "P" + << "Q" + << "R" + << "S" + << "T" + << "U" + << "V" + << "W" + << "X" + << "Y" + << "Z" + << "F1" + << "F2" + << "F3" + << "F4" + << "F5" + << "F6" + << "F7" + << "F8" + << "F9" + << "F10" + << "F11" + << "F12" + << "1" + << "2" + << "3" + << "4" + << "5" + << "6" + << "7" + << "8" + << "9" + << "0" + << "Left" + << "Right" + << "Up" + << "Down" + << "PgUp" + << "PgDown" + << "Home" + << "End" + << "Backspace" + << "Del" + << "Enter" +; + + diff --git a/facetracknoir/images/facetracknoir.ico b/facetracknoir/images/facetracknoir.ico new file mode 100644 index 00000000..5115066c Binary files /dev/null and b/facetracknoir/images/facetracknoir.ico differ diff --git a/facetracknoir/main.cpp b/facetracknoir/main.cpp index 6e0549d7..d2eb84cc 100644 --- a/facetracknoir/main.cpp +++ b/facetracknoir/main.cpp @@ -27,28 +27,28 @@ messages from the Game. */ -#include "FaceApp.h" -#include "FaceTrackNoIR.h" +#include "facetracknoir.h" +#include "tracker.h" #include #include #include #include -int main(int argc, char *argv[]) +#if defined(_WIN32) +#include +#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") +#endif +int main(int argc, char** argv) { -//// QApplication a(argc, argv); - FaceApp a(argc, argv); + QApplication app(argc, argv); QFont font; font.setFamily(font.defaultFamily()); font.setPointSize(9); - a.setFont(font); - + app.setFont(font); + FaceTrackNoIR w; // // Create the Main Window and DeskTop and Exec! // - FaceTrackNoIR w; - a.SetupEventFilter(&w); - QDesktopWidget desktop; w.move(desktop.screenGeometry().width()/2-w.width()/2, 100); w.show(); diff --git a/facetracknoir/posix-version-script.txt b/facetracknoir/posix-version-script.txt new file mode 100644 index 00000000..97edb9aa --- /dev/null +++ b/facetracknoir/posix-version-script.txt @@ -0,0 +1,8 @@ +{ + global: + GetDialog; + GetConstructor; + GetMetadata; + local: + *; +}; \ No newline at end of file diff --git a/facetracknoir/rotation.cpp b/facetracknoir/rotation.cpp index 1c89d775..f6d16d2d 100644 --- a/facetracknoir/rotation.cpp +++ b/facetracknoir/rotation.cpp @@ -32,7 +32,7 @@ void Rotation::fromEuler(double yaw, double pitch, double roll) d = cos_phi*cos_the*sin_psi - sin_phi*sin_the*cos_psi; } -void Rotation::toEuler(double& yaw, double& pitch, double& roll) +void Rotation::toEuler(volatile double& yaw, volatile double& pitch, volatile double& roll) { roll = atan2(2.0*(a*b + c*d), 1.0 - 2.0*(b*b + c*c)); pitch = asin(2.0*(a*c - b*d)); diff --git a/facetracknoir/rotation.h b/facetracknoir/rotation.h index 967d6661..9dcea285 100644 --- a/facetracknoir/rotation.h +++ b/facetracknoir/rotation.h @@ -20,7 +20,7 @@ public: // conversions void fromEuler(double yaw, double pitch, double roll); - void toEuler(double& yaw, double& pitch, double& roll); + void toEuler(volatile double& yaw, volatile double& pitch, volatile double& roll); protected: double a,b,c,d; // quaternion coefficients diff --git a/facetracknoir/spot.h b/facetracknoir/spot.h new file mode 100644 index 00000000..e23c4e2c --- /dev/null +++ b/facetracknoir/spot.h @@ -0,0 +1,27 @@ +#ifndef __SPOT_H__ +#define __SPOT_H__ + +class Spot { + +private: + QPoint distance; + QPoint position; + QImage image; + QRect target; + QRect source; + +public: + Spot(); + + void setDistance(QPoint distance); + QPoint getDistance(); + + void setPosition(QPoint position); + QPoint getPosition(); + + QRect getTarget(); + QRect getSource(); + QImage getImage(); +}; + +#endif \ No newline at end of file diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp index 5396c95b..fbc0bd29 100644 --- a/facetracknoir/tracker.cpp +++ b/facetracknoir/tracker.cpp @@ -23,7 +23,6 @@ *********************************************************************************/ /* Modifications (last one on top): - 20130201 - WVR: Remove the Protocol, when stopping the Thread. 20121215 - WVR: Fixed crash after message: protocol not installed correctly... by terminating the thread. 20120921 - WVR: Fixed centering when no filter is selected. 20120917 - WVR: Added Mouse-buttons to ShortKeys. @@ -31,7 +30,7 @@ 20120805 - WVR: The FunctionConfig-widget is used to configure the Curves. It was tweaked some more, because the Accela filter now also uses the Curve(s). ToDo: make the ranges configurable by the user. Development on the Toradex IMU makes us realize, that a fixed input-range may not be so handy after all.. - 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled ´statically´. Now, a Dir() of the + 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled �statically�. Now, a Dir() of the EXE-folder is done, to locate Protocol-DLLs. The Icons were also moved to the DLLs 20120317 - WVR: The Filter and Tracker-code was moved to separate DLLs. The calling-method was changed accordingly. @@ -67,779 +66,249 @@ 1 or (-1). */ #include "tracker.h" -#include "FaceTrackNoIR.h" - -// Flags -bool Tracker::confid = false; -bool Tracker::do_tracking = true; -bool Tracker::do_center = false; -bool Tracker::do_inhibit = false; -bool Tracker::do_game_zero = false; -bool Tracker::do_axis_reverse = false; - -bool Tracker::setZero = true; -bool Tracker::setEngineStop = true; -HANDLE Tracker::hTrackMutex = 0; - -bool Tracker::useAxisReverse = false; // Use Axis Reverse -float Tracker::YawAngle4ReverseAxis = 40.0f; // Axis Reverse settings -float Tracker::Z_Pos4ReverseAxis = -20.0f; -float Tracker::Z_PosWhenReverseAxis = 50.0f; - - -T6DOF Tracker::current_camera(0,0,0,0,0,0); // Used for filtering -T6DOF Tracker::target_camera(0,0,0,0,0,0); -T6DOF Tracker::new_camera(0,0,0,0,0,0); -T6DOF Tracker::output_camera(0,0,0,0,0,0); // Position sent to game protocol - -THeadPoseDOF Tracker::Pitch("PitchUp", "PitchDown", 50, 180, 50, 90); // One structure for each of 6DOF's -THeadPoseDOF Tracker::Yaw("Yaw", "", 50, 180); -THeadPoseDOF Tracker::Roll("Roll", "", 50, 180); -THeadPoseDOF Tracker::X("X","", 50, 180); -THeadPoseDOF Tracker::Y("Y","", 50, 180); -THeadPoseDOF Tracker::Z("Z","", 50, 180); - -TShortKey Tracker::CenterKey; // ShortKey to Center headposition -TShortKey Tracker::StartStopKey; // ShortKey to Start/stop tracking -TShortKey Tracker::InhibitKey; // ShortKey to inhibit axis while tracking -TShortKey Tracker::GameZeroKey; // ShortKey to Set Game Zero -bool Tracker::DisableBeep = false; // Disable beep when center -//TShortKey Tracker::AxisReverseKey; // ShortKey to start/stop axis reverse while tracking - -int Tracker::CenterMouseKey; // ShortKey to Center headposition -int Tracker::StartStopMouseKey; // ShortKey to Start/stop tracking -int Tracker::InhibitMouseKey; // ShortKey to inhibit axis while tracking -int Tracker::GameZeroMouseKey; // ShortKey to Set Game Zero - -//ITrackerPtr Tracker::pTracker; // Pointer to Tracker instance (in DLL) -IProtocolPtr Tracker::pProtocol; // Pointer to Protocol instance (in DLL) -IFilterPtr Tracker::pFilter; // Pointer to Filter instance (in DLL) +#include "facetracknoir.h" +HeadPoseData* GlobalPose = NULL; /** constructor **/ -Tracker::Tracker( FaceTrackNoIR *parent ) { -QString libName; -importGetTracker getIT; -QLibrary *trackerLib; -importGetFilter getFilter; -QLibrary *filterLib; -importGetProtocol getProtocol; -QLibrary *protocolLib; -QFrame *video_frame; - - // Retieve the pointer to the parent +Tracker::Tracker( FaceTrackNoIR *parent ) : + confid(false), + useAxisReverse(false), + YawAngle4ReverseAxis(40), + Z_Pos4ReverseAxis(-20.0f), + Z_PosWhenReverseAxis(50.0), + should_quit(false), + do_tracking(true), + do_center(false), + do_inhibit(false), + do_game_zero(false), + do_axis_reverse(false), + inhibit_rx(false), + inhibit_ry(false), + inhibit_rz(false), + inhibit_tx(false), + inhibit_ty(false), + inhibit_tz(false) +{ + // Retieve the pointer to the parent mainApp = parent; - - // Create events - m_StopThread = CreateEvent(0, TRUE, FALSE, 0); - m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); - - Tracker::hTrackMutex = CreateMutexA(NULL, false, "HeadPose_mutex"); - - // - // Initialize the headpose-data - // - Tracker::Yaw.initHeadPoseData(); - Tracker::Pitch.initHeadPoseData(); - Tracker::Roll.initHeadPoseData(); - Tracker::X.initHeadPoseData(); - Tracker::Y.initHeadPoseData(); - Tracker::Z.initHeadPoseData(); - - // - // Locate the video-frame, for the DLL - // - video_frame = 0; - video_frame = mainApp->getVideoWidget(); - qDebug() << "Tracker::Tracker VideoFrame = " << video_frame; - - // - // Load the Tracker-engine DLL, get the tracker-class from it and do stuff... - // - pTracker = NULL; - libName = mainApp->getCurrentTrackerName(); - if (!libName.isEmpty()) { - trackerLib = new QLibrary(libName); - getIT = (importGetTracker) trackerLib->resolve("GetTracker"); - qDebug() << "Tracker::Tracker libName = " << libName; - - if (getIT) { - ITracker *ptrXyz(getIT()); // Get the Class - if (ptrXyz) - { - pTracker = ptrXyz; - pTracker->Initialize( video_frame ); - qDebug() << "Tracker::setup Function Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", libName + " DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } - // - // Load the Tracker-engine DLL, get the tracker-class from it and do stuff... - // - pSecondTracker = NULL; - libName = mainApp->getSecondTrackerName(); - if ((!libName.isEmpty()) && (libName != "None")) { - trackerLib = new QLibrary(libName); - getIT = (importGetTracker) trackerLib->resolve("GetTracker"); - - if (getIT) { - ITracker *ptrXyz(getIT()); // Get the Class - if (ptrXyz) - { - pSecondTracker = ptrXyz; - pSecondTracker->Initialize( NULL ); - qDebug() << "Tracker::setup Function Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", libName + " DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - } - } - - // - // Load the DLL with the protocol-logic and retrieve a pointer to the Protocol-class. - // - libName = mainApp->getCurrentProtocolName(); - if (!libName.isEmpty()) { - protocolLib = new QLibrary(libName); - getProtocol = (importGetProtocol) protocolLib->resolve("GetProtocol"); - if (getProtocol) { - IProtocolPtr ptrXyz(getProtocol()); - if (ptrXyz) - { - pProtocol = ptrXyz; - pProtocol->Initialize(); - qDebug() << "Protocol::setup Function Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Protocol-DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - return; - } - } - - // - // Load the DLL with the filter-logic and retrieve a pointer to the Filter-class. - // - pFilter = NULL; - libName = mainApp->getCurrentFilterName(); - - if ((!libName.isEmpty()) && (libName != "None")) { - filterLib = new QLibrary(libName); - - getFilter = (importGetFilter) filterLib->resolve("GetFilter"); - if (getFilter) { - IFilterPtr ptrXyz(getFilter()); - if (ptrXyz) - { - pFilter = ptrXyz; - qDebug() << "Filter::setup Function Resolved!"; - } - } - else { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Filter-DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); - return; - } - } - // Load the settings from the INI-file loadSettings(); + GlobalPose->Yaw.headPos = 0; + GlobalPose->Pitch.headPos = 0; + GlobalPose->Roll.headPos = 0; + GlobalPose->X.headPos = 0; + GlobalPose->Y.headPos = 0; + GlobalPose->Z.headPos = 0; } -/** destructor empty **/ -Tracker::~Tracker() { - - // Stop the Tracker(s) - if (pTracker) { - pTracker->StopTracker( true ); - } - if (pSecondTracker) { - pSecondTracker->StopTracker( true ); - } - - // Trigger thread to stop - ::SetEvent(m_StopThread); - - // Wait until thread finished - if (isRunning()) { - ::WaitForSingleObject(m_WaitThread, INFINITE); - } - - // - // Remove the Tracker - // 20120615, WVR: As suggested by Stanislaw - if (pTracker) { - delete pTracker; - pTracker = NULL; - } - if (pSecondTracker) { - delete pSecondTracker; - pSecondTracker = NULL; - } - - // - // Remove the Protocol - // - if (pProtocol) { - delete pProtocol; - pProtocol = NULL; - } - - // Close handles - ::CloseHandle(m_StopThread); - ::CloseHandle(m_WaitThread); - - if (Tracker::hTrackMutex != 0) { - ::CloseHandle( Tracker::hTrackMutex ); - } - -# ifdef USE_DEBUG_CLIENT - debug_Client->deleteLater(); // Delete Excel protocol-server -# endif - - qDebug() << "Tracker::~Tracker Finished..."; - +Tracker::~Tracker() +{ } -/** setting up the tracker engine **/ -void Tracker::setup() { - bool DLL_Ok; - - // retrieve pointers to the User Interface and the main Application - if (pTracker) { - pTracker->StartTracker( mainApp->winId() ); - } - if (pSecondTracker) { - pSecondTracker->StartTracker( mainApp->winId() ); - } - - // - // Check if the Protocol-server files were installed OK. - // Some servers also create a memory-mapping, for Inter Process Communication. - // The handle of the MainWindow is sent to 'The Game', so it can send a message back. - // - if (pProtocol) { - - DLL_Ok = pProtocol->checkServerInstallationOK( mainApp->winId() ); - if (!DLL_Ok) { - // Trigger thread to stop - ::SetEvent(m_StopThread); - QMessageBox::information(mainApp, "FaceTrackNoIR error", "Protocol is not (correctly) installed!"); - } - } - -# ifdef USE_DEBUG_CLIENT - DLL_Ok = debug_Client->checkServerInstallationOK( mainApp->winId() ); // Check installation - if (!DLL_Ok) { - QMessageBox::information(mainApp, "FaceTrackNoIR error", "Excel Protocol is not (correctly) installed!"); - } -# endif - +static void get_curve(bool inhibitp, bool inhibit_zerop, double pos, double& out, THeadPoseDOF& axis) { + if (inhibitp) { + if (inhibit_zerop) + out = 0; + axis.curvePtr->setTrackingActive( true ); + axis.curvePtrAlt->setTrackingActive( false ); + } + else { + bool altp = (pos < 0) && axis.altp; + if (altp) { + out = axis.invert * axis.curvePtrAlt->getValue(pos); + axis.curvePtr->setTrackingActive( false ); + axis.curvePtrAlt->setTrackingActive( true ); + } + else { + out = axis.invert * axis.curvePtr->getValue(pos); + axis.curvePtr->setTrackingActive( true ); + axis.curvePtrAlt->setTrackingActive( false ); + } + } } /** QThread run method @override **/ void Tracker::run() { -/** Direct Input variables **/ -// -// The DirectX stuff was found here: http://www.directxtutorial.com/tutorial9/e-directinput/dx9e2.aspx -// -LPDIRECTINPUT8 din; // the pointer to our DirectInput interface -LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device -LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device -BYTE keystate[256]; // the storage for the key-information -DIMOUSESTATE mousestate; // the storage for the mouse-information -HRESULT retAcquire; -bool lastCenterKey = false; // Remember state, to detect rising edge -bool lastStartStopKey = false; -bool lastInhibitKey = false; -bool lastGameZeroKey = false; - -bool lastCenterMouseKey = false; // Remember state, to detect rising edge -bool lastStartStopMouseKey = false; -bool lastInhibitMouseKey = false; -bool lastGameZeroMouseKey = false; - -bool waitAxisReverse = false; -bool waitThroughZero = false; -double actualYaw = 0.0f; -double actualZ = 0.0f; -T6DOF offset_camera(0,0,0,0,0,0); -T6DOF gamezero_camera(0,0,0,0,0,0); -T6DOF gameoutput_camera(0,0,0,0,0,0); - -bool bInitialCenter1 = true; -bool bInitialCenter2 = true; -bool bTracker1Confid = false; -bool bTracker2Confid = false; - - Tracker::do_tracking = true; // Start initially - Tracker::do_center = false; // Center initially - - // - // Test some Filter-stuff - // - if (pFilter) { - QString filterName; - //pFilter->getFullName(&filterName); - //qDebug() << "Tracker::run() FilterName = " << filterName; - } - - // - // Setup the DirectInput for keyboard strokes - // - // create the DirectInput interface - if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, - (void**)&din, NULL) != DI_OK) { // COM stuff, so we'll set it to NULL - qDebug() << "Tracker::setup DirectInput8 Creation failed!" << GetLastError(); - } - - // create the keyboard device - if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) { - qDebug() << "Tracker::setup CreateDevice function failed!" << GetLastError(); - } - // create the mouse device - din->CreateDevice(GUID_SysMouse, &dinmouse, NULL); - - // set the data format to keyboard format - if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) { - qDebug() << "Tracker::setup SetDataFormat function failed!" << GetLastError(); - } - // set the data format to mouse format - dinmouse->SetDataFormat(&c_dfDIMouse); - - // set the control you will have over the keyboard - if (dinkeyboard->SetCooperativeLevel(mainApp->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) { - qDebug() << "Tracker::setup SetCooperativeLevel function failed!" << GetLastError(); - } - // set the control you will have over the mouse - dinmouse->SetCooperativeLevel(mainApp->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); - - forever - { - - // Check event for stop thread - if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) - { - dinkeyboard->Unacquire(); // Unacquire keyboard - dinkeyboard->Release(); - dinmouse->Unacquire(); // Unacquire mouse - dinmouse->Release(); - din->Release(); // Release DirectInput - - // Set event - ::SetEvent(m_WaitThread); - qDebug() << "Tracker::run terminated run()"; - X.curvePtr->setTrackingActive( false ); - Y.curvePtr->setTrackingActive( false ); - Z.curvePtr->setTrackingActive( false ); - Yaw.curvePtr->setTrackingActive( false ); - Pitch.curvePtr->setTrackingActive( false ); - Pitch.curvePtrAlt->setTrackingActive( false ); - Roll.curvePtr->setTrackingActive( false ); - - return; - } + T6DOF current_camera; // Used for filtering + T6DOF target_camera; + T6DOF new_camera; - // - // Check the mouse - // - // get access if we don't have it already - retAcquire = dinmouse->Acquire(); - if ( (retAcquire != DI_OK) && (retAcquire != S_FALSE) ) { - qDebug() << "Tracker::run Acquire function failed!" << GetLastError(); - } - else { - if (dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate) != DI_OK) { - qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError(); - } - else { - // - // Check the state of the StartStop MouseKey - // - if ( isMouseKeyPressed( &StartStopMouseKey, &mousestate ) && (!lastStartStopMouseKey) ) { - Tracker::do_tracking = !Tracker::do_tracking; - - // - // To start tracking again and to be at '0', execute Center command too - // - if (Tracker::do_tracking) { - Tracker::confid = false; - if (pTracker) { - pTracker->StartTracker( mainApp->winId() ); - } - if (pSecondTracker) { - pSecondTracker->StartTracker( mainApp->winId() ); - } - } - else { - if (setEngineStop) { // Only stop engine when option is checked - if (pTracker) { - pTracker->StopTracker( false ); - } - if (pSecondTracker) { - pSecondTracker->StopTracker( false ); - } - } - } - qDebug() << "Tracker::run() says StartStop pressed, do_tracking =" << Tracker::do_tracking; - } - lastStartStopMouseKey = isMouseKeyPressed( &StartStopMouseKey, &mousestate ); // Remember - - // - // Check the state of the Center MouseKey - // - if ( isMouseKeyPressed( &CenterMouseKey, &mousestate ) && (!lastCenterMouseKey) ) { - Tracker::do_center = true; - qDebug() << "Tracker::run() says Center MouseKey pressed"; - } - lastCenterMouseKey = isMouseKeyPressed( &CenterMouseKey, &mousestate ); // Remember - - // - // Check the state of the GameZero MouseKey - // - if ( isMouseKeyPressed( &GameZeroMouseKey, &mousestate ) && (!lastGameZeroMouseKey) ) { - Tracker::do_game_zero = true; - qDebug() << "Tracker::run() says GameZero MouseKey pressed"; - } - lastGameZeroMouseKey = isMouseKeyPressed( &GameZeroMouseKey, &mousestate ); // Remember - - // - // Check the state of the Inhibit MouseKey - // - if ( isMouseKeyPressed( &InhibitMouseKey, &mousestate ) && (!lastInhibitMouseKey) ) { - Tracker::do_inhibit = !Tracker::do_inhibit; - qDebug() << "Tracker::run() says Inhibit MouseKey pressed"; - // - // Execute Center command too, when inhibition ends. - // - if (!Tracker::do_inhibit) { - Tracker::do_center = true; - } - } - lastInhibitMouseKey = isMouseKeyPressed( &InhibitMouseKey, &mousestate ); // Remember - } - } - - // - // Check the keyboard - // - // get access if we don't have it already - retAcquire = dinkeyboard->Acquire(); - if ( (retAcquire != DI_OK) && (retAcquire != S_FALSE) ) { - qDebug() << "Tracker::run Acquire function failed!" << GetLastError(); - } - else { - // get the input data - if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) { - qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError(); - } - else { - // - // Check the state of the Start/Stop key - // - if ( isShortKeyPressed( &StartStopKey, &keystate[0] ) && (!lastStartStopKey) ) { - Tracker::do_tracking = !Tracker::do_tracking; - - // - // To start tracking again and to be at '0', execute Center command too - // - if (Tracker::do_tracking) { - Tracker::confid = false; - if (pTracker) { - pTracker->StartTracker( mainApp->winId() ); - } - if (pSecondTracker) { - pSecondTracker->StartTracker( mainApp->winId() ); - } - } - else { - if (setEngineStop) { // Only stop engine when option is checked - if (pTracker) { - pTracker->StopTracker( false ); - } - if (pSecondTracker) { - pSecondTracker->StopTracker( false ); - } - } - } - qDebug() << "Tracker::run() says StartStop pressed, do_tracking =" << Tracker::do_tracking; - } - lastStartStopKey = isShortKeyPressed( &StartStopKey, &keystate[0] ); // Remember - - // - // Check the state of the Center key - // - if ( isShortKeyPressed( &CenterKey, &keystate[0] ) && (!lastCenterKey) ) { - Tracker::do_center = true; - qDebug() << "Tracker::run() says Center pressed"; - } - lastCenterKey = isShortKeyPressed( &CenterKey, &keystate[0] ); // Remember - - // - // Check the state of the GameZero key - // - if ( isShortKeyPressed( &GameZeroKey, &keystate[0] ) && (!lastGameZeroKey) ) { - Tracker::do_game_zero = true; - qDebug() << "Tracker::run() says GameZero pressed"; - } - lastGameZeroKey = isShortKeyPressed( &GameZeroKey, &keystate[0] ); // Remember - - // - // Check the state of the Inhibit key - // - if ( isShortKeyPressed( &InhibitKey, &keystate[0] ) && (!lastInhibitKey) ) { - Tracker::do_inhibit = !Tracker::do_inhibit; - qDebug() << "Tracker::run() says Inhibit pressed"; - // - // Execute Center command too, when inhibition ends. - // - if (!Tracker::do_inhibit) { - Tracker::do_center = true; - } - } - lastInhibitKey = isShortKeyPressed( &InhibitKey, &keystate[0] ); // Remember - } - } - - // - // Reset the 'wait' flag. Moving above 90 with the key pressed, will (de-)activate Axis Reverse. - // -// qDebug() << "Tracker::run() says actualZ = " << actualZ << ", terwijl Z_Pos4 = " << Z_Pos4ReverseAxis; - if (useAxisReverse) { - Tracker::do_axis_reverse = ((fabs(actualYaw) > YawAngle4ReverseAxis) && (actualZ < Z_Pos4ReverseAxis)); - } - else { - Tracker::do_axis_reverse = false; - } - - - if (WaitForSingleObject(Tracker::hTrackMutex, 100) == WAIT_OBJECT_0) { - - THeadPoseData newpose; - newpose.pitch = 0.0f; - newpose.roll = 0.0f; - newpose.yaw = 0.0f; - newpose.x = 0.0f; - newpose.y = 0.0f; - newpose.z = 0.0f; - - // - // The second tracker serves as 'secondary'. So if an axis is written by the second tracker it CAN be overwritten by the Primary tracker. - // This is enforced by the sequence below. - // - if (pSecondTracker) { - bTracker2Confid = pSecondTracker->GiveHeadPoseData(&newpose); - } - else { - bTracker2Confid = false; - bInitialCenter2 = false; - } - if (pTracker) { - bTracker1Confid = pTracker->GiveHeadPoseData(&newpose); -// qDebug() << "Tracker::run() says Roll = " << newpose.roll; - } - else { - bTracker1Confid = false; - bInitialCenter1 = false; - } - - Tracker::confid = (bTracker1Confid || bTracker2Confid); - if ( Tracker::confid ) { - addHeadPose(newpose); - } - - // - // If Center is pressed, copy the current values to the offsets. - // - if ((Tracker::do_center) || ((bInitialCenter1 && bTracker1Confid ) || (bInitialCenter2 && bTracker2Confid))) { - - if (!DisableBeep) { - MessageBeep (MB_ICONASTERISK); // Acknowledge the key-press with a beep. - } - if (pTracker && bTracker1Confid) { - pTracker->notifyCenter(); // Send 'center' to the tracker - bInitialCenter1 = false; - } - if (pSecondTracker && bTracker2Confid) { - pSecondTracker->notifyCenter(); // Send 'center' to the second tracker - bInitialCenter2 = false; - } - - // - // Only copy valid values - // - if (Tracker::confid) { - - offset_camera.x = getSmoothFromList( &X.rawList ); - offset_camera.y = getSmoothFromList( &Y.rawList ); - offset_camera.z = getSmoothFromList( &Z.rawList ); - offset_camera.pitch = getSmoothFromList( &Pitch.rawList ); - offset_camera.yaw = getSmoothFromList( &Yaw.rawList ); - offset_camera.roll = getSmoothFromList( &Roll.rawList ); - } - - Tracker::do_center = false; - } - - // - // If Set Game Zero is pressed, copy the current values to the offsets. - // Change requested by Stanislaw - // - if (Tracker::confid && Tracker::do_game_zero) { - if (pTracker) { - if (!pTracker->notifyZeroed()) - gamezero_camera = gameoutput_camera; - } -// gamezero_camera = gameoutput_camera; - - Tracker::do_game_zero = false; - } - - if (Tracker::do_tracking && Tracker::confid) { - - // get values - target_camera.x = getSmoothFromList( &X.rawList ); - target_camera.y = getSmoothFromList( &Y.rawList ); - target_camera.z = getSmoothFromList( &Z.rawList ); - target_camera.pitch = getSmoothFromList( &Pitch.rawList ); - target_camera.yaw = getSmoothFromList( &Yaw.rawList ); - target_camera.roll = getSmoothFromList( &Roll.rawList ); -// qDebug() << "Tracker::run() says Roll from Smoothing = " << target_camera.roll; - - // do the centering - target_camera = target_camera - offset_camera; - - // - // Use advanced filtering, when a filter was selected. - // - if (pFilter) { - pFilter->FilterHeadPoseData(¤t_camera, &target_camera, &new_camera, Tracker::Pitch.newSample); -// qDebug() << "Tracker::run() says Roll in Filter = " << current_camera.roll << ", Roll to output = " << new_camera.roll; - } - else { - new_camera = target_camera; -// qDebug() << "Tracker::run() says Roll to output = " << new_camera.roll; - } - output_camera.x = X.invert * X.curvePtr->getValue(new_camera.x); - output_camera.y = Y.invert * Y.curvePtr->getValue(new_camera.y); - output_camera.z = Z.invert * Z.curvePtr->getValue(new_camera.z); - - // - // Determine, which curve (Up or Down) must be used for Pitch - // - bool altp = (new_camera.pitch < 0); - if (altp) { - output_camera.pitch = Pitch.invert * Pitch.curvePtrAlt->getValue(new_camera.pitch); - Pitch.curvePtr->setTrackingActive( false ); - Pitch.curvePtrAlt->setTrackingActive( true ); - } - else { - output_camera.pitch = Pitch.invert * Pitch.curvePtr->getValue(new_camera.pitch); - Pitch.curvePtr->setTrackingActive( true ); - Pitch.curvePtrAlt->setTrackingActive( false ); - } - output_camera.yaw = Yaw.invert * Yaw.curvePtr->getValue(new_camera.yaw); - output_camera.roll = Roll.invert * Roll.curvePtr->getValue(new_camera.roll); - - X.curvePtr->setTrackingActive( true ); - Y.curvePtr->setTrackingActive( true ); - Z.curvePtr->setTrackingActive( true ); - Yaw.curvePtr->setTrackingActive( true ); - Roll.curvePtr->setTrackingActive( true ); - - // - // Reverse Axis. - // - actualYaw = output_camera.yaw; // Save the actual Yaw, otherwise we can't check for +90 - actualZ = output_camera.z; // Also the Z - if (Tracker::do_axis_reverse) { - output_camera.z = Z_PosWhenReverseAxis; // Set the desired Z-position - } - - // - // Reset value for the selected axis, if inhibition is active - // - if (Tracker::do_inhibit) { - if (InhibitKey.doPitch) output_camera.pitch = 0.0f; - if (InhibitKey.doYaw) output_camera.yaw = 0.0f; - if (InhibitKey.doRoll) output_camera.roll = 0.0f; - if (InhibitKey.doX) output_camera.x = 0.0f; - if (InhibitKey.doY) output_camera.y = 0.0f; - if (InhibitKey.doZ) output_camera.z = 0.0f; - } - - // - // Send the headpose to the game - // - if (pProtocol) { - gameoutput_camera = output_camera + gamezero_camera; - pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters - } - } - else { - // - // Go to initial position - // - if (pProtocol && setZero) { - output_camera.pitch = 0.0f; - output_camera.yaw = 0.0f; - output_camera.roll = 0.0f; - output_camera.x = 0.0f; - output_camera.y = 0.0f; - output_camera.z = 0.0f; - gameoutput_camera = output_camera + gamezero_camera; - pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters - } - X.curvePtr->setTrackingActive( false ); - Y.curvePtr->setTrackingActive( false ); - Z.curvePtr->setTrackingActive( false ); - Yaw.curvePtr->setTrackingActive( false ); - Pitch.curvePtr->setTrackingActive( false ); - Pitch.curvePtrAlt->setTrackingActive( false ); - Roll.curvePtr->setTrackingActive( false ); - } - } - - Tracker::Pitch.newSample = false; - ReleaseMutex(Tracker::hTrackMutex); - - //for lower cpu load - usleep(10000); - yieldCurrentThread(); - } -} - -/** 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 ); + /** Direct Input variables **/ + T6DOF offset_camera; + T6DOF gamezero_camera; + T6DOF gameoutput_camera; + + bool bTracker1Confid = false; + bool bTracker2Confid = false; + + THeadPoseData last; + + forever + { + if (should_quit) + break; + + // Check event for stop thread + + THeadPoseData newpose; + newpose.pitch = 0.0f; + newpose.roll = 0.0f; + newpose.yaw = 0.0f; + newpose.x = 0.0f; + newpose.y = 0.0f; + newpose.z = 0.0f; + + // + // The second tracker serves as 'secondary'. So if an axis is written by the second tracker it CAN be overwritten by the Primary tracker. + // This is enforced by the sequence below. + // + if (Libraries->pSecondTracker) { + bTracker2Confid = Libraries->pSecondTracker->GiveHeadPoseData(&newpose); + } + + if (Libraries->pTracker) { + bTracker1Confid = Libraries->pTracker->GiveHeadPoseData(&newpose); + } + + confid = (bTracker1Confid || bTracker2Confid); + + bool newp = last.yaw != newpose.yaw || + last.pitch != newpose.pitch || + last.roll != newpose.roll || + last.x != newpose.x || + last.y != newpose.y || + last.z != newpose.z; + + if (newp) + last = newpose; + + if ( confid ) { + GlobalPose->Yaw.headPos = newpose.yaw; + GlobalPose->Pitch.headPos = newpose.pitch; + GlobalPose->Roll.headPos = newpose.roll; + GlobalPose->X.headPos = newpose.x; + GlobalPose->Y.headPos = newpose.y; + GlobalPose->Z.headPos = newpose.z; + } + + // + // If Center is pressed, copy the current values to the offsets. + // + if (do_center) { + // + // Only copy valid values + // + if (Tracker::confid) { + offset_camera.x = GlobalPose->X.headPos; + offset_camera.y = GlobalPose->Y.headPos; + offset_camera.z = GlobalPose->Z.headPos; + offset_camera.pitch = GlobalPose->Pitch.headPos; + offset_camera.yaw = GlobalPose->Yaw.headPos; + offset_camera.roll = GlobalPose->Roll.headPos; + } + + Tracker::do_center = false; + + // for kalman + if (Libraries->pFilter) + Libraries->pFilter->Initialize(); + + last = newpose; + } + + if (do_game_zero) { + gamezero_camera = gameoutput_camera; + do_game_zero = false; + } + + if (Tracker::do_tracking && Tracker::confid) { + // get values + target_camera.x = GlobalPose->X.headPos; + target_camera.y = GlobalPose->Y.headPos; + target_camera.z = GlobalPose->Z.headPos; + target_camera.pitch = GlobalPose->Pitch.headPos; + target_camera.yaw = GlobalPose->Yaw.headPos; + target_camera.roll = GlobalPose->Roll.headPos; + + // do the centering + target_camera = target_camera - offset_camera; + + // + // Use advanced filtering, when a filter was selected. + // + if (Libraries->pFilter) { + THeadPoseData last_post_filter = gameoutput_camera; + Libraries->pFilter->FilterHeadPoseData(¤t_camera, &target_camera, &new_camera, &last_post_filter, newp); + } + else { + new_camera = target_camera; + } + + get_curve(do_inhibit && inhibit_rx, inhibit_zero, new_camera.yaw, output_camera.yaw, GlobalPose->Yaw); + get_curve(do_inhibit && inhibit_ry, inhibit_zero, new_camera.pitch, output_camera.pitch, GlobalPose->Pitch); + get_curve(do_inhibit && inhibit_rz, inhibit_zero, new_camera.roll, output_camera.roll, GlobalPose->Roll); + get_curve(do_inhibit && inhibit_tx, inhibit_zero, new_camera.x, output_camera.x, GlobalPose->X); + get_curve(do_inhibit && inhibit_ty, inhibit_zero, new_camera.y, output_camera.y, GlobalPose->Y); + get_curve(do_inhibit && inhibit_tz, inhibit_zero, new_camera.z, output_camera.z, GlobalPose->Z); + + if (useAxisReverse) { + do_axis_reverse = ((fabs(output_camera.yaw) > YawAngle4ReverseAxis) && (output_camera.z < Z_Pos4ReverseAxis)); + } else { + do_axis_reverse = false; + } + + // + // Reverse Axis. + // + if (Tracker::do_axis_reverse) { + output_camera.z = Z_PosWhenReverseAxis; // Set the desired Z-position + } + + // + // Send the headpose to the game + // + if (Libraries->pProtocol) { + gameoutput_camera = output_camera + gamezero_camera; + Libraries->pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters + } + } + else { + // + // Go to initial position + // + if (Libraries->pProtocol && inhibit_zero) { + output_camera.pitch = 0.0f; + output_camera.yaw = 0.0f; + output_camera.roll = 0.0f; + output_camera.x = 0.0f; + output_camera.y = 0.0f; + output_camera.z = 0.0f; + gameoutput_camera = output_camera + gamezero_camera; + Libraries->pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters + } + GlobalPose->X.curvePtr->setTrackingActive( false ); + GlobalPose->Y.curvePtr->setTrackingActive( false ); + GlobalPose->Z.curvePtr->setTrackingActive( false ); + GlobalPose->Yaw.curvePtr->setTrackingActive( false ); + GlobalPose->Pitch.curvePtr->setTrackingActive( false ); + GlobalPose->Pitch.curvePtrAlt->setTrackingActive( false ); + GlobalPose->Roll.curvePtr->setTrackingActive( false ); + if (Libraries->pFilter) + Libraries->pFilter->Initialize(); + } + + //for lower cpu load + usleep(10000); + } + + GlobalPose->X.curvePtr->setTrackingActive( false ); + GlobalPose->Y.curvePtr->setTrackingActive( false ); + GlobalPose->Z.curvePtr->setTrackingActive( false ); + GlobalPose->Yaw.curvePtr->setTrackingActive( false ); + GlobalPose->Pitch.curvePtr->setTrackingActive( false ); + GlobalPose->Pitch.curvePtrAlt->setTrackingActive( false ); + GlobalPose->Roll.curvePtr->setTrackingActive( false ); } // @@ -850,8 +319,8 @@ QString str; char dest[100]; str = QString("No protocol active?"); - if (pProtocol) { - pProtocol->getNameFromGame( dest ); + if (Libraries->pProtocol) { + Libraries->pProtocol->getNameFromGame( dest ); str = QString( dest ); } return str; @@ -876,36 +345,17 @@ bool Tracker::handleGameCommand ( int command ) { return false; } -// -// Add the new Raw value to the QList. -// Remove the last item(s), depending on the set maximum list-items. -// -void Tracker::addRaw2List ( QList *rawList, float maxIndex, float raw ) { - // - // Remove old values from the end of the QList. - // If the setting for MaxItems was lowered, the QList is shortened here... - // - while (rawList->size() >= maxIndex) { - rawList->removeLast(); - } - - // - // Insert the newest at the beginning. - // - rawList->prepend ( raw ); -} - // // Get the raw headpose, so it can be displayed. // void Tracker::getHeadPose( THeadPoseData *data ) { - data->x = Tracker::X.headPos; // centimeters - data->y = Tracker::Y.headPos; - data->z = Tracker::Z.headPos; + data->x = GlobalPose->X.headPos; // centimeters + data->y = GlobalPose->Y.headPos; + data->z = GlobalPose->Z.headPos; - data->pitch = Tracker::Pitch.headPos; // degrees - data->yaw = Tracker::Yaw.headPos; - data->roll = Tracker::Roll.headPos; + data->pitch = GlobalPose->Pitch.headPos; // degrees + data->yaw = GlobalPose->Yaw.headPos; + data->roll = GlobalPose->Roll.headPos; } // @@ -921,31 +371,10 @@ void Tracker::getOutputHeadPose( THeadPoseData *data ) { data->roll = output_camera.roll; } -// -// Get the Smoothed value from the QList. -// -float Tracker::getSmoothFromList ( QList *rawList ) { -float sum = 0; - - if (rawList->isEmpty()) return 0.0f; - - // - // Add the Raw values and divide. - // - for ( int i = 0; i < rawList->size(); i++) { - sum += rawList->at(i); - } - return sum / rawList->size(); -} - // // Load the current Settings from the currently 'active' INI-file. // void Tracker::loadSettings() { -//int NeutralZone; -//int sensYaw, sensPitch, sensRoll; -//int sensX, sensY, sensZ; - qDebug() << "Tracker::loadSettings says: Starting "; QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) @@ -954,128 +383,27 @@ void Tracker::loadSettings() { qDebug() << "loadSettings says: iniFile = " << currentFile; - // - // Read the Tracking settings, to fill the curves. - // - //iniFile.beginGroup ( "Tracking" ); - //NeutralZone = iniFile.value ( "NeutralZone", 5 ).toInt(); - //sensYaw = iniFile.value ( "sensYaw", 100 ).toInt(); - //sensPitch = iniFile.value ( "sensPitch", 100 ).toInt(); - //sensRoll = iniFile.value ( "sensRoll", 100 ).toInt(); - //sensX = iniFile.value ( "sensX", 100 ).toInt(); - //sensY = iniFile.value ( "sensY", 100 ).toInt(); - //sensZ = iniFile.value ( "sensZ", 100 ).toInt(); - //iniFile.endGroup (); - - // - // Read the keyboard shortcuts. - // + iniFile.beginGroup ( "Tracking" ); + iniFile.endGroup (); iniFile.beginGroup ( "KB_Shortcuts" ); - - // Center key - CenterMouseKey = iniFile.value ( "MouseKey_Center", 0 ).toInt(); - CenterKey.keycode = iniFile.value ( "Keycode_Center", DIK_HOME ).toInt(); - CenterKey.shift = iniFile.value ( "Shift_Center", 0 ).toBool(); - CenterKey.ctrl = iniFile.value ( "Ctrl_Center", 0 ).toBool(); - CenterKey.alt = iniFile.value ( "Alt_Center", 0 ).toBool(); - DisableBeep = iniFile.value ( "Disable_Beep", 0 ).toBool(); - - // StartStop key - StartStopMouseKey = iniFile.value ( "MouseKey_StartStop", 0 ).toInt(); - StartStopKey.keycode = iniFile.value ( "Keycode_StartStop", DIK_END ).toInt(); - StartStopKey.shift = iniFile.value ( "Shift_StartStop", 0 ).toBool(); - StartStopKey.ctrl = iniFile.value ( "Ctrl_StartStop", 0 ).toBool(); - StartStopKey.alt = iniFile.value ( "Alt_StartStop", 0 ).toBool(); - setZero = iniFile.value ( "SetZero", 1 ).toBool(); - setEngineStop = iniFile.value ( "SetEngineStop", 1 ).toBool(); - - // Inhibit key - InhibitMouseKey = iniFile.value ( "MouseKey_Inhibit", 0 ).toInt(); - InhibitKey.keycode = iniFile.value ( "Keycode_Inhibit", 0 ).toInt(); - InhibitKey.shift = iniFile.value ( "Shift_Inhibit", 0 ).toBool(); - InhibitKey.ctrl = iniFile.value ( "Ctrl_Inhibit", 0 ).toBool(); - InhibitKey.alt = iniFile.value ( "Alt_Inhibit", 0 ).toBool(); - InhibitKey.doPitch = iniFile.value ( "Inhibit_Pitch", 0 ).toBool(); - InhibitKey.doYaw = iniFile.value ( "Inhibit_Yaw", 0 ).toBool(); - InhibitKey.doRoll = iniFile.value ( "Inhibit_Roll", 0 ).toBool(); - InhibitKey.doX = iniFile.value ( "Inhibit_X", 0 ).toBool(); - InhibitKey.doY = iniFile.value ( "Inhibit_Y", 0 ).toBool(); - InhibitKey.doZ = iniFile.value ( "Inhibit_Z", 0 ).toBool(); - - // Game Zero key - GameZeroMouseKey = iniFile.value ( "MouseKey_GameZero", 0 ).toInt(); - GameZeroKey.keycode = iniFile.value ( "Keycode_GameZero", 0 ).toInt(); - GameZeroKey.shift = iniFile.value ( "Shift_GameZero", 0 ).toBool(); - GameZeroKey.ctrl = iniFile.value ( "Ctrl_GameZero", 0 ).toBool(); - GameZeroKey.alt = iniFile.value ( "Alt_GameZero", 0 ).toBool(); - - // Axis Reverse key - //AxisReverseKey.keycode = DIK_R; - //AxisReverseKey.shift = false; - //AxisReverseKey.ctrl = false; - //AxisReverseKey.alt = false; - - // Reverse Axis - useAxisReverse = iniFile.value ( "Enable_ReverseAxis", 0 ).toBool(); - YawAngle4ReverseAxis = iniFile.value ( "RA_Yaw", 40 ).toInt(); - Z_Pos4ReverseAxis = iniFile.value ( "RA_ZPos", 50 ).toInt(); - Z_PosWhenReverseAxis = iniFile.value ( "RA_ToZPos", 80 ).toInt(); - + // Reverse Axis + useAxisReverse = iniFile.value ( "Enable_ReverseAxis", 0 ).toBool(); + YawAngle4ReverseAxis = iniFile.value ( "RA_Yaw", 40 ).toInt(); + Z_Pos4ReverseAxis = iniFile.value ( "RA_ZPos", 50 ).toInt(); + Z_PosWhenReverseAxis = iniFile.value ( "RA_ToZPos", 80 ).toInt(); + inhibit_rx = iniFile.value("Inhibit_Yaw", false).toBool(); + inhibit_ry = iniFile.value("Inhibit_Pitch", false).toBool(); + inhibit_rz = iniFile.value("Inhibit_Roll", false).toBool(); + inhibit_tx = iniFile.value("Inhibit_X", false).toBool(); + inhibit_ty = iniFile.value("Inhibit_Y", false).toBool(); + inhibit_tz = iniFile.value("Inhibit_Z", false).toBool(); + inhibit_zero = iniFile.value("SetZero", false).toBool(); iniFile.endGroup (); } -// -// Determine if the ShortKey (incl. CTRL, SHIFT and/or ALT) is pressed. -// -bool Tracker::isShortKeyPressed( TShortKey *key, BYTE *keystate ){ -bool shift; -bool ctrl; -bool alt; - - // - // First, check if the right key is pressed. If so, check the modifiers - // - if (keystate[key->keycode] & 0x80) { - shift = ( (keystate[DIK_LSHIFT] & 0x80) || (keystate[DIK_RSHIFT] & 0x80) ); - ctrl = ( (keystate[DIK_LCONTROL] & 0x80) || (keystate[DIK_RCONTROL] & 0x80) ); - alt = ( (keystate[DIK_LALT] & 0x80) || (keystate[DIK_RALT] & 0x80) ); - - // - // If one of the modifiers is needed and not pressed, return false. - // - if (key->shift && !shift) return false; - if (key->ctrl && !ctrl) return false; - if (key->alt && !alt) return false; - - // - // All is well! - // - return true; - } - else { - return false; - } -} - -// -// Determine if the MouseKey is pressed. -// -bool Tracker::isMouseKeyPressed( int *key, DIMOUSESTATE *mousestate ){ - - // - // If key == NONE, or invalid: ready! - // - if ((*key <= 0) || (*key > 5)) { - return false; - } - - // - // Now, check if the right key is pressed. - // - if (mousestate->rgbButtons[*key-1] & 0x80) { - return true; - } - else { - return false; - } -} +void Tracker::setInvertPitch(bool invert) { GlobalPose->Pitch.invert = invert?-1.0f:1.0f; } +void Tracker::setInvertYaw(bool invert) { GlobalPose->Yaw.invert = invert?-1.0f:+1.0f; } +void Tracker::setInvertRoll(bool invert) { GlobalPose->Roll.invert = invert?-1.0f:+1.0f; } +void Tracker::setInvertX(bool invert) { GlobalPose->X.invert = invert?-1.0f:+1.0f; } +void Tracker::setInvertY(bool invert) { GlobalPose->Y.invert = invert?-1.0f:+1.0f; } +void Tracker::setInvertZ(bool invert) { GlobalPose->Z.invert = invert?-1.0f:+1.0f; } diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h index 4b161293..5cfcacd7 100644 --- a/facetracknoir/tracker.h +++ b/facetracknoir/tracker.h @@ -30,30 +30,35 @@ #include #include #include -#include #include #include #include #include #include - -#define DIRECTINPUT_VERSION 0x0800 -#include - -#include "FunctionConfig.h" - -#include "..\ftnoir_tracker_base\FTNoIR_Tracker_base.h" -#include "..\ftnoir_protocol_base\FTNoIR_Protocol_base.h" -#include "..\ftnoir_filter_base\FTNoIR_Filter_base.h" +#include +#include "global-settings.h" + +//#define DIRECTINPUT_VERSION 0x0800 +//#include +#undef FTNOIR_PROTOCOL_BASE_LIB +#undef FTNOIR_TRACKER_BASE_LIB +#undef FTNOIR_FILTER_BASE_LIB +#undef FTNOIR_PROTOCOL_BASE_EXPORT +#undef FTNOIR_TRACKER_BASE_EXPORT +#undef FTNOIR_FILTER_BASE_EXPORT +#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT + +#include +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ftnoir_filter_base/ftnoir_filter_base.h" #include "tracker_types.h" -typedef ITrackerPtr (WINAPI *importGetTracker)(void); -typedef IProtocolPtr (WINAPI *importGetProtocol)(void); -typedef IFilterPtr (WINAPI *importGetFilter)(void); - // include the DirectX Library files -#pragma comment (lib, "dinput8.lib") -#pragma comment (lib, "dxguid.lib") +//#pragma comment (lib, "dinput8.lib") +//#pragma comment (lib, "dxguid.lib") enum AngleName { PITCH = 0, @@ -88,127 +93,48 @@ enum FTNoIR_Tracker_Status { class FaceTrackNoIR; // pre-define parent-class to avoid circular includes +struct HeadPoseData; +extern HeadPoseData* GlobalPose; + // // Structure to hold all variables concerning one of 6 DOF's // class THeadPoseDOF { public: - - THeadPoseDOF(QString primary, QString secondary = "", int maxInput1 = 50, int maxOutput1 = 180, int maxInput2 = 50, int maxOutput2 = 90) { - QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - - curvePtr = new FunctionConfig(primary, maxInput1, maxOutput1); // Create the Function-config for input-output translation - curvePtr->loadSettings(iniFile); // Load the settings from the INI-file - if (secondary != "") { - curvePtrAlt = new FunctionConfig(secondary, maxInput2, maxOutput2); - curvePtrAlt->loadSettings(iniFile); - } - - } - - void initHeadPoseData(){ - headPos = 0.0f; - invert = 0.0f; - red = 0.0f; - rawList.clear(); - maxItems = 10.0f; - prevPos = 0.0f; - prevRawPos = 0.0f; - NeutralZone = 0; - MaxInput = 0; - confidence = 0.0f; - newSample = FALSE; - - qDebug() << "initHeadPoseData: " << curvePtr->getTitle(); - - } + THeadPoseDOF(QString primary, QString secondary, int maxInput1 = 50, int maxOutput1 = 180, int maxInput2 = 50, int maxOutput2 = 90) { + QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + + curvePtr = new FunctionConfig(primary, maxInput1, maxOutput1); // Create the Function-config for input-output translation + curvePtr->loadSettings(iniFile); // Load the settings from the INI-file + if (secondary != "") { + curvePtrAlt = new FunctionConfig(secondary, maxInput2, maxOutput2); + curvePtrAlt->loadSettings(iniFile); + } + headPos = 0.0f; + invert = 1; + altp = false; + } float headPos; // Current position (from faceTracker, radials or meters) - float invert; // Invert measured value (= 1.0f or -1.0f) - float red; // Reduction factor (used for EWMA-filtering, between 0.0f and 1.0f) - QList rawList; // List of 'n' headPos values (used for moving average) - int maxItems; // Maximum number of elements in rawList - float prevPos; // Previous Position - float prevRawPos; // Previous Raw Position - + float invert; // Invert measured value (= 1.0f or -1.0f) FunctionConfig* curvePtr; // Function to translate input -> output FunctionConfig* curvePtrAlt; - - int NeutralZone; // Neutral zone - int MaxInput; // Maximum raw input - float confidence; // Current confidence - bool newSample; // Indicate new sample from tracker -}; - -// -// Structure to hold keycode and CTRL, SHIFT, ALT for shortkeys -// -struct TShortKey { - BYTE keycode; // Required Key - bool shift; // Modifiers to examine - bool ctrl; - bool alt; - bool doPitch; // Modifiers to act on axis - bool doYaw; - bool doRoll; - bool doX; - bool doY; - bool doZ; + bool altp; }; class Tracker : public QThread { Q_OBJECT private: - // Handles to neatly terminate thread... - HANDLE m_StopThread; - HANDLE m_WaitThread; - - static T6DOF current_camera; // Used for filtering - static T6DOF target_camera; - static T6DOF new_camera; - static T6DOF output_camera; + bool useAxisReverse; // Use Axis Reverse + float YawAngle4ReverseAxis; // Axis Reverse settings + float Z_Pos4ReverseAxis; + float Z_PosWhenReverseAxis; + + volatile bool inhibit_rx, inhibit_ry, inhibit_rz, inhibit_tx, inhibit_ty, inhibit_tz, inhibit_zero; - ITrackerPtr pTracker; // Pointer to Tracker instance (in DLL) - ITrackerPtr pSecondTracker; // Pointer to second Tracker instance (in DLL) - static IProtocolPtr pProtocol; // Pointer to Protocol instance (in DLL) - static IFilterPtr pFilter; // Pointer to Filter instance (in DLL) - - static void addHeadPose( THeadPoseData head_pose ); - static void addRaw2List ( QList *rawList, float maxIndex, float raw ); - - static TShortKey CenterKey; // ShortKey to Center headposition - static TShortKey StartStopKey; // ShortKey to Start/stop tracking - static TShortKey InhibitKey; // ShortKey to disable one or more axis during tracking - static TShortKey GameZeroKey; // ShortKey to Set Game Zero -// static TShortKey AxisReverseKey; // ShortKey to reverse axis during tracking - - static int CenterMouseKey; // ShortKey to Center headposition - static int StartStopMouseKey; // ShortKey to Start/stop tracking - static int InhibitMouseKey; // ShortKey to disable one or more axis during tracking - static int GameZeroMouseKey; // ShortKey to Set Game Zero - static bool DisableBeep; // Disable Beep when center is pressed - - // Flags to start/stop/reset tracking - static bool confid; // Tracker data is OK - static bool do_tracking; // Start/stop tracking, using the shortkey - static bool do_center; // Center head-position, using the shortkey - static bool do_inhibit; // Inhibit DOF-axis, using the shortkey - static bool do_game_zero; // Set in-game zero, using the shortkey - static bool do_axis_reverse; // Axis reverse, using the shortkey - - static HANDLE hTrackMutex; // Prevent reading/writing the headpose simultaneously - - static bool setZero; // Set to zero's, when OFF (one-shot) - static bool setEngineStop; // Stop tracker->engine, when OFF - - static bool useAxisReverse; // Use Axis Reverse - static float YawAngle4ReverseAxis; // Axis Reverse settings - static float Z_Pos4ReverseAxis; - static float Z_PosWhenReverseAxis; - - FaceTrackNoIR *mainApp; + FaceTrackNoIR *mainApp; protected: // qthread override run method @@ -216,67 +142,63 @@ protected: public: Tracker( FaceTrackNoIR *parent ); - ~Tracker(); - - /** static member variables for saving the head pose **/ - static THeadPoseDOF Pitch; // Head-rotation X-direction (Up/Down) - static THeadPoseDOF Yaw; // Head-rotation Y-direction () - static THeadPoseDOF Roll; // Head-rotation Z-direction () - static THeadPoseDOF X; // Head-movement X-direction (Left/Right) - static THeadPoseDOF Y; // Head-movement Y-direction (Up/Down) - static THeadPoseDOF Z; // Head-movement Z-direction (To/From camera) - - void setup(); + ~Tracker(); // void registerHeadPoseCallback(); bool handleGameCommand ( int command ); QString getGameProgramName(); // Get the ProgramName from the game and display it. void loadSettings(); // Load settings from the INI-file - bool isShortKeyPressed( TShortKey *key, BYTE *keystate ); - bool isMouseKeyPressed( int *key, DIMOUSESTATE *mousestate ); - - static bool getTrackingActive() { return do_tracking && confid; } - static bool getAxisReverse() { return do_axis_reverse; } - - static bool getConfid() { return confid; } - - static void setInvertPitch(bool invert) { Pitch.invert = invert?-1.0f:+1.0f; } - static void setInvertYaw(bool invert) { Yaw.invert = invert?-1.0f:+1.0f; } - static void setInvertRoll(bool invert) { Roll.invert = invert?-1.0f:+1.0f; } - static void setInvertX(bool invert) { X.invert = invert?-1.0f:+1.0f; } - static void setInvertY(bool invert) { Y.invert = invert?-1.0f:+1.0f; } - static void setInvertZ(bool invert) { Z.invert = invert?-1.0f:+1.0f; } - - static void getHeadPose(THeadPoseData *data); // Return the current headpose data - static void getOutputHeadPose(THeadPoseData *data); // Return the current (processed) headpose data - static IFilterPtr getFilterPtr() { return pFilter; } // Return the pointer for the active Filter - ITracker *getTrackerPtr() { return pTracker; } // Return the pointer for the active Tracker - ITracker *getSecondTrackerPtr() { return pSecondTracker; } // Return the pointer for the secondary Tracker - IProtocol *getProtocolPtr() { return pProtocol; } // Return the pointer for the active Protocol - - void doRefreshVideo() { // Call the face-tracker-function RefreshVideo - if (pTracker) { - pTracker->refreshVideo(); - } - if (pSecondTracker) { - pSecondTracker->refreshVideo(); - } - }; - - static float getSmoothFromList ( QList *rawList ); - static float getDegreesFromRads ( float rads ) { return (rads * 57.295781f); } - static float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } - - // For now, use one slider for all - void setSmoothing(int x) { - Pitch.maxItems = x; - Yaw.maxItems = x; - Roll.maxItems = x; - X.maxItems = x; - Y.maxItems = x; - Z.maxItems = x; - } + //bool isShortKeyPressed( TShortKey *key, BYTE *keystate ); + //bool isMouseKeyPressed( int *key, DIMOUSESTATE *mousestate ); + + bool getTrackingActive() { return do_tracking && confid; } + bool getAxisReverse() { return do_axis_reverse; } + + bool getConfid() { return confid; } + + void setInvertPitch(bool invert); + void setInvertYaw(bool invert); + void setInvertRoll(bool invert); + void setInvertX(bool invert); + void setInvertY(bool invert); + void setInvertZ(bool invert); + + void getHeadPose(THeadPoseData *data); // Return the current headpose data + void getOutputHeadPose(THeadPoseData *data); // Return the current (processed) headpose data + + float getDegreesFromRads ( float rads ) { return (rads * 57.295781f); } + float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } + volatile bool should_quit; + // following are now protected by hTrackMutex + volatile bool do_tracking; // Start/stop tracking, using the shortkey + volatile bool do_center; // Center head-position, using the shortkey + volatile bool do_inhibit; // Inhibit DOF-axis, using the shortkey + volatile bool do_game_zero; // Set in-game zero, using the shortkey + volatile bool do_axis_reverse; // Axis reverse, using the shortkey + + // Flags to start/stop/reset tracking + volatile bool confid; // Tracker data is OK; + + T6DOF output_camera; +}; +struct HeadPoseData { +public: + THeadPoseDOF Pitch; + THeadPoseDOF Yaw; + THeadPoseDOF Roll; + THeadPoseDOF X; + THeadPoseDOF Y; + THeadPoseDOF Z; + HeadPoseData() : + Pitch("PitchUp", "PitchDown", 50, 180, 50, 90), + Yaw("Yaw", "YawAlt", 50, 180), + Roll("Roll", "RollAlt", 50, 180), + X("X","XAlt", 50, 180), + Y("Y","YAlt", 50, 180), + Z("Z","ZAlt", 50, 180) + { + } }; -#endif \ No newline at end of file +#endif diff --git a/facetracknoir/tracker_types.h b/facetracknoir/tracker_types.h index 5a13af85..d8e7ecee 100644 --- a/facetracknoir/tracker_types.h +++ b/facetracknoir/tracker_types.h @@ -28,12 +28,12 @@ #ifndef __TRACKER_TYPES_H__ #define __TRACKER_TYPES_H__ -#include "..\ftnoir_tracker_base\ftnoir_tracker_types.h" +#include "ftnoir_tracker_base/ftnoir_tracker_types.h" class T6DOF : public THeadPoseData { public: - T6DOF() : THeadPoseData() {} + T6DOF() : THeadPoseData() {} T6DOF(double x, double y, double z, double yaw, double pitch, double roll) : THeadPoseData(x,y,z, yaw,pitch,roll) {} @@ -42,4 +42,4 @@ public: T6DOF operator-(const T6DOF& A, const T6DOF& B); // get new pose with respect to reference pose B T6DOF operator+(const T6DOF& A, const T6DOF& B); // get new pose with respect to reference pose B^-1 -#endif //__TRACKER_TYPES_H__ \ No newline at end of file +#endif //__TRACKER_TYPES_H__ diff --git a/facetracknoir/uielements/facetracknoir.ico b/facetracknoir/uielements/facetracknoir.ico new file mode 100644 index 00000000..af36ec30 Binary files /dev/null and b/facetracknoir/uielements/facetracknoir.ico differ diff --git a/facetracknoir/uielements/setupfacetracknoir.jpg b/facetracknoir/uielements/setupfacetracknoir.jpg new file mode 100644 index 00000000..8778c6d5 Binary files /dev/null and b/facetracknoir/uielements/setupfacetracknoir.jpg differ -- cgit v1.2.3