From edc4fdcc4aaa9c501848c1a4b775cd2bef437091 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Sun, 8 Jan 2012 16:27:31 +0000 Subject: Making Filter-DLL into plug-in git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@97 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FaceTrackNoIR/FTNoIR_KeyboardShortcuts.ui | 56 ++- FaceTrackNoIR/FTNoIR_Preferences.ui | 35 +- FaceTrackNoIR/FaceTrackNoIR.cpp | 206 +++++++++- FaceTrackNoIR/FaceTrackNoIR.h | 7 + FaceTrackNoIR/FaceTrackNoIR.ui | 641 +++++++++++++++++++++--------- FaceTrackNoIR/Readme.txt | 26 +- FaceTrackNoIR/tracker.cpp | 166 ++++---- FaceTrackNoIR/tracker.h | 17 +- 8 files changed, 829 insertions(+), 325 deletions(-) diff --git a/FaceTrackNoIR/FTNoIR_KeyboardShortcuts.ui b/FaceTrackNoIR/FTNoIR_KeyboardShortcuts.ui index 41fc4d36..783b2a0e 100644 --- a/FaceTrackNoIR/FTNoIR_KeyboardShortcuts.ui +++ b/FaceTrackNoIR/FTNoIR_KeyboardShortcuts.ui @@ -7,7 +7,7 @@ 0 0 558 - 404 + 415 @@ -571,9 +571,15 @@ + + + 50 + 0 + + - 40 + 60 16777215 @@ -614,9 +620,15 @@ + + + 50 + 0 + + - 40 + 60 16777215 @@ -624,10 +636,10 @@ -50 - 50 + 150 - -20 + 50 @@ -647,9 +659,15 @@ + + + 50 + 0 + + - 40 + 60 16777215 @@ -657,7 +675,7 @@ -50 - 50 + 150 -20 @@ -702,6 +720,30 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + These settings are saved 'per game' (INI-file) + + + + + diff --git a/FaceTrackNoIR/FTNoIR_Preferences.ui b/FaceTrackNoIR/FTNoIR_Preferences.ui index 78e6aeaf..bb440fc6 100644 --- a/FaceTrackNoIR/FTNoIR_Preferences.ui +++ b/FaceTrackNoIR/FTNoIR_Preferences.ui @@ -7,7 +7,7 @@ 0 0 485 - 131 + 151 @@ -105,6 +105,39 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + These settings are saved globally (Registry) + + + false + + + + + diff --git a/FaceTrackNoIR/FaceTrackNoIR.cpp b/FaceTrackNoIR/FaceTrackNoIR.cpp index a9334752..58c60362 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/FaceTrackNoIR.cpp @@ -71,6 +71,16 @@ QMainWindow(parent, flags) _pose_display = new GLWidget(ui.widget4logo, 0); _pose_display->rotateBy(0, 0, 0); + ui.lblX->setVisible(false); + ui.lblY->setVisible(false); + ui.lblZ->setVisible(false); + ui.lblRotX->setVisible(false); + ui.lblRotY->setVisible(false); + ui.lblRotZ->setVisible(false); + + ui.lcdNumOutputPosX->setVisible(false); + ui.lcdNumOutputPosY->setVisible(false); + ui.lcdNumOutputPosZ->setVisible(false); ui.lcdNumOutputRotX->setVisible(false); ui.lcdNumOutputRotY->setVisible(false); ui.lcdNumOutputRotZ->setVisible(false); @@ -107,6 +117,7 @@ void FaceTrackNoIR::setupFaceTrackNoIR() { connect(ui.actionHeadPoseWidget, SIGNAL(triggered()), this, SLOT(showHeadPoseWidget())); connect(ui.btnShowEngineControls, SIGNAL(clicked()), this, SLOT(showEngineControls())); connect(ui.btnShowServerControls, SIGNAL(clicked()), this, SLOT(showServerControls())); + connect(ui.btnShowFilterControls, SIGNAL(clicked()), this, SLOT(showFilterControls())); // button methods connect with methods in this class connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(startTracker())); @@ -326,9 +337,9 @@ void FaceTrackNoIR::save() { iniFile.setValue ( "invertY", ui.chkInvertY->isChecked() ); iniFile.setValue ( "invertZ", ui.chkInvertZ->isChecked() ); iniFile.setValue ( "useEWMA", ui.chkUseEWMA->isChecked() ); - iniFile.setValue ( "minSmooth", ui.minSmooth->value() ); - iniFile.setValue ( "powCurve", ui.powCurve->value() ); - iniFile.setValue ( "maxSmooth", ui.maxSmooth->value() ); + //iniFile.setValue ( "minSmooth", ui.minSmooth->value() ); + //iniFile.setValue ( "powCurve", ui.powCurve->value() ); + //iniFile.setValue ( "maxSmooth", ui.maxSmooth->value() ); iniFile.endGroup (); iniFile.beginGroup ( "GameProtocol" ); @@ -410,7 +421,7 @@ void FaceTrackNoIR::loadSettings() { // Put the filename in the window-title. // QFileInfo pathInfo ( currentFile ); - setWindowTitle ( "FaceTrackNoIR (1.6) - " + pathInfo.fileName() ); + setWindowTitle ( "FaceTrackNoIR (1.7) - " + pathInfo.fileName() ); // // Get a List of all the INI-files in the (currently active) Settings-folder. @@ -447,9 +458,9 @@ void FaceTrackNoIR::loadSettings() { ui.chkInvertZ->setChecked (iniFile.value ( "invertZ", 0 ).toBool()); ui.chkUseEWMA->setChecked (iniFile.value ( "useEWMA", 1 ).toBool()); - ui.minSmooth->setValue (iniFile.value ( "minSmooth", 15 ).toInt()); - ui.maxSmooth->setValue (iniFile.value ( "maxSmooth", 50 ).toInt()); - ui.powCurve->setValue (iniFile.value ( "powCurve", 10 ).toInt()); + //ui.minSmooth->setValue (iniFile.value ( "minSmooth", 15 ).toInt()); + //ui.maxSmooth->setValue (iniFile.value ( "maxSmooth", 50 ).toInt()); + //ui.powCurve->setValue (iniFile.value ( "powCurve", 10 ).toInt()); iniFile.endGroup (); iniFile.beginGroup ( "GameProtocol" ); @@ -576,6 +587,17 @@ void FaceTrackNoIR::startTracker( ) { // Start the timer to update the head-pose (digits and 'man in black') // timUpdateHeadPose->start(10); + + ui.lblX->setVisible(true); + ui.lblY->setVisible(true); + ui.lblZ->setVisible(true); + ui.lblRotX->setVisible(true); + ui.lblRotY->setVisible(true); + ui.lblRotZ->setVisible(true); + + ui.lcdNumOutputPosX->setVisible(true); + ui.lcdNumOutputPosY->setVisible(true); + ui.lcdNumOutputPosZ->setVisible(true); ui.lcdNumOutputRotX->setVisible(true); ui.lcdNumOutputRotY->setVisible(true); ui.lcdNumOutputRotZ->setVisible(true); @@ -589,6 +611,18 @@ void FaceTrackNoIR::stopTracker( ) { // timUpdateHeadPose->stop(); _pose_display->rotateBy(0, 0, 0); + + + ui.lblX->setVisible(false); + ui.lblY->setVisible(false); + ui.lblZ->setVisible(false); + ui.lblRotX->setVisible(false); + ui.lblRotY->setVisible(false); + ui.lblRotZ->setVisible(false); + + ui.lcdNumOutputPosX->setVisible(false); + ui.lcdNumOutputPosY->setVisible(false); + ui.lcdNumOutputPosZ->setVisible(false); ui.lcdNumOutputRotX->setVisible(false); ui.lcdNumOutputRotY->setVisible(false); ui.lcdNumOutputRotZ->setVisible(false); @@ -701,9 +735,13 @@ THeadPoseData newdata; Tracker::getOutputHeadPose(&newdata); _pose_display->rotateBy(newdata.pitch, newdata.yaw, newdata.roll); - ui.lcdNumOutputRotX->display((double) (((int)(newdata.yaw * 10.0f))/10.0f)); - ui.lcdNumOutputRotY->display((double) (((int)(newdata.pitch * 10.0f))/10.0f)); - ui.lcdNumOutputRotZ->display((double) (((int)(newdata.roll * 10.0f))/10.0f)); + 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)); } } @@ -888,6 +926,51 @@ QString libName; } } +/** toggles Filter Controls Dialog **/ +void FaceTrackNoIR::showFilterControls() { +importGetFilterDialog getIT; +QLibrary *filterLib; + + 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) + + // + // Read the currently selected Filter from the INI-file. + // + iniFile.beginGroup ( "Filter" ); + QString selectedFilterName = iniFile.value ( "Selection", "FTNoIR_Filter_EWMA2.dll" ).toString(); + qDebug() << "createIconGroupBox says: selectedFilterName = " << selectedFilterName; + iniFile.endGroup (); + + // + // Delete the existing QDialog + // + if (pFilterDialog) { + pFilterDialog.Release(); + } + + filterLib = new QLibrary(selectedFilterName); + + getIT = (importGetFilterDialog) filterLib->resolve("GetFilterDialog"); + if (getIT) { + IFilterDialogPtr ptrXyz(getIT()); + if (ptrXyz) + { + pFilterDialog = ptrXyz; + pFilterDialog->Initialize( this ); + 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); + } +} + /** toggles FaceTrackNoIR Preferences Dialog **/ void FaceTrackNoIR::showPreferences() { @@ -946,6 +1029,15 @@ void FaceTrackNoIR::exit() { // void FaceTrackNoIR::createIconGroupBox() { +importGetFilterDialog getIT; +QLibrary *filterLib; +QString *filterName; + + 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) + ui.iconcomboBox->addItem(QIcon(":/images/Freetrack.ico"), tr("Freetrack")); ui.iconcomboBox->addItem(QIcon(":/images/FlightGear.ico"), tr("FlightGear")); ui.iconcomboBox->addItem(QIcon(":/images/FaceTrackNoIR.ico"), tr("FTNoir client")); @@ -963,6 +1055,70 @@ void FaceTrackNoIR::createIconGroupBox() # endif + // + // Read the currently selected Filter from the INI-file. + // + iniFile.beginGroup ( "Filter" ); + QString selectedFilterName = iniFile.value ( "Selection", "FTNoIR_Filter_EWMA2.dll" ).toString(); + qDebug() << "createIconGroupBox says: selectedFilterName = " << selectedFilterName; + iniFile.endGroup (); + + // + // Get a List of all the Filter-DLL-files in the Program-folder. + // + QDir settingsDir( QCoreApplication::applicationDirPath() ); + QStringList filters; + filters << "FTNoIR_Filter_*.dll"; + filterFileList.clear(); + filterFileList = 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(); + for ( int i = 0; i < filterFileList.size(); i++) { + + qDebug() << "createIconGroupBox says: FilterName = " << filterFileList.at(i); + + // + // Delete the existing QDialog + // + if (pFilterDialog) { + pFilterDialog.Release(); + } + + // Show the appropriate Protocol-server Settings + filterLib = new QLibrary(filterFileList.at(i)); + filterName = new QString(""); + + getIT = (importGetFilterDialog) filterLib->resolve("GetFilterDialog"); + if (getIT) { + IFilterDialogPtr ptrXyz(getIT()); + if (ptrXyz) + { + pFilterDialog = ptrXyz; + pFilterDialog->getFilterFullName( filterName ); + qDebug() << "FaceTrackNoIR::showServerControls GetFilterDialog Function Resolved!"; + } + else { + qDebug() << "FaceTrackNoIR::showServerControls Function NOT Resolved!"; + } + } + else { + QMessageBox::warning(0,"FaceTrackNoIR Error", "DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton); + } + + ui.iconcomboFilter->addItem(QIcon(":/images/Settings16.png"), *filterName ); + if (filterFileList.at(i) == selectedFilterName) { + ui.iconcomboFilter->setItemIcon(i, QIcon(":/images/SettingsOpen16.png")); + ui.iconcomboFilter->setCurrentIndex( i ); + } + } + connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + } // @@ -1099,6 +1255,24 @@ void FaceTrackNoIR::profileSelected(int index) loadSettings(); } +// +// Handle changes of the Filter selection +// +void FaceTrackNoIR::filterSelected(int index) +{ + //// + //// Read the current INI-file setting, to get the folder in which it's located... + //// + //QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + //QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + // QFileInfo pathInfo ( currentFile ); + + //// + //// Get a List of all the INI-files in the (currently active) Settings-folder. + //// + //settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + iniFileList.at(ui.iconcomboProfile->currentIndex())); + //loadSettings(); +} // // Constructor for FaceTrackNoIR=Preferences-dialog @@ -1536,9 +1710,9 @@ int keyindex; // Reverse Axis ui.chkEnableReverseAxis->setChecked (iniFile.value ( "Enable_ReverseAxis", 0 ).toBool()); - ui.spinYawAngle4ReverseAxis->setValue( settings.value ( "RA_Yaw", 40 ).toInt() ); - ui.spinZ_Pos4ReverseAxis->setValue( settings.value ( "RA_ZPos", -20 ).toInt() ); - ui.spinZ_PosWhenReverseAxis->setValue( settings.value ( "RA_ToZPos", 50 ).toInt() ); + ui.spinYawAngle4ReverseAxis->setValue( iniFile.value ( "RA_Yaw", 40 ).toInt() ); + ui.spinZ_Pos4ReverseAxis->setValue( iniFile.value ( "RA_ZPos", -20 ).toInt() ); + ui.spinZ_PosWhenReverseAxis->setValue( iniFile.value ( "RA_ToZPos", 50 ).toInt() ); iniFile.endGroup (); @@ -1590,9 +1764,9 @@ void KeyboardShortcutDialog::save() { // Reverse Axis iniFile.setValue ( "Enable_ReverseAxis", ui.chkEnableReverseAxis->isChecked() ); - settings.setValue( "RA_Yaw", ui.spinYawAngle4ReverseAxis->value() ); - settings.setValue( "RA_ZPos", ui.spinZ_Pos4ReverseAxis->value() ); - settings.setValue( "RA_ToZPos", ui.spinZ_PosWhenReverseAxis->value() ); + iniFile.setValue( "RA_Yaw", ui.spinYawAngle4ReverseAxis->value() ); + iniFile.setValue( "RA_ZPos", ui.spinZ_Pos4ReverseAxis->value() ); + iniFile.setValue( "RA_ToZPos", ui.spinZ_PosWhenReverseAxis->value() ); iniFile.endGroup (); diff --git a/FaceTrackNoIR/FaceTrackNoIR.h b/FaceTrackNoIR/FaceTrackNoIR.h index 9dc38071..c17d21d7 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.h +++ b/FaceTrackNoIR/FaceTrackNoIR.h @@ -45,6 +45,7 @@ // #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 "AutoClosePtr.h" // 1a. COM-Like usage with smart pointer. @@ -54,6 +55,8 @@ typedef AutoClosePtr ITrackerDia typedef ITrackerDialog *(WINAPI *importGetTrackerDialog)(void); typedef AutoClosePtr IProtocolDialogPtr; typedef IProtocolDialog *(WINAPI *importGetProtocolDialog)(void); +typedef AutoClosePtr IFilterDialogPtr; +typedef IFilterDialog *(WINAPI *importGetFilterDialog)(void); #include @@ -82,9 +85,11 @@ private: 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 filterFileList; // List of Filter-DLL-files, that are present in the program-folder ITrackerDialogPtr pTrackerDialog; // Pointer to Tracker dialog instance (in DLL) IProtocolDialogPtr pProtocolDialog; // Pointer to Protocol dialog instance (in DLL) + IFilterDialogPtr pFilterDialog; // Pointer to Filter dialog instance (in DLL) /** Widget variables **/ QVBoxLayout *l; @@ -135,11 +140,13 @@ private: void iconActivated(QSystemTrayIcon::ActivationReason reason); void trackingSourceSelected(int index); void profileSelected(int index); + void filterSelected(int index); void showVideoWidget(); void showHeadPoseWidget(); void showEngineControls(); void showServerControls(); + void showFilterControls(); void showPreferences(); void showKeyboardShortcuts(); void showCurveConfiguration(); diff --git a/FaceTrackNoIR/FaceTrackNoIR.ui b/FaceTrackNoIR/FaceTrackNoIR.ui index ef21ab82..7cb74b0a 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.ui +++ b/FaceTrackNoIR/FaceTrackNoIR.ui @@ -11,7 +11,7 @@ 0 0 925 - 411 + 528 @@ -220,7 +220,7 @@ QGroupBox { 100 - 20 + 1 145 34 @@ -246,9 +246,9 @@ Support FaceTrackNoIR! - 100 - 60 - 41 + 196 + 34 + 50 21 @@ -265,7 +265,7 @@ Support FaceTrackNoIR! QFrame::Raised - 3 + 5 QLCDNumber::Flat @@ -274,9 +274,9 @@ Support FaceTrackNoIR! - 150 - 60 - 41 + 196 + 52 + 50 21 @@ -293,7 +293,7 @@ Support FaceTrackNoIR! QFrame::Raised - 3 + 5 QLCDNumber::Flat @@ -302,9 +302,93 @@ Support FaceTrackNoIR! - 200 - 60 - 41 + 196 + 70 + 50 + 21 + + + + false + + + color: rgb(0, 255, 0); + + + QFrame::NoFrame + + + QFrame::Raised + + + 5 + + + QLCDNumber::Flat + + + + + + 114 + 34 + 50 + 21 + + + + false + + + color: rgb(0, 255, 0); + + + QFrame::NoFrame + + + QFrame::Raised + + + 5 + + + QLCDNumber::Flat + + + + + + 114 + 52 + 50 + 21 + + + + false + + + color: rgb(0, 255, 0); + + + QFrame::NoFrame + + + QFrame::Raised + + + 5 + + + QLCDNumber::Flat + + + + + + 114 + 70 + 50 21 @@ -321,12 +405,108 @@ Support FaceTrackNoIR! QFrame::Raised - 3 + 5 QLCDNumber::Flat + + + + 104 + 35 + 16 + 16 + + + + color: rgb(0, 255, 0); + + + X + + + + + + 105 + 55 + 16 + 16 + + + + color: rgb(0, 255, 0); + + + Y + + + + + + 105 + 74 + 16 + 16 + + + + color: rgb(0, 255, 0); + + + Z + + + + + + 168 + 74 + 20 + 16 + + + + color: rgb(0, 255, 0); + + + rotZ + + + + + + 167 + 35 + 20 + 16 + + + + color: rgb(0, 255, 0); + + + rotX + + + + + + 168 + 55 + 20 + 16 + + + + color: rgb(0, 255, 0); + + + rotY + + @@ -980,161 +1160,6 @@ color: rgb(0, 255, 0); - - - - - 200 - 120 - - - - - - - Tracker Source - - - - - 10 - 20 - 180 - 22 - - - - - - - -1 - - - 3 - - - - - false - - - - 10 - 80 - 180 - 23 - - - - Change tracker settings - - - - - - Settings - - - - - - 10 - 50 - 81 - 23 - - - - Start the Tracker - - - - - - Start - - - - - false - - - - 109 - 50 - 81 - 23 - - - - Stop the Tracker - - - - - - Stop - - - - - - - - - 190 - 100 - - - - - - - Game protocol - - - - - 10 - 20 - 180 - 22 - - - - - - - -1 - - - 7 - - - - - true - - - - 10 - 80 - 180 - 23 - - - - Change game protocol settings - - - - - - Settings - - - - @@ -2069,6 +2094,228 @@ background:none; + + + + 10 + + + 10 + + + + + + 200 + 120 + + + + + + + Tracker Source + + + + + 10 + 20 + 180 + 22 + + + + + + + -1 + + + 3 + + + + + false + + + + 10 + 80 + 180 + 23 + + + + Change tracker settings + + + + + + Settings + + + + + + 10 + 50 + 81 + 23 + + + + Start the Tracker + + + + + + Start + + + + + false + + + + 109 + 50 + 81 + 23 + + + + Stop the Tracker + + + + + + Stop + + + + + + + + + 190 + 100 + + + + + + + Game protocol + + + + + 10 + 20 + 180 + 22 + + + + + + + -1 + + + 7 + + + + + true + + + + 10 + 80 + 180 + 23 + + + + Change game protocol settings + + + + + + Settings + + + + + + + + + 190 + 100 + + + + + + + Filter + + + + + 10 + 20 + 180 + 22 + + + + + + + -1 + + + 7 + + + + + true + + + + 10 + 80 + 180 + 23 + + + + Change game protocol settings + + + + + + Settings + + + + + + @@ -2309,11 +2556,11 @@ background:none; 442 - 347 + 387 494 - 349 + 389 @@ -2325,11 +2572,11 @@ background:none; 494 - 349 + 389 442 - 347 + 387 @@ -2340,12 +2587,12 @@ background:none; setValue(int) - 648 - 293 + 643 + 333 - 696 - 295 + 691 + 335 @@ -2356,12 +2603,12 @@ background:none; setValue(int) - 696 - 295 + 691 + 335 - 648 - 293 + 643 + 333 @@ -2372,12 +2619,12 @@ background:none; setValue(int) - 648 - 320 + 643 + 360 - 696 - 322 + 691 + 362 @@ -2388,12 +2635,12 @@ background:none; setValue(int) - 696 - 322 + 691 + 362 - 648 - 320 + 643 + 360 @@ -2404,12 +2651,12 @@ background:none; setValue(int) - 648 - 347 + 643 + 387 - 696 - 349 + 691 + 389 @@ -2420,12 +2667,12 @@ background:none; setValue(int) - 696 - 349 + 691 + 389 - 648 - 347 + 643 + 387 diff --git a/FaceTrackNoIR/Readme.txt b/FaceTrackNoIR/Readme.txt index bdd1a5d3..8bd28966 100644 --- a/FaceTrackNoIR/Readme.txt +++ b/FaceTrackNoIR/Readme.txt @@ -1,29 +1,23 @@ -FaceTrackNoIR (v. 1.0.0). +FaceTrackNoIR (v. 1.6.0). -FaceTrackNoIR is a head-tracker, which uses the FaceAPI provided by SeeingMachines. It was made using Visual Studio 2008 and Qt.The major advantage over other headtrackers is, that it uses a simple webcam to track the face of 'the gamer'. There is no need for expensive equipment or even Borg-like devices with LED's and such. +FaceTrackNoIR is a head-tracker, which uses the FaceAPI provided by SeeingMachines. It was made using Visual Studio 2005 and Qt. +The major advantage over other headtrackers is, that it uses a simple webcam to track the face of 'the gamer'. There is no need +for expensive equipment or even Borg-like devices with LED's and such. Installation: To install the program, simply start Setup.exe and follow the directions. Use the desktop-icon to start FaceTrackNoIR. Compatibility: -FaceTrackNoIR is made for Windows and tested on XP, Vista and Windows7. The FaceAPI creators recommend a dual-core processor or better. Because the 'non-commercial' version of the FaceAPI is used, the webcam can not be 'chosen': it always uses the first webcam it finds! When FaceTrackNoIR is started, the name of this webcam is displayed. +FaceTrackNoIR is made for Windows and tested on XP, Vista and Windows7. The FaceAPI creators recommend a dual-core processor or better. +Because the 'non-commercial' version of the FaceAPI is used, the webcam can not be 'chosen': it always uses the first webcam it finds! When FaceTrackNoIR is started, the name of this webcam is displayed. Games: -Until now, FaceTrackNoIR supports the protocol created by Free-track (ArmA 2 supports this) and FlightGear. We are working on others... - -Testing: -To test the Free-track protocol, we included FreeTrackTest.exe, which was made by the Free-track team. If this works, ArmA 2 also will. - -Settings: -The head-tracking settings can be loaded and saved, using the menu-items under 'File'. The last settings will automatically load on startup. It may be necessary to fiddle with these settings: the provided .ini files are not really optimized! - -Remarks: -- To reduce CPU-load it is best to minimize FaceTrackNoIR before starting/switching to the game. -- The combobox 'Game protocol' shows 3 choices, however it does not actually do anything with the selection (yet). Both Free-track and FlightGear protocols are started. -- We are planning to make FaceTrackNoIR 'server-client' modes. This way the head-tracking can be run on one computer and the game on another. This should significantly improve performance. +FaceTrackNoIR supports several protocols, so it can be used with several games, flight-sims and other. Check out the website for a +list: http://facetracknoir.sourceforge.net/compatibility/games.htm +Visit the website for the latest info! Please let us know if you like the program, if you have ideas for improvements or any questions you might have. @@ -34,4 +28,4 @@ The FaceTrackNoIR team: Wim Vriend Ron Hendriks - +and others... diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 5f67352a..59f6680b 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -74,6 +74,11 @@ 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); @@ -91,7 +96,7 @@ 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 -TShortKey Tracker::AxisReverseKey; // ShortKey to start/stop axis reverse while tracking +//TShortKey Tracker::AxisReverseKey; // ShortKey to start/stop axis reverse while tracking ITrackerPtr Tracker::pTracker; // Pointer to Tracker instance (in DLL) IProtocolPtr Tracker::pProtocol; // Pointer to Protocol instance (in DLL) @@ -496,28 +501,20 @@ T6DOF gameoutput_camera(0,0,0,0,0,0); } } lastInhibitKey = isShortKeyPressed( &InhibitKey, &keystate[0] ); // Remember - - // - // Check the state of the Axis Reverse key - // - ////if ( isShortKeyPressed( &AxisReverseKey, &keystate[0] ) ) { - //// if ((fabs(actualYaw) > 90.0f) && (!waitAxisReverse)) { - //// Tracker::do_axis_reverse = !Tracker::do_axis_reverse; - //// waitAxisReverse = true; - //// } - ////} } } // // Reset the 'wait' flag. Moving above 90 with the key pressed, will (de-)activate Axis Reverse. // - //////if (fabs(actualYaw) < 85.0f) { - ////// waitAxisReverse = false; - //////} - //// if { -// qDebug() << "Tracker::run() says actualZ = " << actualZ; - Tracker::do_axis_reverse = ((fabs(actualYaw) > 90.0f) && (actualZ < -20.0f)); + 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) { @@ -587,7 +584,7 @@ T6DOF gameoutput_camera(0,0,0,0,0,0); actualYaw = output_camera.position.yaw; // Save the actual Yaw, otherwise we can't check for +90 actualZ = output_camera.position.z; // Also the Z if (Tracker::do_axis_reverse) { - output_camera.position.z = 100; // Max. + output_camera.position.z = Z_PosWhenReverseAxis; // Set the desired Z-position } // @@ -777,7 +774,7 @@ void Tracker::setPowCurve( int x ) { } // -// Set the filter-value from the GUI. +// Get the raw headpose, so it can be displayed. // void Tracker::getHeadPose( THeadPoseData *data ) { data->x = Tracker::X.headPos - Tracker::X.offset_headPos; // centimeters @@ -790,7 +787,7 @@ void Tracker::getHeadPose( THeadPoseData *data ) { } // -// Set the filter-value from the GUI. +// Get the output-headpose, so it can be displayed. // void Tracker::getOutputHeadPose( THeadPoseData *data ) { data->x = output_camera.position.x; // centimeters @@ -822,27 +819,27 @@ float sum = 0; // // Correct the Raw value, with the Neutral Zone supplied // -float Tracker::getCorrectedNewRaw ( float NewRaw, float rotNeutral ) { - - // - // Return 0, if NewRaw is within the Neutral Zone - // - if ( fabs( NewRaw ) < rotNeutral ) { - return 0.0f; - } - - // - // NewRaw is outside the zone. - // Substract rotNeutral from the NewRaw - // - if ( NewRaw > 0.0f ) { - return (NewRaw - rotNeutral); - } - else { - return (NewRaw + rotNeutral); // Makes sense? - } - -} +//float Tracker::getCorrectedNewRaw ( float NewRaw, float rotNeutral ) { +// +// // +// // Return 0, if NewRaw is within the Neutral Zone +// // +// if ( fabs( NewRaw ) < rotNeutral ) { +// return 0.0f; +// } +// +// // +// // NewRaw is outside the zone. +// // Substract rotNeutral from the NewRaw +// // +// if ( NewRaw > 0.0f ) { +// return (NewRaw - rotNeutral); +// } +// else { +// return (NewRaw + rotNeutral); // Makes sense? +// } +// +//} // // Implementation of an Exponentially Weighted Moving Average, used to serve as a low-pass filter. @@ -851,48 +848,48 @@ float Tracker::getCorrectedNewRaw ( float NewRaw, float rotNeutral ) { // The function takes the new value, the delta-time (sec) and a weighing coefficient (>0 and <1) // All previous values are taken into account, the weight of this is determined by 'coeff'. // -float Tracker::lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff) { -float c = 0.0f; -float fil = 0.0f; - - c = dt / (coeff + dt); - fil = (newvalue * c) + (*oldvalue * (1 - c)); - *oldvalue = fil; - - return fil; -} +//float Tracker::lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff) { +//float c = 0.0f; +//float fil = 0.0f; +// +// c = dt / (coeff + dt); +// fil = (newvalue * c) + (*oldvalue * (1 - c)); +// *oldvalue = fil; +// +// return fil; +//} // // Implementation of a Rate Limiter, used to eliminate spikes in the raw data. // // The function takes the new value, the delta-time (sec) and the positive max. slew-rate (engineering units/sec) // -float Tracker::rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate) { -float rate = 0.0f; -float clamped_value = 0.0f; - - rate = (newvalue - *oldvalue) / dt; - clamped_value = newvalue; // If all is well, the newvalue is returned - - // - // One max-rate is used for ramp-up and ramp-down - // If the rate exceeds max_rate, return the maximum value that the max_rate allows - // - if (fabs(rate) > max_rate) { - // - // For ramp-down, apply a factor -1 to the max_rate - // - if (rate < 0.0f) { - clamped_value = (-1.0f * dt * max_rate) + *oldvalue; - } - else { - clamped_value = (dt * max_rate) + *oldvalue; - } - } - *oldvalue = clamped_value; - - return clamped_value; -} +//float Tracker::rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate) { +//float rate = 0.0f; +//float clamped_value = 0.0f; +// +// rate = (newvalue - *oldvalue) / dt; +// clamped_value = newvalue; // If all is well, the newvalue is returned +// +// // +// // One max-rate is used for ramp-up and ramp-down +// // If the rate exceeds max_rate, return the maximum value that the max_rate allows +// // +// if (fabs(rate) > max_rate) { +// // +// // For ramp-down, apply a factor -1 to the max_rate +// // +// if (rate < 0.0f) { +// clamped_value = (-1.0f * dt * max_rate) + *oldvalue; +// } +// else { +// clamped_value = (dt * max_rate) + *oldvalue; +// } +// } +// *oldvalue = clamped_value; +// +// return clamped_value; +//} // // Get the output from the curve. @@ -1062,11 +1059,16 @@ QPointF point1, point2, point3, point4; GameZeroKey.alt = iniFile.value ( "Alt_GameZero", 0 ).toBool(); // Axis Reverse key - AxisReverseKey.keycode = DIK_R; - AxisReverseKey.shift = false; - AxisReverseKey.ctrl = false; - AxisReverseKey.alt = false; - + //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(); iniFile.endGroup (); } diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 79af07a1..dd8a961b 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -40,7 +40,7 @@ #include "..\ftnoir_tracker_base\FTNoIR_Tracker_base.h" #include "..\ftnoir_protocol_base\FTNoIR_Protocol_base.h" -#include "FTNoIR_Filter_base.h" +#include "..\ftnoir_filter_base\FTNoIR_Filter_base.h" #include "AutoClosePtr.h" // 1a. COM-Like usage with smart pointer. @@ -162,9 +162,9 @@ private: static void addHeadPose( THeadPoseData head_pose ); static void addRaw2List ( QList *rawList, float maxIndex, float raw ); - static float lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff); - static float rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate); - static float getCorrectedNewRaw ( float NewRaw, float rotNeutral ); +// static float lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff); +// static float rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate); +// static float getCorrectedNewRaw ( float NewRaw, float rotNeutral ); /** static member variables for saving the head pose **/ static THeadPoseDOF Pitch; // Head-rotation X-direction (Up/Down) @@ -178,7 +178,7 @@ private: 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 TShortKey AxisReverseKey; // ShortKey to reverse axis during tracking // Flags to start/stop/reset tracking static bool confid; // Tracker data is OK @@ -193,7 +193,12 @@ private: static bool useFilter; // Use EWMA-filtering 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; QSharedPointer debug_Client; // Protocol Server to log debug-data -- cgit v1.2.3