From 28c091a886e6c98f41d3f5f8b153768b4a589fcd Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Fri, 1 Apr 2011 17:16:11 +0000 Subject: Started with placing the protocol's in DLL's. First one: FlightGear. git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@60 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FTNoIR_Filter_EWMA2/ftnoir_filter_ewma2.cpp | 18 + FTNoIR_Protocol_Base/ftnoir_protocol_base.h | 65 ++++ FTNoIR_Protocol_Base/ftnoir_protocol_base_global.h | 12 + FTNoIR_Protocol_FG/FTNoIR_FGcontrols.ui | 279 +++++++++++++++ FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.cpp | 388 +++++++++++++++++++++ FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.h | 96 +++++ FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.vcproj | 328 +++++++++++++++++ FaceTrackNoIR.sln | 6 + FaceTrackNoIR.suo | Bin 367104 -> 367104 bytes FaceTrackNoIR/FaceTrackNoIR.cpp | 7 +- FaceTrackNoIR/tracker.cpp | 56 ++- FaceTrackNoIR/tracker.h | 4 + bin/FaceTrackNoIR.exe | Bin 663552 -> 663552 bytes 13 files changed, 1249 insertions(+), 10 deletions(-) create mode 100644 FTNoIR_Protocol_Base/ftnoir_protocol_base.h create mode 100644 FTNoIR_Protocol_Base/ftnoir_protocol_base_global.h create mode 100644 FTNoIR_Protocol_FG/FTNoIR_FGcontrols.ui create mode 100644 FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.cpp create mode 100644 FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.h create mode 100644 FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.vcproj diff --git a/FTNoIR_Filter_EWMA2/ftnoir_filter_ewma2.cpp b/FTNoIR_Filter_EWMA2/ftnoir_filter_ewma2.cpp index 957f5aec..7bdac328 100644 --- a/FTNoIR_Filter_EWMA2/ftnoir_filter_ewma2.cpp +++ b/FTNoIR_Filter_EWMA2/ftnoir_filter_ewma2.cpp @@ -1,6 +1,10 @@ #include "ftnoir_filter_base.h" #include "math.h" #include +#include +#include + +//#define LOG_OUTPUT ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -157,6 +161,7 @@ void FTNoIR_Filter_EWMA2::FilterHeadPoseData(THeadPoseData *current_camera_posit for (i=0;i<6;i++) { output[i]=target[i]; + prev_alpha[i] = 0.0f; } new_camera_position->x=target[0]; @@ -215,6 +220,19 @@ void FTNoIR_Filter_EWMA2::FilterHeadPoseData(THeadPoseData *current_camera_posit // output[i]=(smoothed_alpha[i]*target[i])+((1.0f-smoothed_alpha[i])*prev_output[i]); } + + #ifdef LOG_OUTPUT + // Use this for some debug-output to file... + QFile data(QCoreApplication::applicationDirPath() + "\\EWMA_output.txt"); + if (data.open(QFile::WriteOnly | QFile::Append)) { + QTextStream out(&data); + out << "output:\t" << output[0] << "\t" << output[1] << "\t" << output[2] << "\t" << output[3] << "\t" << output[4] << "\t" << output[5] << '\n'; + out << "target:\t" << target[0] << "\t" << target[1] << "\t" << target[2] << "\t" << target[3] << "\t" << target[4] << "\t" << target[5] << '\n'; + out << "prev_output:\t" << prev_output[0] << "\t" << prev_output[1] << "\t" << prev_output[2] << "\t" << prev_output[3] << "\t" << prev_output[4] << "\t" << prev_output[5] << '\n'; + out << "largest_alpha:\t" << largest_alpha << '\n'; + } + #endif + new_camera_position->x=output[0]; new_camera_position->y=output[1]; new_camera_position->z=output[2]; diff --git a/FTNoIR_Protocol_Base/ftnoir_protocol_base.h b/FTNoIR_Protocol_Base/ftnoir_protocol_base.h new file mode 100644 index 00000000..92372740 --- /dev/null +++ b/FTNoIR_Protocol_Base/ftnoir_protocol_base.h @@ -0,0 +1,65 @@ +#ifndef FTNOIR_PROTOCOL_BASE_H +#define FTNOIR_PROTOCOL_BASE_H + +#include "ftnoir_protocol_base_global.h" +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include +#include +#include "windows.h" + +// COM-Like abstract interface. +// This interface doesn't require __declspec(dllexport/dllimport) specifier. +// Method calls are dispatched via virtual table. +// Any C++ compiler can use it. +// Instances are obtained via factory function. +struct IProtocol +{ + virtual void Release() = 0; // Member required to enable Auto-remove + virtual void Initialize() = 0; + virtual bool checkServerInstallationOK ( HANDLE handle ) = 0; + virtual void sendHeadposeToGame( T6DOF *headpose ) = 0; +}; + +// Handle type. In C++ language the iterface type is used. +typedef IProtocol* PROTOCOLHANDLE; + +//////////////////////////////////////////////////////////////////////////////// +// +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif // __cplusplus + +// Factory function that creates instances of the Protocol object. +EXTERN_C +FTNOIR_PROTOCOL_BASE_EXPORT +PROTOCOLHANDLE +__stdcall +GetProtocol( + void); + + +// COM-Like abstract interface. +// This interface doesn't require __declspec(dllexport/dllimport) specifier. +// Method calls are dispatched via virtual table. +// Any C++ compiler can use it. +// Instances are obtained via factory function. +struct IProtocolDialog +{ + virtual void Release() = 0; // Member required to enable Auto-remove + virtual void Initialize(QWidget *parent) = 0; +}; + +// Handle type. In C++ language the iterface type is used. +typedef IProtocolDialog* PROTOCOLDIALOGHANDLE; + +// Factory function that creates instances of the Protocol object. +EXTERN_C +FTNOIR_PROTOCOL_BASE_EXPORT +PROTOCOLDIALOGHANDLE +__stdcall +GetProtocolDialog(void); + + +#endif // FTNOIR_PROTOCOL_BASE_H diff --git a/FTNoIR_Protocol_Base/ftnoir_protocol_base_global.h b/FTNoIR_Protocol_Base/ftnoir_protocol_base_global.h new file mode 100644 index 00000000..3527bad7 --- /dev/null +++ b/FTNoIR_Protocol_Base/ftnoir_protocol_base_global.h @@ -0,0 +1,12 @@ +#ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H +#define FTNOIR_PROTOCOL_BASE_GLOBAL_H + +#include + +#ifdef FTNOIR_PROTOCOL_BASE_LIB +# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT +#else +# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#endif + +#endif // FTNOIR_PROTOCOL_BASE_GLOBAL_H diff --git a/FTNoIR_Protocol_FG/FTNoIR_FGcontrols.ui b/FTNoIR_Protocol_FG/FTNoIR_FGcontrols.ui new file mode 100644 index 00000000..c5f81c29 --- /dev/null +++ b/FTNoIR_Protocol_FG/FTNoIR_FGcontrols.ui @@ -0,0 +1,279 @@ + + + UICFGControls + + + + 0 + 0 + 411 + 194 + + + + FlightGear settings FaceTrackNoIR + + + + images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + + + Qt::LeftToRight + + + false + + + + + + + + + 60 + 16777215 + + + + 255 + + + 1 + + + + + + + + 60 + 16777215 + + + + 255 + + + 1 + + + + + + + + 60 + 16777215 + + + + 255 + + + 1 + + + + + + + + 60 + 16777215 + + + + 255 + + + 1 + + + + + + + IP-address remote PC + + + + + + + Qt::RightToLeft + + + Local PC only + + + + + + + Port-number + + + + + + + 5550 + + + 10000 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + If FlightGear is on the same PC as FaceTrackNoIR, tick the 'Local PC only' box. + + + + + + + Otherwise: enter IP-address and port-number for the remote PC. + + + true + + + + + + + Remember: you may have to change firewall-settings too! + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + OK + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Cancel + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + + spinIPFirstNibble + spinIPSecondNibble + spinIPThirdNibble + spinIPFourthNibble + spinPortNumber + btnOK + btnCancel + chkLocalPC + + + + + startEngineClicked() + stopEngineClicked() + cameraSettingsClicked() + + diff --git a/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.cpp b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.cpp new file mode 100644 index 00000000..cb03c70e --- /dev/null +++ b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.cpp @@ -0,0 +1,388 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of the some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2010 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +* FGServer FGServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +/* + Modifications (last one on top): + 20110401 - WVR: Moved protocol to a DLL, convenient for installation etc. + 20101224 - WVR: Base class is no longer inheriting QThread. sendHeadposeToGame + is called from run() of Tracker.cpp +*/ +#include "ftnoir_protocol_fg.h" + +/** constructor **/ +FTNoIR_Protocol_FG::FTNoIR_Protocol_FG() +{ + loadSettings(); +} + +/** destructor **/ +FTNoIR_Protocol_FG::~FTNoIR_Protocol_FG() +{ + if (inSocket != 0) { + inSocket->close(); + delete inSocket; + } + + if (outSocket != 0) { + outSocket->close(); + delete outSocket; + } +} + +/** helper to Auto-destruct **/ +void FTNoIR_Protocol_FG::Release() +{ + delete this; +} + +void FTNoIR_Protocol_FG::Initialize() +{ + return; +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol_FG::loadSettings() { + 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 ( "FG" ); + + bool blnLocalPC = iniFile.value ( "LocalPCOnly", 1 ).toBool(); + if (blnLocalPC) { + destIP = QHostAddress::LocalHost; + } + else { + QString destAddr = iniFile.value ( "IP-1", 192 ).toString() + "." + iniFile.value ( "IP-2", 168 ).toString() + "." + iniFile.value ( "IP-3", 2 ).toString() + "." + iniFile.value ( "IP-4", 1 ).toString(); + destIP = QHostAddress( destAddr ); + } + destPort = iniFile.value ( "PortNumber", 5550 ).toInt(); + + iniFile.endGroup (); + +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol_FG::sendHeadposeToGame( T6DOF *headpose ) { +int no_bytes; +QHostAddress sender; +quint16 senderPort; + + // + // Copy the Raw measurements directly to the client. + // + FlightData.x = headpose->position.x / 100.0f; + FlightData.y = headpose->position.y / 100.0f; + FlightData.z = headpose->position.z / 100.0f; + FlightData.p = headpose->position.pitch; + FlightData.h = headpose->position.yaw; + FlightData.r = headpose->position.roll; + FlightData.status = fg_cmd; + + // + // Try to send an UDP-message to the FlightGear + // + + //! [1] +// no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), QHostAddress::LocalHost, 5550); + if (outSocket != 0) { + no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), destIP, destPort); + if ( no_bytes > 0) { + // qDebug() << "FGServer::writePendingDatagrams says: bytes send =" << no_bytes << sizeof( double ); + } + else { + qDebug() << "FGServer::writePendingDatagrams says: nothing sent!"; + } + } + + // + // FlightGear keeps sending data, so we must read that here. + // + if (inSocket != 0) { + while (inSocket->hasPendingDatagrams()) { + + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + + inSocket->readDatagram( (char * ) &cmd, sizeof(cmd), &sender, &senderPort); + + fg_cmd = cmd; // Let's just accept that command for now... + if ( cmd > 0 ) { + qDebug() << "FGServer::sendHeadposeToGame hasPendingDatagrams, cmd = " << cmd; +// headTracker->handleGameCommand ( cmd ); // Send it upstream, for the Tracker to handle + } + } + } +} + +// +// Check if the Client DLL exists and load it (to test it), if so. +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol_FG::checkServerInstallationOK( HANDLE handle ) +{ + // Init. the data + FlightData.x = 0.0f; + FlightData.y = 0.0f; + FlightData.z = 0.0f; + FlightData.h = 0.0f; + FlightData.p = 0.0f; + FlightData.r = 0.0f; + FlightData.status = 0; + fg_cmd = 1; + + inSocket = 0; + outSocket = 0; + + // + // Create UDP-sockets. + // + if (inSocket == 0) { + qDebug() << "FGServer::sendHeadposeToGame creating insocket"; + inSocket = new QUdpSocket(); + + // Connect the inSocket to the port, to receive messages + if (!inSocket->bind(QHostAddress::Any, destPort+1)) { + QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton); + delete inSocket; + inSocket = 0; + return false; + } + } + + if (outSocket == 0) { + outSocket = new QUdpSocket(); + } + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol object. + +// Export both decorated and undecorated names. +// GetProtocol - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocol@0 - Common name decoration for __stdcall functions in C language. +#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0") + +FTNOIR_PROTOCOL_BASE_EXPORT PROTOCOLHANDLE __stdcall GetProtocol() +{ + return new FTNoIR_Protocol_FG; +} + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +FGControls::FGControls( QWidget *parent, Qt::WindowFlags f ) : +QWidget( parent , f) +{ + ui.setupUi( this ); + + QPoint offsetpos(100, 100); + this->move(parent->pos() + offsetpos); + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.chkLocalPC, SIGNAL(stateChanged(int)), this, SLOT(chkLocalPCOnlyChanged())); + connect(ui.spinIPFirstNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPSecondNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPThirdNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +FGControls::~FGControls() { + qDebug() << "~FGControls() says: started"; +} + +void FGControls::Release() +{ + delete this; +} + +// +// Initialize tracker-client-dialog +// +void FGControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void FGControls::doOK() { + save(); + this->close(); +} + +// override show event +void FGControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FGControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FGControls::loadSettings() { +// 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(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FG" ); + ui.chkLocalPC->setChecked (iniFile.value ( "LocalPCOnly", 1 ).toBool()); + + ui.spinIPFirstNibble->setValue( iniFile.value ( "IP-1", 192 ).toInt() ); + ui.spinIPSecondNibble->setValue( iniFile.value ( "IP-2", 168 ).toInt() ); + ui.spinIPThirdNibble->setValue( iniFile.value ( "IP-3", 2 ).toInt() ); + ui.spinIPFourthNibble->setValue( iniFile.value ( "IP-4", 1 ).toInt() ); + + ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); + iniFile.endGroup (); + + chkLocalPCOnlyChanged(); + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FGControls::save() { + 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 ( "FG" ); + iniFile.setValue ( "LocalPCOnly", ui.chkLocalPC->isChecked() ); + iniFile.setValue ( "IP-1", ui.spinIPFirstNibble->value() ); + iniFile.setValue ( "IP-2", ui.spinIPSecondNibble->value() ); + iniFile.setValue ( "IP-3", ui.spinIPThirdNibble->value() ); + iniFile.setValue ( "IP-4", ui.spinIPFourthNibble->value() ); + iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Handle change of the checkbox. +// +void FGControls::chkLocalPCOnlyChanged() { + + if ( ui.chkLocalPC->isChecked() ) { + ui.spinIPFirstNibble->setValue( 127 ); + ui.spinIPFirstNibble->setEnabled ( false ); + ui.spinIPSecondNibble->setValue( 0 ); + ui.spinIPSecondNibble->setEnabled ( false ); + ui.spinIPThirdNibble->setValue( 0 ); + ui.spinIPThirdNibble->setEnabled ( false ); + ui.spinIPFourthNibble->setValue( 1 ); + ui.spinIPFourthNibble->setEnabled ( false ); + } + else { + ui.spinIPFirstNibble->setEnabled ( true ); + ui.spinIPSecondNibble->setEnabled ( true ); + ui.spinIPThirdNibble->setEnabled ( true ); + ui.spinIPFourthNibble->setEnabled ( true ); + } + + settingsDirty = true; +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +FTNOIR_PROTOCOL_BASE_EXPORT PROTOCOLDIALOGHANDLE __stdcall GetProtocolDialog( ) +{ + return new FGControls; +} diff --git a/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.h b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.h new file mode 100644 index 00000000..220dc60d --- /dev/null +++ b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.h @@ -0,0 +1,96 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of the some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2010 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +* FGServer FGServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FGSERVER_H +#define INCLUDED_FGSERVER_H + +#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h" +#include "ui_FTNoIR_FGcontrols.h" +#include "..\facetracknoir\FGTypes.h" +#include +#include +#include +#include +#include "Windows.h" +#include "math.h" + +class FTNoIR_Protocol_FG : public IProtocol +{ +public: + FTNoIR_Protocol_FG(); + ~FTNoIR_Protocol_FG(); + + void Release(); + void Initialize(); + + bool checkServerInstallationOK( HANDLE handle ); + void sendHeadposeToGame( T6DOF *headpose ); + +private: +// Tracker *headTracker; // For upstream messages... + TFlightGearData FlightData; + QUdpSocket *inSocket; // Receive from FligthGear + QUdpSocket *outSocket; // Send to FligthGear + qint32 cmd; + qint32 fg_cmd; // Command from FlightGear + QHostAddress destIP; // Destination IP-address + int destPort; // Destination port-number + void loadSettings(); + +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class FGControls: public QWidget, Ui::UICFGControls, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit FGControls( QWidget *parent=0, Qt::WindowFlags f=0 ); + virtual ~FGControls(); + void showEvent ( QShowEvent * event ); + + void Release(); // Member functions which are accessible from outside the DLL + void Initialize(QWidget *parent); + +private: + Ui::UICFGControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + +private slots: + void doOK(); + void doCancel(); + void chkLocalPCOnlyChanged(); + void settingChanged() { settingsDirty = true; }; +}; + +#endif//INCLUDED_FGSERVER_H +//END diff --git a/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.vcproj b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.vcproj new file mode 100644 index 00000000..eae8510a --- /dev/null +++ b/FTNoIR_Protocol_FG/FTNoIR_Protocol_FG.vcproj @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FaceTrackNoIR.sln b/FaceTrackNoIR.sln index 64bab306..633d424d 100644 --- a/FaceTrackNoIR.sln +++ b/FaceTrackNoIR.sln @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FTNoIR_Tracker_SM", "FTNoIR EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FTNoIR_FaceAPI_EXE", "faceAPI\FaceAPI2FSX.vcproj", "{EF743D32-0980-44D9-BA9E-B9D2456251AC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FTNoIR_Protocol_FG", "FTNoIR_Protocol_FG\FTNoIR_Protocol_FG.vcproj", "{7C77C833-5687-4A35-B219-4CF4D3D8E626}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -46,6 +48,10 @@ Global {EF743D32-0980-44D9-BA9E-B9D2456251AC}.Debug|Win32.Build.0 = Debug|Win32 {EF743D32-0980-44D9-BA9E-B9D2456251AC}.Release|Win32.ActiveCfg = Release|Win32 {EF743D32-0980-44D9-BA9E-B9D2456251AC}.Release|Win32.Build.0 = Release|Win32 + {7C77C833-5687-4A35-B219-4CF4D3D8E626}.Debug|Win32.ActiveCfg = Debug|Win32 + {7C77C833-5687-4A35-B219-4CF4D3D8E626}.Debug|Win32.Build.0 = Debug|Win32 + {7C77C833-5687-4A35-B219-4CF4D3D8E626}.Release|Win32.ActiveCfg = Release|Win32 + {7C77C833-5687-4A35-B219-4CF4D3D8E626}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FaceTrackNoIR.suo b/FaceTrackNoIR.suo index 982e6626..9f9c2c5c 100644 Binary files a/FaceTrackNoIR.suo and b/FaceTrackNoIR.suo differ diff --git a/FaceTrackNoIR/FaceTrackNoIR.cpp b/FaceTrackNoIR/FaceTrackNoIR.cpp index 51acf6ec..d2373824 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/FaceTrackNoIR.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ /* Modifications (last one on top): + 20110401 - WVR: The about-dialog was shown 'misplaced'. It was corrected. 20110328 - WVR: Added the display for output-pose. 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. @@ -478,9 +479,9 @@ void FaceTrackNoIR::openurl_donation() { /** show about dialog **/ void FaceTrackNoIR::about() { - aboutDialog.move(this->width()/2-135, - this->height()/2-220); - + + QPoint offsetpos(100, 100); + aboutDialog.move(this->pos() + offsetpos); aboutDialog.show(); /** ABOUT DIALOG **/ diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 38c72437..cb881201 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -86,6 +86,7 @@ TShortKey Tracker::StartStopKey; // ShortKey to Start/stop tracking TShortKey Tracker::InhibitKey; // ShortKey to inhibit axis while tracking 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) @@ -95,6 +96,8 @@ importGetTracker getIT; QLibrary *trackerLib; importGetFilter getFilter; QLibrary *filterLib; +importGetProtocol getProtocol; +QLibrary *protocolLib; QFrame *video_frame; // Retieve the pointer to the parent @@ -184,7 +187,28 @@ QFrame *video_frame; break; case FLIGHTGEAR: - server_Game = QSharedPointer(new FGServer ( this )); // Create FlightGear protocol-server + server_Game = QSharedPointer(new FTServer ( )); // Create Free-track protocol-server +// server_Game = QSharedPointer(new FGServer ( this )); // Create FlightGear protocol-server +// server_Game = NULL; + // + // Load the DLL with the protocol-logic and retrieve a pointer to the Protocol-class. + // + protocolLib = new QLibrary("FTNoIR_Protocol_FG.dll"); + + 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; + } break; case FTNOIR: @@ -297,6 +321,19 @@ void Tracker::setup() { } + // + // 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) { + 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) { @@ -499,12 +536,12 @@ void Tracker::run() { pFilter->FilterHeadPoseData(¤t_camera.position, &target_camera.position, &new_camera.position, Tracker::Pitch.newSample); } else { - output_camera.position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos; - output_camera.position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos; - output_camera.position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos; - output_camera.position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos; - output_camera.position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos; - output_camera.position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos; + new_camera.position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos; + new_camera.position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos; + new_camera.position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos; + new_camera.position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos; + new_camera.position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos; + new_camera.position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos; } output_camera.position.x = X.invert * getOutputFromCurve(&X.curve, new_camera.position.x, X.NeutralZone, X.MaxInput); output_camera.position.y = Y.invert * getOutputFromCurve(&Y.curve, new_camera.position.y, Y.NeutralZone, Y.MaxInput); @@ -549,6 +586,11 @@ void Tracker::run() { server_Game->setVirtPosZ ( output_camera.position.z ); } + // All Protocol server(s) + if (pProtocol) { + pProtocol->sendHeadposeToGame( &output_camera ); // degrees & centimeters + } + // headRotXLine->setText(QString("%1").arg( new_camera.position.pitch, 0, 'f', 1)); // show degrees // headRotYLine->setText(QString("%1").arg( new_camera.position.yaw, 0, 'f', 1)); // headRotZLine->setText(QString("%1").arg( new_camera.position.roll, 0, 'f', 1)); diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 3b7d7ca8..1ffed69c 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -46,6 +46,7 @@ #include "FTNoIR_cxx_protocolserver.h" #include "..\ftnoir_tracker_base\FTNoIR_Tracker_base.h" +#include "..\ftnoir_protocol_base\FTNoIR_Protocol_base.h" #include "FTNoIR_Filter_base.h" #include "AutoClosePtr.h" @@ -54,6 +55,8 @@ // be released automatically in destructor of the smart pointer. typedef AutoClosePtr ITrackerPtr; typedef ITracker *(WINAPI *importGetTracker)(void); +typedef AutoClosePtr IProtocolPtr; +typedef IProtocol *(WINAPI *importGetProtocol)(void); typedef AutoClosePtr IFilterPtr; typedef IFilter *(WINAPI *importGetFilter)(void); @@ -157,6 +160,7 @@ private: static T6DOF output_camera; static ITrackerPtr pTracker; // Pointer to 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 ); diff --git a/bin/FaceTrackNoIR.exe b/bin/FaceTrackNoIR.exe index 75adfa6f..60dbfc51 100644 Binary files a/bin/FaceTrackNoIR.exe and b/bin/FaceTrackNoIR.exe differ -- cgit v1.2.3