diff options
136 files changed, 6147 insertions, 5320 deletions
| diff --git a/compat/compat.cpp b/compat/compat.cpp new file mode 100644 index 00000000..2263ea11 --- /dev/null +++ b/compat/compat.cpp @@ -0,0 +1,84 @@ +/* Copyright (c) 2013 Stanisław Halik <sthalik@misaki.pl> + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ +#define IN_FTNOIR_COMPAT +#include "compat.h" + +#if defined(_WIN32) || defined(__WIN32) + +PortableLockedShm::PortableLockedShm(const char* shmName, const char* mutexName, int mapSize) +{ +    hMutex = CreateMutexA(NULL, false, mutexName); +    hMapFile = CreateFileMappingA( +                 INVALID_HANDLE_VALUE, +                 NULL, +                 PAGE_READWRITE, +                 0, +                 mapSize, +                 shmName); +    mem = MapViewOfFile(hMapFile, +                        FILE_MAP_READ | FILE_MAP_WRITE, +                        0, +                        0, +                        mapSize); +} + +PortableLockedShm::~PortableLockedShm() +{ +    UnmapViewOfFile(mem); +    CloseHandle(hMapFile); +    CloseHandle(hMutex); +} + +void PortableLockedShm::lock() +{ +    (void) WaitForSingleObject(hMutex, INFINITE); +} + +void PortableLockedShm::unlock() +{ +    (void) ReleaseMutex(hMutex); +} + +#else +PortableLockedShm::PortableLockedShm(const char *shmName, const char *mutexName, int mapSize) : size(mapSize) +{ +    char shm_filename[NAME_MAX]; +    shm_filename[0] = '/'; +    strncpy(shm_filename+1, shmName, NAME_MAX-2); +    sprintf(shm_filename + strlen(shm_filename), "%ld\n", (long) getuid()); +    shm_filename[NAME_MAX-1] = '\0'; + +    //(void) shm_unlink(shm_filename); + +    fd = shm_open(shm_filename, O_RDWR | O_CREAT, 0600); +    if (ftruncate(fd, mapSize) == 0) +        mem = mmap(NULL, mapSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)0); +    else +        mem = (void*) -1; +} + +PortableLockedShm::~PortableLockedShm() +{ +    //(void) shm_unlink(shm_filename); + +    (void) munmap(mem, size); +    (void) close(fd); +} + +void PortableLockedShm::lock() +{ +    flock(fd, LOCK_EX); +} + +void PortableLockedShm::unlock() +{ +    flock(fd, LOCK_UN); +} + + + +#endif diff --git a/compat/compat.h b/compat/compat.h new file mode 100644 index 00000000..7692b38a --- /dev/null +++ b/compat/compat.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2013 Stanisław Halik <sthalik@misaki.pl> + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ +#pragma once + +#if defined(_WIN32) || defined(__WIN32) +#include <windows.h> +#else +#include <stdio.h> +#include <string.h> +#include <sys/file.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <limits.h> +#include <unistd.h> +#include <sys/types.h> +#endif + +#if defined(IN_FTNOIR_COMPAT) && (defined(_WIN32) || defined(__WIN32)) +#	define COMPAT_EXPORT __declspec(dllexport) +#else +#	define COMPAT_EXPORT +#endif + +class COMPAT_EXPORT PortableLockedShm { +public: +    PortableLockedShm(const char *shmName, const char *mutexName, int mapSize); +    ~PortableLockedShm(); +    void lock(); +    void unlock(); +    void* mem; +private: +#if defined(_WIN32) || defined(__WIN32) +    HANDLE hMutex, hMapFile; +#else +    int fd, size; +    //char shm_filename[NAME_MAX]; +#endif +}; diff --git a/faceapi/ftnoir-faceapi-wrapper.exe.manifest b/faceapi/ftnoir-faceapi-wrapper.exe.manifest new file mode 100644 index 00000000..b6c98376 --- /dev/null +++ b/faceapi/ftnoir-faceapi-wrapper.exe.manifest @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +	<dependency> +		<dependentAssembly> +			<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.4053" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"> +			</assemblyIdentity> +		</dependentAssembly> +	</dependency> +	<dependency> +		<dependentAssembly> +			<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"> +			</assemblyIdentity> +		</dependentAssembly> +	</dependency> +</assembly>
\ No newline at end of file diff --git a/faceapi/ftnoir-faceapi-wrapper.rc b/faceapi/ftnoir-faceapi-wrapper.rc new file mode 100644 index 00000000..54cbb863 --- /dev/null +++ b/faceapi/ftnoir-faceapi-wrapper.rc @@ -0,0 +1,2 @@ +#include "winuser.h" +2 RT_MANIFEST ftnoir-faceapi-wrapper.exe.manifest
\ No newline at end of file diff --git a/faceapi/main.cpp b/faceapi/main.cpp index 46732cb3..64e721f4 100644 --- a/faceapi/main.cpp +++ b/faceapi/main.cpp @@ -36,8 +36,9 @@  //FaceAPI headers
  #include <sm_api.h>
 -#include "ftnoir_tracker_sm_types.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_sm_types.h"
  #include "utils.h"
 +#include <exception>
  //local headers
  #include "build_options.h"
 @@ -171,7 +172,7 @@ smCameraHandle createFirstCamera()      if (info_list.num_cameras == 0)
      {
 -        throw runtime_error("No cameras were detected");
 +        throw std::exception();
      }
      else
      {
 @@ -211,7 +212,6 @@ smCameraHandle createFirstCamera()  // The main function: setup a tracking engine and show a video window, then loop on the keyboard.
  void run()
  {
 -	char msg[100];
  	int state;
  	// Capture control-C
 @@ -377,11 +377,6 @@ void run()  		//
  		if (ftnoirConnected && (pMemData != 0)) {
 -			sprintf_s(msg, "Command: %d, \n", pMemData->command, pMemData->par_val_int);
 -			OutputDebugStringA(msg);
 -			std::cout << msg;
 -
 -			//
  			//
  			// Determine the trackers' state and send it to FaceTrackNoIR.
  			//
 diff --git a/faceapi/mutex.h b/faceapi/mutex.h index 11aabafc..a4f84705 100644 --- a/faceapi/mutex.h +++ b/faceapi/mutex.h @@ -1,6 +1,8 @@  #ifndef SM_API_TESTAPPCONSOLE_MUTEX_H
  #define SM_API_TESTAPPCONSOLE_MUTEX_H
 +#include <exception>
 +
  namespace sm
  {
      namespace faceapi
 @@ -16,7 +18,7 @@ namespace sm                  {
                      if (!InitializeCriticalSectionAndSpinCount(&_cs,0x80000400)) 
                      {
 -                        throw std::runtime_error("Failed to initialize Mutex");
 +                        throw std::exception();
                      }
                  }
                  ~Mutex()
 diff --git a/faceapi/stdafx.h b/faceapi/stdafx.h index d97c9353..1fdab0b1 100644 --- a/faceapi/stdafx.h +++ b/faceapi/stdafx.h @@ -1,8 +1,3 @@ -// stdafx.h : include file for standard system include files,
 -// or project specific include files that are used frequently, but
 -// are changed infrequently
 -//
 -
  #pragma once
  #ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
 @@ -12,10 +7,30 @@  #include <stdio.h>
  #include <tchar.h>
 -// TODO: reference additional headers your program requires here
 +#ifndef _MSC_VER
 +
 +#include <inttypes.h>
 +
 +typedef uint64_t u_int64_t;
 +typedef uint32_t u_int32_t;
 +typedef uint16_t u_int16_t;
 +typedef uint8_t u_int8_t;
 +#endif
 +
  #include <iostream>
  #include <sstream>
  #include <string>
  #include <cassert>
  #include <conio.h>
 +#include <sm_api_configure.h>
 +#ifdef SM_API
 +#   undef SM_API
 +#endif
 +#ifdef STDCALL
 +#   undef STDCALL
 +#endif
 +
 +#define SM_API(type) type __declspec(dllimport) __stdcall
 +#define STDCALL __stdcall
 +
  #include <sm_api.h>
 diff --git a/faceapi/utils.h b/faceapi/utils.h index 1fdb35b5..5d25e9a7 100644 --- a/faceapi/utils.h +++ b/faceapi/utils.h @@ -2,6 +2,8 @@  #define SM_API_TESTAPPCONSOLE_UTILS_H
  #include "lock.h"
 +#include <exception>
 +#include <iostream>
  #define THROW_ON_ERROR(x) \
  { \
 @@ -10,7 +12,8 @@      { \
          std::stringstream s; \
          s << "API error code: " << result; \
 -        throw std::runtime_error(s.str()); \
 +        std::cerr << s; \
 +        throw std::exception(); \
      } \
  }
 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 <ftnoir_tracker_ht/ht-api.h>
 +#include <QDebug>
 +
 +#if defined(__WIN32) || defined(_WIN32)
 +#   include <windows.h>
 +#endif
 +
 +#if defined(__APPLE__)
 +#   define SONAME "dylib"
 +#elif defined(_WIN32) || defined(__WIN32)
 +#   define SONAME "dll"
 +#else
 +#   define SONAME "so"
 +#endif
 +
 +#include <iostream>
 +
 +#if defined(__WIN32) || defined(_WIN32)
 +#define DIRECTINPUT_VERSION 0x0800
 +#include <dshow.h>
 +#include <dinput.h>
 +
 +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 **/
 @@ -218,15 +357,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.
  //
  void FaceTrackNoIR::updateSettings() {
 @@ -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);
 @@ -804,24 +858,32 @@ void FaceTrackNoIR::stopTracker( ) {  	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 <tchar.h>
 +#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 <QtGui/QMainWindow>
  #include <QApplication>
  #include <QFileDialog>
 @@ -34,30 +40,58 @@  #include <QWidget>
  #include <QDialog>
  #include <QUrl>
 -
 -#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 <Dshow.h>
 +#include <QList>
 +#include <QKeySequence>
 +#include <QtGui>
 +#include <QString>
 +#if !defined(_WIN32) && !defined(__WIN32)
 +#	include <qxtglobalshortcut.h>
 +#else
 +#	include <windows.h>
 +#endif
 +#include <QThread>
 +#include <QDebug>
 +#include <QElapsedTimer>
 +
 +#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<int> global_windows_key_sequences;
 +#include <dinput.h>
 +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<DynamicLibrary*> dlopen_filters;
 +    QList<DynamicLibrary*> dlopen_trackers;
 +    QList<DynamicLibrary*> 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<QString> stringList;			// List of strings, that describe the keyboard-keys
 -	QList<BYTE> keyList; 				// List of keys, with the values of the keyboard-keys
 -	QList<QString> 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<QString> 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.icoBinary files differ new file mode 100644 index 00000000..5115066c --- /dev/null +++ b/facetracknoir/facetracknoir.ico 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 @@     <rect>
      <x>0</x>
      <y>0</y>
 -    <width>901</width>
 -    <height>661</height>
 +    <width>718</width>
 +    <height>698</height>
     </rect>
    </property>
    <property name="windowTitle">
 @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 @@ -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);         <property name="currentIndex">
          <number>0</number>
         </property>
 -       <widget class="QWidget" name="rotation_tab">
 -        <attribute name="icon">
 -         <iconset resource="FaceTrackNoIR.qrc">
 -          <normaloff>:/images/rotation_DOFs.png</normaloff>:/images/rotation_DOFs.png</iconset>
 +       <widget class="QWidget" name="tab">
 +        <attribute name="title">
 +         <string>rx</string>
          </attribute>
 +        <widget class="QFunctionConfigurator" name="rxconfig">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>0</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="rx_altp">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>166</width>
 +           <height>21</height>
 +          </rect>
 +         </property>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="rxconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>0</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +       </widget>
 +       <widget class="QWidget" name="tab2">
          <attribute name="title">
 -         <string>Rotations</string>
 +         <string>ry</string>
          </attribute>
 -        <widget class="QWidget" name="verticalLayoutWidget">
 +        <widget class="QFunctionConfigurator" name="ryconfig">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>255</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="ry_altp">
           <property name="geometry">
            <rect>
 -           <x>10</x>
 -           <y>10</y>
 -           <width>794</width>
 -           <height>548</height>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>199</width>
 +           <height>21</height>
            </rect>
           </property>
 -         <layout class="QGridLayout" name="gridLayout">
 -          <item row="0" column="1">
 -           <widget class="QFunctionConfigurator" name="qFunctionPitch">
 -            <property name="sizePolicy">
 -             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
 -              <horstretch>0</horstretch>
 -              <verstretch>0</verstretch>
 -             </sizepolicy>
 -            </property>
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>500</height>
 -             </size>
 -            </property>
 -            <property name="maxOutputEGU" stdset="0">
 -             <number>180</number>
 -            </property>
 -            <property name="pixPerEGU_Output" stdset="0">
 -             <number>1</number>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>0</red>
 -              <green>255</green>
 -              <blue>255</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Input Pitch Up (degr.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Pitch Up (degr.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="0" column="2">
 -           <widget class="QFunctionConfigurator" name="qFunctionRoll">
 -            <property name="sizePolicy">
 -             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
 -              <horstretch>0</horstretch>
 -              <verstretch>0</verstretch>
 -             </sizepolicy>
 -            </property>
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>500</height>
 -             </size>
 -            </property>
 -            <property name="pixPerEGU_Output" stdset="0">
 -             <number>1</number>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>0</red>
 -              <green>255</green>
 -              <blue>0</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Input Roll (degr.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Roll (degr.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="0" column="0">
 -           <widget class="QFunctionConfigurator" name="qFunctionYaw">
 -            <property name="sizePolicy">
 -             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
 -              <horstretch>0</horstretch>
 -              <verstretch>0</verstretch>
 -             </sizepolicy>
 -            </property>
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>400</width>
 -              <height>500</height>
 -             </size>
 -            </property>
 -            <property name="pixPerEGU_Output" stdset="0">
 -             <number>1</number>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>255</red>
 -              <green>170</green>
 -              <blue>0</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Input Yaw (degr.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Yaw (degr.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="1" column="1">
 -           <widget class="QFunctionConfigurator" name="qFunctionPitchDown">
 -            <property name="sizePolicy">
 -             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
 -              <horstretch>0</horstretch>
 -              <verstretch>0</verstretch>
 -             </sizepolicy>
 -            </property>
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>500</height>
 -             </size>
 -            </property>
 -            <property name="maxOutputEGU" stdset="0">
 -             <number>90</number>
 -            </property>
 -            <property name="pixPerEGU_Output" stdset="0">
 -             <number>2</number>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>0</red>
 -              <green>255</green>
 -              <blue>255</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Input Pitch Down (degr.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Pitch Down (degr.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="1" column="0">
 -           <widget class="QLabel" name="label_9">
 -            <property name="maximumSize">
 -             <size>
 -              <width>16777215</width>
 -              <height>25</height>
 -             </size>
 -            </property>
 -            <property name="text">
 -             <string>Left-click the graph to place a new point, right-click a point to remove. Left-click and drag to move a point.</string>
 -            </property>
 -            <property name="wordWrap">
 -             <bool>true</bool>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="1" column="2">
 -           <widget class="QWidget" name="widget_3" native="true">
 -            <property name="minimumSize">
 -             <size>
 -              <width>170</width>
 -              <height>140</height>
 -             </size>
 -            </property>
 -            <property name="styleSheet">
 -             <string notr="true">image: url(:/images/rotation_DOFs.png);</string>
 -            </property>
 -           </widget>
 -          </item>
 -         </layout>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="ryconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>255</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
          </widget>
         </widget>
 -       <widget class="QWidget" name="translation_tab">
 -        <attribute name="icon">
 -         <iconset resource="FaceTrackNoIR.qrc">
 -          <normaloff>:/images/translation_DOFs.png</normaloff>:/images/translation_DOFs.png</iconset>
 +       <widget class="QWidget" name="tab3">
 +        <attribute name="title">
 +         <string>rz</string>
          </attribute>
 +        <widget class="QFunctionConfigurator" name="rzconfig">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>0</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="rz_altp">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>271</width>
 +           <height>21</height>
 +          </rect>
 +         </property>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="rzconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>240</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>180</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>0</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +       </widget>
 +       <widget class="QWidget" name="tab4">
          <attribute name="title">
 -         <string>Translations</string>
 +         <string>tx</string>
          </attribute>
 -        <widget class="QWidget" name="verticalLayoutWidget_2">
 +        <widget class="QFunctionConfigurator" name="txconfig">
           <property name="geometry">
            <rect>
 -           <x>30</x>
 -           <y>10</y>
 -           <width>794</width>
 -           <height>390</height>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>260</height>
            </rect>
           </property>
 -         <layout class="QGridLayout" name="gridLayout_3">
 -          <item row="0" column="0">
 -           <widget class="QFunctionConfigurator" name="qFunctionX">
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>255</red>
 -              <green>255</green>
 -              <blue>0</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Left/Right Input X (cm.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output X (cm.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="0" column="1">
 -           <widget class="QFunctionConfigurator" name="qFunctionY">
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>85</red>
 -              <green>0</green>
 -              <blue>255</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Up/Down Input Y (cm.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Y (cm.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="0" column="2">
 -           <widget class="QFunctionConfigurator" name="qFunctionZ">
 -            <property name="minimumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="maximumSize">
 -             <size>
 -              <width>260</width>
 -              <height>240</height>
 -             </size>
 -            </property>
 -            <property name="colorBezier">
 -             <color>
 -              <red>255</red>
 -              <green>0</green>
 -              <blue>0</blue>
 -             </color>
 -            </property>
 -            <property name="colorBackground">
 -             <color>
 -              <red>192</red>
 -              <green>192</green>
 -              <blue>192</blue>
 -             </color>
 -            </property>
 -            <property name="stringInputEGU" stdset="0">
 -             <string>Forward/Backward Input Z (cm.)</string>
 -            </property>
 -            <property name="stringOutputEGU" stdset="0">
 -             <string>Output Z (cm.)</string>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="1" column="0">
 -           <widget class="QLabel" name="label_10">
 -            <property name="maximumSize">
 -             <size>
 -              <width>16777215</width>
 -              <height>25</height>
 -             </size>
 -            </property>
 -            <property name="text">
 -             <string>Left-click the graph to place a new point, right-click a point to remove. Left-click and drag to move a point.</string>
 -            </property>
 -            <property name="wordWrap">
 -             <bool>true</bool>
 -            </property>
 -           </widget>
 -          </item>
 -          <item row="1" column="2">
 -           <widget class="QWidget" name="widget_2" native="true">
 -            <property name="minimumSize">
 -             <size>
 -              <width>170</width>
 -              <height>140</height>
 -             </size>
 -            </property>
 -            <property name="styleSheet">
 -             <string notr="true">image: url(:/images/translation_DOFs.png);</string>
 -            </property>
 -           </widget>
 -          </item>
 -         </layout>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>0</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="tx_altp">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>228</width>
 +           <height>21</height>
 +          </rect>
 +         </property>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="txconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>260</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>0</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +       </widget>
 +       <widget class="QWidget" name="tab5">
 +        <attribute name="title">
 +         <string>ty</string>
 +        </attribute>
 +        <widget class="QFunctionConfigurator" name="tyconfig">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>260</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>255</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="ty_altp">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>229</width>
 +           <height>21</height>
 +          </rect>
 +         </property>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="tyconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>260</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>255</red>
 +           <green>255</green>
 +           <blue>0</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +       </widget>
 +       <widget class="QWidget" name="tab6">
 +        <attribute name="title">
 +         <string>tz</string>
 +        </attribute>
 +        <widget class="QFunctionConfigurator" name="tzconfig">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>0</y>
 +           <width>595</width>
 +           <height>260</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>255</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
 +        </widget>
 +        <widget class="QCheckBox" name="tz_altp">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>280</y>
 +           <width>263</width>
 +           <height>21</height>
 +          </rect>
 +         </property>
 +         <property name="text">
 +          <string>Use alternative</string>
 +         </property>
 +        </widget>
 +        <widget class="QFunctionConfigurator" name="tzconfig_alt">
 +         <property name="geometry">
 +          <rect>
 +           <x>0</x>
 +           <y>340</y>
 +           <width>595</width>
 +           <height>260</height>
 +          </rect>
 +         </property>
 +         <property name="maxInputEGU" stdset="0">
 +          <number>60</number>
 +         </property>
 +         <property name="maxOutputEGU" stdset="0">
 +          <number>200</number>
 +         </property>
 +         <property name="pixPerEGU_Input" stdset="0">
 +          <number>9</number>
 +         </property>
 +         <property name="pixPerEGU_Output" stdset="0">
 +          <number>1</number>
 +         </property>
 +         <property name="colorBezier">
 +          <color>
 +           <red>0</red>
 +           <green>255</green>
 +           <blue>255</blue>
 +          </color>
 +         </property>
 +         <property name="colorBackground">
 +          <color>
 +           <red>200</red>
 +           <green>200</green>
 +           <blue>200</blue>
 +          </color>
 +         </property>
          </widget>
         </widget>
        </widget>
 @@ -499,19 +639,6 @@ color: rgb(255, 255, 255);     </item>
     <item>
      <layout class="QGridLayout" name="gridLayout_2">
 -     <item row="0" column="1">
 -      <spacer name="horizontalSpacer_2">
 -       <property name="orientation">
 -        <enum>Qt::Horizontal</enum>
 -       </property>
 -       <property name="sizeHint" stdset="0">
 -        <size>
 -         <width>40</width>
 -         <height>20</height>
 -        </size>
 -       </property>
 -      </spacer>
 -     </item>
       <item row="0" column="2">
        <layout class="QHBoxLayout" name="horizontalLayout_2">
         <property name="sizeConstraint">
 @@ -527,7 +654,7 @@ color: rgb(255, 255, 255);           </property>
           <property name="minimumSize">
            <size>
 -           <width>52</width>
 +           <width>58</width>
             <height>0</height>
            </size>
           </property>
 @@ -552,7 +679,7 @@ color: rgb(255, 255, 255);           </property>
           <property name="minimumSize">
            <size>
 -           <width>52</width>
 +           <width>58</width>
             <height>0</height>
            </size>
           </property>
 @@ -569,17 +696,14 @@ color: rgb(255, 255, 255);         </item>
        </layout>
       </item>
 -     <item row="0" column="3">
 -      <spacer name="horizontalSpacer">
 +     <item row="0" column="1">
 +      <spacer name="horizontalSpacer_2">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
 -       <property name="sizeType">
 -        <enum>QSizePolicy::Fixed</enum>
 -       </property>
         <property name="sizeHint" stdset="0">
          <size>
 -         <width>10</width>
 +         <width>40</width>
           <height>20</height>
          </size>
         </property>
 @@ -596,9 +720,7 @@ color: rgb(255, 255, 255);     <header>qfunctionconfigurator.h</header>
    </customwidget>
   </customwidgets>
 - <resources>
 -  <include location="FaceTrackNoIR.qrc"/>
 - </resources>
 + <resources/>
   <connections/>
   <slots>
    <slot>startEngineClicked()</slot>
 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 @@      <x>0</x>
      <y>0</y>
      <width>541</width>
 -    <height>127</height>
 +    <height>131</height>
     </rect>
    </property>
    <property name="windowTitle">
 @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 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 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 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 @@     <rect>
      <x>0</x>
      <y>0</y>
 -    <width>687</width>
 +    <width>591</width>
      <height>438</height>
     </rect>
    </property>
 @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 @@ -28,58 +28,8 @@      <layout class="QHBoxLayout" name="horizontalLayout_3">
       <item>
        <layout class="QGridLayout" name="gridLayout">
 -       <item row="5" column="8">
 -        <widget class="QLabel" name="label_3">
 -         <property name="text">
 -          <string>Disables:</string>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="3" column="8">
 -        <widget class="QLabel" name="label_5">
 -         <property name="text">
 -          <string>When OFF:</string>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="1" column="0">
 -        <widget class="QLabel" name="textLabel2">
 -         <property name="sizePolicy">
 -          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
 -           <horstretch>0</horstretch>
 -           <verstretch>0</verstretch>
 -          </sizepolicy>
 -         </property>
 -         <property name="text">
 -          <string>Center</string>
 -         </property>
 -         <property name="wordWrap">
 -          <bool>false</bool>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="5" column="0">
 -        <widget class="QLabel" name="label_2">
 -         <property name="text">
 -          <string>Axis Inhibitor</string>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="1" column="1">
 -        <widget class="QCheckBox" name="chkCenterShift">
 -         <property name="maximumSize">
 -          <size>
 -           <width>50</width>
 -           <height>16777215</height>
 -          </size>
 -         </property>
 -         <property name="text">
 -          <string>Shift</string>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="3" column="1">
 -        <widget class="QCheckBox" name="chkStartStopShift">
 +       <item row="5" column="3">
 +        <widget class="QCheckBox" name="chkInhibitAlt">
           <property name="maximumSize">
            <size>
             <width>50</width>
 @@ -87,12 +37,12 @@            </size>
           </property>
           <property name="text">
 -          <string>Shift</string>
 +          <string>Alt</string>
           </property>
          </widget>
         </item>
 -       <item row="5" column="1">
 -        <widget class="QCheckBox" name="chkInhibitShift">
 +       <item row="3" column="3">
 +        <widget class="QCheckBox" name="chkStartStopAlt">
           <property name="maximumSize">
            <size>
             <width>50</width>
 @@ -100,12 +50,12 @@            </size>
           </property>
           <property name="text">
 -          <string>Shift</string>
 +          <string>Alt</string>
           </property>
          </widget>
         </item>
 -       <item row="1" column="2">
 -        <widget class="QCheckBox" name="chkCenterCtrl">
 +       <item row="5" column="2">
 +        <widget class="QCheckBox" name="chkInhibitCtrl">
           <property name="maximumSize">
            <size>
             <width>50</width>
 @@ -130,8 +80,8 @@           </property>
          </widget>
         </item>
 -       <item row="5" column="2">
 -        <widget class="QCheckBox" name="chkInhibitCtrl">
 +       <item row="1" column="2">
 +        <widget class="QCheckBox" name="chkCenterCtrl">
           <property name="maximumSize">
            <size>
             <width>50</width>
 @@ -143,8 +93,8 @@           </property>
          </widget>
         </item>
 -       <item row="3" column="3">
 -        <widget class="QCheckBox" name="chkStartStopAlt">
 +       <item row="5" column="1">
 +        <widget class="QCheckBox" name="chkInhibitShift">
           <property name="maximumSize">
            <size>
             <width>50</width>
 @@ -152,21 +102,18 @@            </size>
           </property>
           <property name="text">
 -          <string>Alt</string>
 +          <string>Shift</string>
           </property>
          </widget>
         </item>
 -       <item row="5" column="3">
 -        <widget class="QCheckBox" name="chkInhibitAlt">
 -         <property name="maximumSize">
 +       <item row="5" column="4">
 +        <widget class="QComboBox" name="cbxInhibitKey">
 +         <property name="minimumSize">
            <size>
 -           <width>50</width>
 -           <height>16777215</height>
 +           <width>90</width>
 +           <height>0</height>
            </size>
           </property>
 -         <property name="text">
 -          <string>Alt</string>
 -         </property>
          </widget>
         </item>
         <item row="1" column="4">
 @@ -185,27 +132,7 @@           </property>
          </widget>
         </item>
 -       <item row="3" column="4">
 -        <widget class="QComboBox" name="cbxStartStopKey">
 -         <property name="minimumSize">
 -          <size>
 -           <width>90</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="5" column="4">
 -        <widget class="QComboBox" name="cbxInhibitKey">
 -         <property name="minimumSize">
 -          <size>
 -           <width>90</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="5" column="9">
 +       <item row="5" column="6">
          <widget class="QGroupBox" name="groupBox">
           <property name="minimumSize">
            <size>
 @@ -278,7 +205,7 @@           </widget>
          </widget>
         </item>
 -       <item row="3" column="9">
 +       <item row="3" column="6">
          <widget class="QGroupBox" name="groupBox_2">
           <property name="minimumSize">
            <size>
 @@ -330,7 +257,7 @@           </property>
          </widget>
         </item>
 -       <item row="5" column="10">
 +       <item row="5" column="7">
          <widget class="QGroupBox" name="groupBox_3">
           <property name="styleSheet">
            <string notr="true">color: rgb(0, 0, 0);</string>
 @@ -397,48 +324,6 @@           </widget>
          </widget>
         </item>
 -       <item row="3" column="10">
 -        <widget class="QGroupBox" name="groupBox_4">
 -         <property name="minimumSize">
 -          <size>
 -           <width>100</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -         <property name="styleSheet">
 -          <string notr="true">color: rgb(0, 0, 0);</string>
 -         </property>
 -         <property name="title">
 -          <string>Engine tracker</string>
 -         </property>
 -         <widget class="QRadioButton" name="radioSetEngineStop">
 -          <property name="geometry">
 -           <rect>
 -            <x>10</x>
 -            <y>20</y>
 -            <width>81</width>
 -            <height>17</height>
 -           </rect>
 -          </property>
 -          <property name="text">
 -           <string>Stop Engine</string>
 -          </property>
 -         </widget>
 -         <widget class="QRadioButton" name="radioSetKeepTracking">
 -          <property name="geometry">
 -           <rect>
 -            <x>10</x>
 -            <y>40</y>
 -            <width>91</width>
 -            <height>17</height>
 -           </rect>
 -          </property>
 -          <property name="text">
 -           <string>Keep tracking</string>
 -          </property>
 -         </widget>
 -        </widget>
 -       </item>
         <item row="2" column="0">
          <widget class="QLabel" name="textLabel2_2">
           <property name="sizePolicy">
 @@ -542,75 +427,15 @@           </property>
          </widget>
         </item>
 -       <item row="0" column="6">
 -        <widget class="QLabel" name="textLabel2_4">
 -         <property name="sizePolicy">
 -          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
 -           <horstretch>0</horstretch>
 -           <verstretch>0</verstretch>
 -          </sizepolicy>
 -         </property>
 -         <property name="text">
 -          <string>Mouse</string>
 -         </property>
 -         <property name="alignment">
 -          <set>Qt::AlignCenter</set>
 -         </property>
 -         <property name="wordWrap">
 -          <bool>false</bool>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="1" column="6">
 -        <widget class="QComboBox" name="cbxCenterMouseKey">
 -         <property name="minimumSize">
 -          <size>
 -           <width>90</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -         <property name="toolTip">
 -          <string>Select Number</string>
 -         </property>
 -         <property name="insertPolicy">
 -          <enum>QComboBox::InsertAlphabetically</enum>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="2" column="6">
 -        <widget class="QComboBox" name="cbxGameZeroMouseKey">
 -         <property name="minimumSize">
 -          <size>
 -           <width>90</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -         <property name="toolTip">
 -          <string>Select Number</string>
 -         </property>
 -         <property name="insertPolicy">
 -          <enum>QComboBox::InsertAlphabetically</enum>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="3" column="6">
 -        <widget class="QComboBox" name="cbxStartStopMouseKey">
 -         <property name="minimumSize">
 -          <size>
 -           <width>90</width>
 -           <height>0</height>
 -          </size>
 -         </property>
 -         <property name="toolTip">
 -          <string>Select Number</string>
 -         </property>
 -         <property name="insertPolicy">
 -          <enum>QComboBox::InsertAlphabetically</enum>
 +       <item row="4" column="0">
 +        <widget class="Line" name="line_12">
 +         <property name="orientation">
 +          <enum>Qt::Vertical</enum>
           </property>
          </widget>
         </item>
 -       <item row="5" column="6">
 -        <widget class="QComboBox" name="cbxInhibitMouseKey">
 +       <item row="3" column="4">
 +        <widget class="QComboBox" name="cbxStartStopKey">
           <property name="minimumSize">
            <size>
             <width>90</width>
 @@ -619,79 +444,66 @@           </property>
          </widget>
         </item>
 -       <item row="1" column="5">
 -        <widget class="Line" name="line_2">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 -         </property>
 -        </widget>
 -       </item>
 -       <item row="2" column="5">
 -        <widget class="Line" name="line_3">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +       <item row="5" column="5">
 +        <widget class="QLabel" name="label_3">
 +         <property name="text">
 +          <string>Disables:</string>
           </property>
          </widget>
         </item>
         <item row="3" column="5">
 -        <widget class="Line" name="line_6">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +        <widget class="QLabel" name="label_5">
 +         <property name="text">
 +          <string>When OFF:</string>
           </property>
          </widget>
         </item>
 -       <item row="5" column="5">
 -        <widget class="Line" name="line_7">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +       <item row="1" column="0">
 +        <widget class="QLabel" name="textLabel2">
 +         <property name="sizePolicy">
 +          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
 +           <horstretch>0</horstretch>
 +           <verstretch>0</verstretch>
 +          </sizepolicy>
           </property>
 -        </widget>
 -       </item>
 -       <item row="1" column="7">
 -        <widget class="Line" name="line_9">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +         <property name="text">
 +          <string>Center</string>
           </property>
 -        </widget>
 -       </item>
 -       <item row="3" column="7">
 -        <widget class="Line" name="line_8">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +         <property name="wordWrap">
 +          <bool>false</bool>
           </property>
          </widget>
         </item>
 -       <item row="2" column="7">
 -        <widget class="Line" name="line_10">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +       <item row="5" column="0">
 +        <widget class="QLabel" name="label_2">
 +         <property name="text">
 +          <string>Axis Inhibitor</string>
           </property>
          </widget>
         </item>
 -       <item row="5" column="7">
 -        <widget class="Line" name="line_11">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +       <item row="1" column="1">
 +        <widget class="QCheckBox" name="chkCenterShift">
 +         <property name="maximumSize">
 +          <size>
 +           <width>50</width>
 +           <height>16777215</height>
 +          </size>
           </property>
 -        </widget>
 -       </item>
 -       <item row="4" column="0">
 -        <widget class="Line" name="line_12">
 -         <property name="orientation">
 -          <enum>Qt::Vertical</enum>
 +         <property name="text">
 +          <string>Shift</string>
           </property>
          </widget>
         </item>
 -       <item row="1" column="9">
 -        <widget class="QCheckBox" name="chkDisableBeep">
 +       <item row="3" column="1">
 +        <widget class="QCheckBox" name="chkStartStopShift">
           <property name="maximumSize">
            <size>
 -           <width>85</width>
 +           <width>50</width>
             <height>16777215</height>
            </size>
           </property>
           <property name="text">
 -          <string>Disable Beep</string>
 +          <string>Shift</string>
           </property>
          </widget>
         </item>
 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 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 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 <dlfcn.h> +#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 <QWidget> +#include <QDebug> +#include <QString> +#include <QLibrary> +#include <QFrame> +#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 <windows.h> +#include <strmif.h> +#include <dshow.h> +QList<int> global_windows_key_sequences = +    QList<int>() +    << 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<QString> global_key_sequences = +    QList<QString>() +    << "" +    << "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.icoBinary files differ new file mode 100644 index 00000000..5115066c --- /dev/null +++ b/facetracknoir/images/facetracknoir.ico 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 <QtGui/QApplication>
  #include <QDesktopWidget>
  #include <QDebug>
  #include <QList>
 -int main(int argc, char *argv[])
 +#if defined(_WIN32)
 +#include <windows.h>
 +#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;	
 @@ -877,35 +346,16 @@ bool Tracker::handleGameCommand ( int command ) {  }
  //
 -// Add the new Raw value to the QList.
 -// Remove the last item(s), depending on the set maximum list-items.
 -//
 -void Tracker::addRaw2List ( QList<float> *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;
  }
  //
 @@ -922,30 +372,9 @@ void Tracker::getOutputHeadPose( THeadPoseData *data ) {  }
  //
 -// Get the Smoothed value from the QList.
 -//
 -float Tracker::getSmoothFromList ( QList<float> *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 <QThread>
  #include <QMessageBox>
  #include <QLineEdit>
 -#include <QThread>
  #include <QPoint>
  #include <QWaitCondition>
  #include <QList>
  #include <QPainterPath>
  #include <QDebug>
 -
 -#define DIRECTINPUT_VERSION 0x0800
 -#include <Dinput.h>
 -
 -#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 <QMutex>
 +#include "global-settings.h"
 +
 +//#define DIRECTINPUT_VERSION 0x0800
 +//#include <Dinput.h>
 +#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 <qfunctionconfigurator/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 "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<float> 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<float> *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<float> *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.icoBinary files differ new file mode 100644 index 00000000..af36ec30 --- /dev/null +++ b/facetracknoir/uielements/facetracknoir.ico diff --git a/facetracknoir/uielements/setupfacetracknoir.jpg b/facetracknoir/uielements/setupfacetracknoir.jpgBinary files differ new file mode 100644 index 00000000..8778c6d5 --- /dev/null +++ b/facetracknoir/uielements/setupfacetracknoir.jpg diff --git a/ftnoir_filter_accela/default-points.cpp b/ftnoir_filter_accela/default-points.cpp new file mode 100644 index 00000000..2cebff6c --- /dev/null +++ b/ftnoir_filter_accela/default-points.cpp @@ -0,0 +1,38 @@ +#include <QList> +#include <QPointF> + +static QList<QPointF> EmptyList() { +	return QList<QPointF>(); +} + +extern const QList<QPointF> defScaleRotation, defScaleTranslation; + +const QList<QPointF> defScaleRotation = +	EmptyList() +    << QPointF(0, 0) +    << QPointF(0.308900523560209, 0.0666666666666667) +    << QPointF(0.565445026178011, 0.226666666666667) +    << QPointF(0.769633507853403, 0.506666666666667) +    << QPointF(0.994764397905759, 1) +    << QPointF(1.23560209424084, 1.61333333333333) +    << QPointF(1.47643979057592, 2.37333333333333) +    << QPointF(1.66492146596859, 3.12) +    << QPointF(1.80628272251309, 3.92) +    << QPointF(1.91623036649215, 4.70666666666667) +    << QPointF(2.00523560209424, 5.44) +    << QPointF(2.07329842931937, 6) +; + +const QList<QPointF> defScaleTranslation = +	EmptyList() +    << QPointF(0, 0) +    << QPointF(0.282722513089005, 0.08) +    << QPointF(0.492146596858639, 0.306666666666667) +    << QPointF(0.764397905759162, 0.84) +    << QPointF(1.00523560209424, 1.62666666666667) +    << QPointF(1.17277486910995, 2.78666666666667) +    << QPointF(1.25130890052356, 3.6) +    << QPointF(1.31937172774869, 4.29333333333333) +    << QPointF(1.38219895287958, 4.90666666666667) +    << QPointF(1.43455497382199, 5.65333333333333) +; diff --git a/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui b/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui new file mode 100644 index 00000000..9be0356b --- /dev/null +++ b/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui @@ -0,0 +1,451 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AccelaUICFilterControls</class> + <widget class="QWidget" name="AccelaUICFilterControls"> +  <property name="windowModality"> +   <enum>Qt::ApplicationModal</enum> +  </property> +  <property name="geometry"> +   <rect> +    <x>0</x> +    <y>0</y> +    <width>880</width> +    <height>673</height> +   </rect> +  </property> +  <property name="windowTitle"> +   <string>Filter settings</string> +  </property> +  <property name="windowIcon"> +   <iconset> +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset> +  </property> +  <property name="layoutDirection"> +   <enum>Qt::LeftToRight</enum> +  </property> +  <property name="autoFillBackground"> +   <bool>false</bool> +  </property> +  <property name="styleSheet"> +   <string notr="true"/> +  </property> +  <layout class="QVBoxLayout" name="_vertical_layout"> +   <item> +    <widget class="QTabWidget" name="tabWidget"> +     <property name="enabled"> +      <bool>true</bool> +     </property> +     <property name="sizePolicy"> +      <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> +       <horstretch>0</horstretch> +       <verstretch>0</verstretch> +      </sizepolicy> +     </property> +     <property name="minimumSize"> +      <size> +       <width>850</width> +       <height>574</height> +      </size> +     </property> +     <property name="maximumSize"> +      <size> +       <width>300</width> +       <height>574</height> +      </size> +     </property> +     <property name="currentIndex"> +      <number>0</number> +     </property> +     <widget class="QWidget" name="tab"> +      <attribute name="title"> +       <string>Rotation</string> +      </attribute> +      <widget class="QFunctionConfigurator" name="scalingConfig" native="true"> +       <property name="geometry"> +        <rect> +         <x>20</x> +         <y>20</y> +         <width>819</width> +         <height>510</height> +        </rect> +       </property> +       <property name="maxInputEGU" stdset="0"> +        <number>4</number> +       </property> +       <property name="maxOutputEGU" stdset="0"> +        <number>6</number> +       </property> +       <property name="pixPerEGU_Input" stdset="0"> +        <number>191</number> +       </property> +       <property name="pixPerEGU_Output" stdset="0"> +        <number>75</number> +       </property> +       <property name="gridDistEGU_Input" stdset="0"> +        <number>1</number> +       </property> +       <property name="gridDistEGU_Output" stdset="0"> +        <number>1</number> +       </property> +       <property name="colorBezier" stdset="0"> +        <color> +         <red>255</red> +         <green>170</green> +         <blue>0</blue> +        </color> +       </property> +       <property name="colorBackground" stdset="0"> +        <color> +         <red>192</red> +         <green>192</green> +         <blue>192</blue> +        </color> +       </property> +       <property name="stringInputEGU" stdset="0"> +        <string>Input</string> +       </property> +       <property name="stringOutputEGU" stdset="0"> +        <string>Output</string> +       </property> +       <property name="stringCaption" stdset="0"> +        <string>Translation</string> +       </property> +      </widget> +     </widget> +     <widget class="QWidget" name="tab_2"> +      <attribute name="title"> +       <string>Translation</string> +      </attribute> +      <widget class="QFunctionConfigurator" name="translationScalingConfig" native="true"> +       <property name="geometry"> +        <rect> +         <x>20</x> +         <y>20</y> +         <width>819</width> +         <height>510</height> +        </rect> +       </property> +       <property name="maxInputEGU" stdset="0"> +        <number>4</number> +       </property> +       <property name="maxOutputEGU" stdset="0"> +        <number>6</number> +       </property> +       <property name="pixPerEGU_Input" stdset="0"> +        <number>191</number> +       </property> +       <property name="pixPerEGU_Output" stdset="0"> +        <number>75</number> +       </property> +       <property name="gridDistEGU_Input" stdset="0"> +        <number>1</number> +       </property> +       <property name="gridDistEGU_Output" stdset="0"> +        <number>1</number> +       </property> +       <property name="colorBezier" stdset="0"> +        <color> +         <red>85</red> +         <green>255</green> +         <blue>0</blue> +        </color> +       </property> +       <property name="colorBackground" stdset="0"> +        <color> +         <red>192</red> +         <green>192</green> +         <blue>192</blue> +        </color> +       </property> +       <property name="stringInputEGU" stdset="0"> +        <string>Input</string> +       </property> +       <property name="stringOutputEGU" stdset="0"> +        <string>Output</string> +       </property> +      </widget> +     </widget> +    </widget> +   </item> +   <item> +    <layout class="QHBoxLayout" name="horizontalLayout_2"> +     <item> +      <widget class="QLabel" name="lblSensYaw_4"> +       <property name="minimumSize"> +        <size> +         <width>25</width> +         <height>0</height> +        </size> +       </property> +       <property name="maximumSize"> +        <size> +         <width>150</width> +         <height>16777215</height> +        </size> +       </property> +       <property name="styleSheet"> +        <string notr="true">color:#0; +background:none;</string> +       </property> +       <property name="text"> +        <string>Reduction factor:</string> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QSlider" name="slideReduction"> +       <property name="minimumSize"> +        <size> +         <width>50</width> +         <height>15</height> +        </size> +       </property> +       <property name="minimum"> +        <number>1</number> +       </property> +       <property name="maximum"> +        <number>100</number> +       </property> +       <property name="pageStep"> +        <number>5</number> +       </property> +       <property name="value"> +        <number>100</number> +       </property> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="tickPosition"> +        <enum>QSlider::NoTicks</enum> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QSpinBox" name="spinReduction"> +       <property name="minimumSize"> +        <size> +         <width>35</width> +         <height>22</height> +        </size> +       </property> +       <property name="styleSheet"> +        <string notr="true">background:none;</string> +       </property> +       <property name="readOnly"> +        <bool>false</bool> +       </property> +       <property name="minimum"> +        <number>1</number> +       </property> +       <property name="maximum"> +        <number>100</number> +       </property> +       <property name="value"> +        <number>100</number> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QLabel" name="lblSensYaw_5"> +       <property name="minimumSize"> +        <size> +         <width>25</width> +         <height>0</height> +        </size> +       </property> +       <property name="maximumSize"> +        <size> +         <width>150</width> +         <height>16777215</height> +        </size> +       </property> +       <property name="styleSheet"> +        <string notr="true">color:#0; +background:none;</string> +       </property> +       <property name="text"> +        <string>Zoom slowness:</string> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QSlider" name="slideZoom"> +       <property name="minimumSize"> +        <size> +         <width>50</width> +         <height>15</height> +        </size> +       </property> +       <property name="minimum"> +        <number>0</number> +       </property> +       <property name="maximum"> +        <number>200</number> +       </property> +       <property name="pageStep"> +        <number>1</number> +       </property> +       <property name="value"> +        <number>100</number> +       </property> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="tickPosition"> +        <enum>QSlider::NoTicks</enum> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QSpinBox" name="spinZoom"> +       <property name="minimumSize"> +        <size> +         <width>35</width> +         <height>22</height> +        </size> +       </property> +       <property name="styleSheet"> +        <string notr="true">background:none;</string> +       </property> +       <property name="readOnly"> +        <bool>false</bool> +       </property> +       <property name="minimum"> +        <number>0</number> +       </property> +       <property name="maximum"> +        <number>200</number> +       </property> +       <property name="value"> +        <number>100</number> +       </property> +      </widget> +     </item> +     <item> +      <spacer name="horizontalSpacer"> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="sizeHint" stdset="0"> +        <size> +         <width>40</width> +         <height>20</height> +        </size> +       </property> +      </spacer> +     </item> +    </layout> +   </item> +   <item> +    <layout class="QHBoxLayout" name="horizontalLayout"> +     <item> +      <spacer name="spacer"> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="sizeHint" stdset="0"> +        <size> +         <width>40</width> +         <height>20</height> +        </size> +       </property> +      </spacer> +     </item> +     <item> +      <widget class="QPushButton" name="btnOK"> +       <property name="text"> +        <string>OK</string> +       </property> +      </widget> +     </item> +     <item> +      <widget class="QPushButton" name="btnCancel"> +       <property name="text"> +        <string>Cancel</string> +       </property> +      </widget> +     </item> +    </layout> +   </item> +  </layout> + </widget> + <customwidgets> +  <customwidget> +   <class>QFunctionConfigurator</class> +   <extends>QWidget</extends> +   <header>qfunctionconfigurator/qfunctionconfigurator.h</header> +  </customwidget> + </customwidgets> + <resources/> + <connections> +  <connection> +   <sender>slideReduction</sender> +   <signal>valueChanged(int)</signal> +   <receiver>spinReduction</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>219</x> +     <y>620</y> +    </hint> +    <hint type="destinationlabel"> +     <x>310</x> +     <y>622</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>spinReduction</sender> +   <signal>valueChanged(int)</signal> +   <receiver>slideReduction</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>315</x> +     <y>613</y> +    </hint> +    <hint type="destinationlabel"> +     <x>170</x> +     <y>621</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>slideZoom</sender> +   <signal>valueChanged(int)</signal> +   <receiver>spinZoom</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>547</x> +     <y>602</y> +    </hint> +    <hint type="destinationlabel"> +     <x>667</x> +     <y>602</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>spinZoom</sender> +   <signal>valueChanged(int)</signal> +   <receiver>slideZoom</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>663</x> +     <y>602</y> +    </hint> +    <hint type="destinationlabel"> +     <x>537</x> +     <y>602</y> +    </hint> +   </hints> +  </connection> + </connections> + <slots> +  <slot>startEngineClicked()</slot> +  <slot>stopEngineClicked()</slot> +  <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index 3e4c3bf6..cb9fb0f5 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -10,11 +10,15 @@  					    Additional changes: I have added two parameters to the constructor of FunctionConfig and
  						renamed 3 member-functions (getFilterFullName is now called getFullName).
  */
 -#include "ftnoir_filter_Accela.h"
 +#include "ftnoir_filter_accela/ftnoir_filter_accela.h"
  #include "math.h"
  #include <QDebug>
 -#include <windows.h>
  #include <float.h>
 +#include "facetracknoir/global-settings.h"
 +
 +#if !defined(_WIN32) && !defined(__WIN32)
 +#   define _isnan isnan
 +#endif
  FTNoIR_Filter::FTNoIR_Filter() :
  	functionConfig("Accela-Scaling-Rotation", 4, 6),
 @@ -32,8 +36,6 @@ FTNoIR_Filter::~FTNoIR_Filter()  void FTNoIR_Filter::Initialize()
  {
 -	loadSettings();
 -	return;
  }
  void FTNoIR_Filter::loadSettings() {
 @@ -45,24 +47,29 @@ void FTNoIR_Filter::loadSettings() {  	QSettings iniFile( currentFile, QSettings::IniFormat );		// Application settings (in INI-file)
  	defPoints.clear();
 -	for (int i = 0; i < NUM_OF(defScaleRotation); i++) {		// Get the default points (hardcoded!)
 +    for (int i = 0; i < defScaleRotation.size(); i++) {		// Get the default points (hardcoded!)
  		defPoints.append(defScaleRotation[i]);
  	}
  	functionConfig.loadSettings(iniFile, defPoints);
  	defPoints.clear();
 -	for (int i = 0; i < NUM_OF(defScaleTranslation); i++) {		// Get the default points (hardcoded!)
 +    for (int i = 0; i < defScaleTranslation.size(); i++) {		// Get the default points (hardcoded!)
  		defPoints.append(defScaleTranslation[i]);
  	}
  	translationFunctionConfig.loadSettings(iniFile, defPoints);
  	iniFile.beginGroup ( "Accela" );
  	kMagicNumber = iniFile.value ( "Reduction", 100 ).toFloat();
 +    kZoomSlowness = iniFile.value("zoom-slowness", 0).toFloat();
  	iniFile.endGroup ();
  }
 -void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, bool newTarget)
 +void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position,
 +                                       THeadPoseData *target_camera_position,
 +                                       THeadPoseData *new_camera_position,
 +                                       THeadPoseData *last_post_filter_values,
 +                                       bool newTarget)
  {
  	double target[6];
  	double prev_output[6];
 @@ -130,10 +137,7 @@ void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, T  		// useful for filtering, as skipping them would result in jerky output.
  		// the magic "100" is the amount of calls to the filter by FTNOIR per sec.
  		// WVR: Added kMagicNumber for Patrick
 -		double velocity = foo / 100.0;
 -		if (kMagicNumber > 0.0f) {
 -			double velocity = foo / kMagicNumber;
 -		}
 +        double velocity = foo / (kMagicNumber > 0 ? kMagicNumber : 100.0) * (1 / std::max(1.0, 1 + kZoomSlowness * -last_post_filter_values->z / 100));
  		double sum = start + velocity * sign;
  		bool done = (sign > 0 ? sum >= e2 : sum <= e2);
  		if (done) {
 @@ -168,9 +172,8 @@ void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, T  //   GetFilter     - Undecorated name, which can be easily used with GetProcAddress
  //                Win32 API function.
  //   _GetFilter@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilter=_GetFilter@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterPtr __stdcall GetFilter()
 +extern "C" FTNOIR_FILTER_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Filter;
 +    return (IFilter*) new FTNoIR_Filter;
  }
 diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h index 77aa59ea..32cebf99 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -26,39 +26,16 @@  #ifndef INCLUDED_FTN_FILTER_H
  #define INCLUDED_FTN_FILTER_H
 -#include "..\ftnoir_filter_base\ftnoir_filter_base.h"
 -#include "ui_FTNoIR_FilterControls.h"
 -#include <FunctionConfig.h>
 +#undef FTNOIR_TRACKER_BASE_LIB
 +#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT
 -const QPointF defScaleRotation[] =
 -{
 -    QPointF(0, 0),
 -    QPointF(0.308900523560209, 0.0666666666666667),
 -    QPointF(0.565445026178011, 0.226666666666667),
 -    QPointF(0.769633507853403, 0.506666666666667),
 -    QPointF(0.994764397905759, 1),
 -    QPointF(1.23560209424084, 1.61333333333333),
 -    QPointF(1.47643979057592, 2.37333333333333),
 -    QPointF(1.66492146596859, 3.12),
 -    QPointF(1.80628272251309, 3.92),
 -    QPointF(1.91623036649215, 4.70666666666667),
 -    QPointF(2.00523560209424, 5.44),
 -    QPointF(2.07329842931937, 6)
 -};
 +#include "ftnoir_filter_base/ftnoir_filter_base.h"
 +#include "ui_ftnoir_accela_filtercontrols.h"
 +#include <qfunctionconfigurator/functionconfig.h>
 +#include "facetracknoir/global-settings.h"
 -const QPointF defScaleTranslation[] =
 -{
 -    QPointF(0, 0),
 -    QPointF(0.282722513089005, 0.08),
 -    QPointF(0.492146596858639, 0.306666666666667),
 -    QPointF(0.764397905759162, 0.84),
 -	QPointF(1.00523560209424, 1.62666666666667),
 -	QPointF(1.17277486910995, 2.78666666666667),
 -	QPointF(1.25130890052356, 3.6),
 -	QPointF(1.31937172774869, 4.29333333333333),
 -	QPointF(1.38219895287958, 4.90666666666667),
 -    QPointF(1.43455497382199, 5.65333333333333)
 -};
 +extern const QList<QPointF> defScaleRotation;
 +extern const QList<QPointF> defScaleTranslation;
  //
  // Macro to determine array-size
 @@ -68,16 +45,14 @@ const QPointF defScaleTranslation[] =  //*******************************************************************************************************
  // FaceTrackNoIR Filter class.
  //*******************************************************************************************************
 -class FTNoIR_Filter : public IFilter
 +class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter
  {
  public:
  	FTNoIR_Filter();
  	~FTNoIR_Filter();
 -	void Release();
      void Initialize();
 -    void StartFilter();
 -	void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, bool newTarget);
 +    void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, THeadPoseData *last_post_filter_values, bool newTarget);
  private:
  	void loadSettings();									// Load the settings from the INI-file
 @@ -86,7 +61,7 @@ private:  	bool	first_run;
  	double kFactor, kFactorTranslation;
  	double kSensitivity, kSensitivityTranslation;
 -	double kMagicNumber;									// Stanislaws' magic number (should be 100 according to him...)
 +    double kMagicNumber, kZoomSlowness;		// Stanislaws' magic number (should be 100 according to him...)
  	FunctionConfig functionConfig;
  	FunctionConfig translationFunctionConfig;
 @@ -97,7 +72,7 @@ private:  //*******************************************************************************************************
  // Widget that has controls for FTNoIR protocol filter-settings.
 -class FilterControls: public QWidget, Ui::UICFilterControls, public IFilterDialog
 +class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, Ui::AccelaUICFilterControls, public IFilterDialog
  {
      Q_OBJECT
  public:
 @@ -107,17 +82,17 @@ public:  	void showEvent ( QShowEvent * event );
  	void Release();											// Member functions which are accessible from outside the DLL
 -    void Initialize(QWidget *parent, IFilterPtr ptr);
 +    void Initialize(QWidget *parent, IFilter *ptr);
  private:
 -	Ui::UICFilterControls ui;
 +    Ui::AccelaUICFilterControls ui;
  	void loadSettings();
  	void save();
  	/** helper **/
  	bool settingsDirty;
 -	IFilterPtr pFilter;										// If the filter was active when the dialog was opened, this will hold a pointer to the Filter instance
 +    IFilter* pFilter;										// If the filter was active when the dialog was opened, this will hold a pointer to the Filter instance
  	FunctionConfig functionConfig;
  	FunctionConfig translationFunctionConfig;
 @@ -131,17 +106,17 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter
  //*******************************************************************************************************
 -class FTNoIR_FilterDll : public IFilterDll
 +class FTNoIR_FilterDll : public Metadata
  {
  public:
  	FTNoIR_FilterDll();
  	~FTNoIR_FilterDll();
 -	void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk2"); };
 -	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk2"); };
 -	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk2"); };
 +    void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk2"); }
 +    void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk2"); }
 +    void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk2"); }
 -	void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png");	};
 +    void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png");	}
  };
 diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp index c230eed8..9970e962 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp @@ -26,9 +26,10 @@  	Modifications (last one on top):
  		20130102 - WVR: Added 'reduction factor' to accommodate Patrick's need for speed.
  */
 -#include "ftnoir_filter_Accela.h"
 +#include "ftnoir_filter_accela/ftnoir_filter_accela.h"
  #include "math.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Filter Settings-dialog.
 @@ -51,7 +52,7 @@ FilterControls::FilterControls() :  	connect(ui.translationScalingConfig, SIGNAL(CurveChanged(bool)), this, SLOT(settingChanged(bool)));
  	// Connect slider for reduction
 -	connect(ui.slideReduction, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int)));
 +    //connect(ui.slideReduction, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int)));
  	qDebug() << "FilterControls() says: started";
  }
 @@ -71,7 +72,7 @@ void FilterControls::Release()  //
  // Initialize tracker-client-dialog
  //
 -void FilterControls::Initialize(QWidget *parent, IFilterPtr ptr) {
 +void FilterControls::Initialize(QWidget *parent, IFilter* ptr) {
  	//
  	// The dialog can be opened, while the Tracker is running.
 @@ -79,6 +80,7 @@ void FilterControls::Initialize(QWidget *parent, IFilterPtr ptr) {  	// This can be used to update settings, while Tracking and may also be handy to display logging-data and such...
  	//
  	pFilter = ptr;
 +    loadSettings();
  	QPoint offsetpos(100, 100);
  	if (parent) {
 @@ -100,7 +102,6 @@ void FilterControls::doOK() {  // override show event
  void FilterControls::showEvent ( QShowEvent * event ) {
 -	loadSettings();
  }
  //
 @@ -150,16 +151,16 @@ QList<QPointF> defPoints;  	qDebug() << "FTNoIR_Filter::loadSettings2 says: iniFile = " << currentFile;
 -	qDebug() << "FTNoIR_Filter::loadSettings2 says: size = " << NUM_OF(defScaleRotation);
 +    //qDebug() << "FTNoIR_Filter::loadSettings2 says: size = " << NUM_OF(defScaleRotation);
  	defPoints.clear();
 -	for (int i = 0; i < NUM_OF(defScaleRotation); i++) {		// Get the default points (hardcoded!)
 +    for (int i = 0; i < defScaleRotation.size(); i++) {		// Get the default points (hardcoded!)
  		defPoints.append(defScaleRotation[i]);
  	}
  	functionConfig.loadSettings(iniFile, defPoints);
  	defPoints.clear();
 -	for (int i = 0; i < NUM_OF(defScaleTranslation); i++) {		// Get the default points (hardcoded!)
 +    for (int i = 0; i < defScaleTranslation.size(); i++) {		// Get the default points (hardcoded!)
  		defPoints.append(defScaleTranslation[i]);
  	}
  	translationFunctionConfig.loadSettings(iniFile, defPoints);
 @@ -169,6 +170,7 @@ QList<QPointF> defPoints;  	iniFile.beginGroup ( "Accela" );
  	ui.slideReduction->setValue (iniFile.value ( "Reduction", 100 ).toInt());
 +    ui.slideZoom->setValue(iniFile.value("zoom-slowness", 0).toInt());
  	iniFile.endGroup ();
  	settingsDirty = false;
 @@ -187,6 +189,7 @@ void FilterControls::save() {  	iniFile.beginGroup ( "Accela" );
  	iniFile.setValue ( "Reduction", ui.slideReduction->value() );
 +    iniFile.setValue("zoom-slowness", ui.slideZoom->value());
  	iniFile.endGroup ();
  	functionConfig.saveSettings(iniFile);
 @@ -202,9 +205,9 @@ void FilterControls::save() {  //   GetFilterDialog     - Undecorated name, which can be easily used with GetProcAddress
  //                          Win32 API function.
  //   _GetFilterDialog@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0")
 +//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterDialogPtr __stdcall GetFilterDialog( )
 +extern "C" FTNOIR_FILTER_BASE_EXPORT void* CALLING_CONVENTION GetDialog()
  {
 -	return new FilterControls;
 +    return (IFilterDialog*) new FilterControls;
  }
 diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp index e1452bf2..3ae273df 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp @@ -30,8 +30,9 @@  						The FilterDll class solves this.
  						The functions to get the name(s) and icon were removed from the two other classes.
  */
 -#include "ftnoir_filter_Accela.h"
 +#include "ftnoir_filter_accela.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_FilterDll::FTNoIR_FilterDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_FilterDll::~FTNoIR_FilterDll()  //   GetFilterDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetFilterDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0")
 +//#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterDllPtr __stdcall GetFilterDll()
 +extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
 -	return new FTNoIR_FilterDll;
 +    return new FTNoIR_FilterDll;
  }
 diff --git a/ftnoir_filter_base/ftnoir_filter_base.h b/ftnoir_filter_base/ftnoir_filter_base.h index 44ce3d72..37309077 100644 --- a/ftnoir_filter_base/ftnoir_filter_base.h +++ b/ftnoir_filter_base/ftnoir_filter_base.h @@ -2,7 +2,7 @@  #define FTNOIR_FILTER_BASE_H
  #include "ftnoir_filter_base_global.h"
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
  #include <QString>
  #include <QList>
  #include <QFile>
 @@ -27,40 +27,10 @@ struct IFilter  {
  	virtual ~IFilter() {}
  	virtual void Initialize() = 0;
 -	virtual void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, bool newTarget) = 0;
 +    virtual void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, THeadPoseData *last_post_filter, bool newTarget) = 0;
  };
 -typedef IFilter* IFilterPtr;
 -//typedef IFilter *(__stdcall *importGetFilter)(void);
 -
 -// Factory function that creates instances of the Filter object.
 -EXTERN_C
 -FTNOIR_FILTER_BASE_EXPORT
 -IFilterPtr
 -__stdcall
 -GetFilter(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 IFilterDialog
 -{
 -	virtual ~IFilterDialog() {}
 -	virtual void Initialize(QWidget *parent, IFilterPtr ptr) = 0;
 -};
 -
 -typedef IFilterDialog* IFilterDialogPtr;
 -
 -
  // Factory function that creates instances of the Filter object.
 -EXTERN_C
 -FTNOIR_FILTER_BASE_EXPORT
 -IFilterDialogPtr
 -__stdcall
 -GetFilterDialog(void);
  ////////////////////////////////////////////////////////////////////////////////
  // COM-Like abstract interface.
 @@ -78,14 +48,15 @@ struct IFilterDll  	virtual void getIcon(QIcon *icon) = 0;
  };
 -typedef IFilterDll* IFilterDllPtr;
 -
 -// Factory function that creates instances of the Filter object.
 -EXTERN_C
 -FTNOIR_FILTER_BASE_EXPORT
 -IFilterDllPtr
 -__stdcall
 -GetFilterDll(void);
 +struct IFilterDialog
 +{
 +    virtual ~IFilterDialog() {}
 +    virtual void Initialize(QWidget *parent, IFilter* ptr) = 0;
 +    virtual void getFullName(QString *strToBeFilled) {};
 +    virtual void getShortName(QString *strToBeFilled) {};
 +    virtual void getDescription(QString *strToBeFilled) {};
 +    virtual void getIcon(QIcon *icon) {};
 +};
  #endif // FTNOIR_FILTER_BASE_H
 diff --git a/ftnoir_filter_base/ftnoir_filter_base_global.h b/ftnoir_filter_base/ftnoir_filter_base_global.h index aac4048e..a923f6cf 100644 --- a/ftnoir_filter_base/ftnoir_filter_base_global.h +++ b/ftnoir_filter_base/ftnoir_filter_base_global.h @@ -1,7 +1,7 @@  #ifndef FTNOIR_FILTER_BASE_GLOBAL_H
  #define FTNOIR_FILTER_BASE_GLOBAL_H
 -#include <Qt/qglobal.h>
 +#include <QtGlobal>
  #ifdef FTNOIR_FILTER_BASE_LIB
  # define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT
 diff --git a/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui b/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui new file mode 100644 index 00000000..0f31bcd3 --- /dev/null +++ b/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui @@ -0,0 +1,587 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFilterControls</class> + <widget class="QWidget" name="UICFilterControls"> +  <property name="geometry"> +   <rect> +    <x>0</x> +    <y>0</y> +    <width>371</width> +    <height>380</height> +   </rect> +  </property> +  <property name="minimumSize"> +   <size> +    <width>0</width> +    <height>380</height> +   </size> +  </property> +  <property name="windowTitle"> +   <string>EWMA2 Filter settings FaceTrackNoIR</string> +  </property> +  <property name="windowIcon"> +   <iconset> +    images/facetracknoir.png +   </iconset> +  </property> +  <property name="layoutDirection"> +   <enum>Qt::LeftToRight</enum> +  </property> +  <property name="autoFillBackground"> +   <bool>false</bool> +  </property> +  <property name="styleSheet"> +   <string notr="true"/> +  </property> +  <layout class="QVBoxLayout" name="_vertical_layout"> +   <item> +    <layout class="QVBoxLayout" name="verticalLayout_2"> +     <property name="sizeConstraint"> +      <enum>QLayout::SetMinimumSize</enum> +     </property> +     <item> +      <layout class="QGridLayout" name="gridLayout"> +       <item row="4" column="3"> +        <widget class="QLabel" name="lblInvert1_5"> +         <property name="minimumSize"> +          <size> +           <width>0</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>pow</string> +         </property> +        </widget> +       </item> +       <item row="4" column="2"> +        <widget class="QSpinBox" name="spinPowCurve"> +         <property name="minimumSize"> +          <size> +           <width>40</width> +           <height>22</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true">background:none;</string> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="singleStep"> +          <number>5</number> +         </property> +         <property name="value"> +          <number>10</number> +         </property> +        </widget> +       </item> +       <item row="4" column="1"> +        <widget class="QSlider" name="powCurve"> +         <property name="minimumSize"> +          <size> +           <width>45</width> +           <height>15</height> +          </size> +         </property> +         <property name="minimum"> +          <number>1</number> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="pageStep"> +          <number>10</number> +         </property> +         <property name="value"> +          <number>10</number> +         </property> +         <property name="orientation"> +          <enum>Qt::Horizontal</enum> +         </property> +         <property name="tickPosition"> +          <enum>QSlider::NoTicks</enum> +         </property> +        </widget> +       </item> +       <item row="3" column="3"> +        <widget class="QLabel" name="lblInvert1_4"> +         <property name="minimumSize"> +          <size> +           <width>35</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>frames</string> +         </property> +        </widget> +       </item> +       <item row="3" column="0"> +        <widget class="QLabel" name="lblInvert1_7"> +         <property name="minimumSize"> +          <size> +           <width>0</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>Max.</string> +         </property> +        </widget> +       </item> +       <item row="4" column="0"> +        <widget class="QLabel" name="lblInvert1_8"> +         <property name="minimumSize"> +          <size> +           <width>0</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>Curve</string> +         </property> +        </widget> +       </item> +       <item row="2" column="2"> +        <widget class="QSpinBox" name="spinMinSmooth"> +         <property name="minimumSize"> +          <size> +           <width>40</width> +           <height>22</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true">background:none;</string> +         </property> +         <property name="minimum"> +          <number>1</number> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="singleStep"> +          <number>5</number> +         </property> +         <property name="value"> +          <number>2</number> +         </property> +        </widget> +       </item> +       <item row="2" column="3"> +        <widget class="QLabel" name="lblInvert1"> +         <property name="minimumSize"> +          <size> +           <width>35</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>frames</string> +         </property> +        </widget> +       </item> +       <item row="3" column="1"> +        <widget class="QSlider" name="maxSmooth"> +         <property name="minimumSize"> +          <size> +           <width>45</width> +           <height>15</height> +          </size> +         </property> +         <property name="minimum"> +          <number>1</number> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="pageStep"> +          <number>10</number> +         </property> +         <property name="value"> +          <number>10</number> +         </property> +         <property name="orientation"> +          <enum>Qt::Horizontal</enum> +         </property> +         <property name="tickPosition"> +          <enum>QSlider::NoTicks</enum> +         </property> +        </widget> +       </item> +       <item row="3" column="2"> +        <widget class="QSpinBox" name="spinMaxSmooth"> +         <property name="minimumSize"> +          <size> +           <width>40</width> +           <height>22</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true">background:none;</string> +         </property> +         <property name="minimum"> +          <number>1</number> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="singleStep"> +          <number>5</number> +         </property> +         <property name="value"> +          <number>10</number> +         </property> +        </widget> +       </item> +       <item row="2" column="0"> +        <widget class="QLabel" name="lblInvert1_6"> +         <property name="minimumSize"> +          <size> +           <width>0</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>30</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="styleSheet"> +          <string notr="true"/> +         </property> +         <property name="text"> +          <string>Min.</string> +         </property> +        </widget> +       </item> +       <item row="2" column="1"> +        <widget class="QSlider" name="minSmooth"> +         <property name="minimumSize"> +          <size> +           <width>45</width> +           <height>15</height> +          </size> +         </property> +         <property name="minimum"> +          <number>1</number> +         </property> +         <property name="maximum"> +          <number>100</number> +         </property> +         <property name="pageStep"> +          <number>10</number> +         </property> +         <property name="value"> +          <number>2</number> +         </property> +         <property name="orientation"> +          <enum>Qt::Horizontal</enum> +         </property> +         <property name="tickPosition"> +          <enum>QSlider::NoTicks</enum> +         </property> +        </widget> +       </item> +      </layout> +     </item> +     <item> +      <widget class="QLabel" name="label_4"> +       <property name="minimumSize"> +        <size> +         <width>0</width> +         <height>204</height> +        </size> +       </property> +       <property name="styleSheet"> +        <string notr="true">background-color: rgb(214, 214, 214); +border-color: rgb(0, 0, 0);</string> +       </property> +       <property name="frameShape"> +        <enum>QFrame::Box</enum> +       </property> +       <property name="text"> +        <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Min. frames:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Defines the way the filter responds to fast movements;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Higher value: slower response;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Max. frames:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Defines the way the filter responds to slow movements;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Higher value: slower response;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Pow:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Defines the filters 'readiness' to respond to speed changes;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Higher value = </span><span style=" font-size:10pt; font-weight:600;">higher</span><span style=" font-size:10pt;"> response;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p></body></html></string> +       </property> +       <property name="margin"> +        <number>5</number> +       </property> +      </widget> +     </item> +    </layout> +   </item> +   <item> +    <spacer name="verticalSpacer"> +     <property name="orientation"> +      <enum>Qt::Vertical</enum> +     </property> +     <property name="sizeHint" stdset="0"> +      <size> +       <width>20</width> +       <height>40</height> +      </size> +     </property> +    </spacer> +   </item> +   <item> +    <layout class="QHBoxLayout" name="horizontalLayout"> +     <item> +      <spacer name="horizontalSpacer_2"> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="sizeHint" stdset="0"> +        <size> +         <width>40</width> +         <height>20</height> +        </size> +       </property> +      </spacer> +     </item> +     <item> +      <layout class="QHBoxLayout" name="horizontalLayout_2"> +       <property name="sizeConstraint"> +        <enum>QLayout::SetDefaultConstraint</enum> +       </property> +       <item> +        <widget class="QPushButton" name="btnOK"> +         <property name="sizePolicy"> +          <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> +           <horstretch>0</horstretch> +           <verstretch>0</verstretch> +          </sizepolicy> +         </property> +         <property name="minimumSize"> +          <size> +           <width>52</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>100</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="text"> +          <string>OK</string> +         </property> +        </widget> +       </item> +       <item> +        <widget class="QPushButton" name="btnCancel"> +         <property name="sizePolicy"> +          <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> +           <horstretch>0</horstretch> +           <verstretch>0</verstretch> +          </sizepolicy> +         </property> +         <property name="minimumSize"> +          <size> +           <width>52</width> +           <height>0</height> +          </size> +         </property> +         <property name="maximumSize"> +          <size> +           <width>100</width> +           <height>16777215</height> +          </size> +         </property> +         <property name="text"> +          <string>Cancel</string> +         </property> +        </widget> +       </item> +      </layout> +     </item> +     <item> +      <spacer name="horizontalSpacer"> +       <property name="orientation"> +        <enum>Qt::Horizontal</enum> +       </property> +       <property name="sizeType"> +        <enum>QSizePolicy::Fixed</enum> +       </property> +       <property name="sizeHint" stdset="0"> +        <size> +         <width>10</width> +         <height>20</height> +        </size> +       </property> +      </spacer> +     </item> +    </layout> +   </item> +  </layout> + </widget> + <tabstops> +  <tabstop>btnOK</tabstop> +  <tabstop>btnCancel</tabstop> + </tabstops> + <resources/> + <connections> +  <connection> +   <sender>minSmooth</sender> +   <signal>valueChanged(int)</signal> +   <receiver>spinMinSmooth</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>199</x> +     <y>22</y> +    </hint> +    <hint type="destinationlabel"> +     <x>337</x> +     <y>23</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>spinMinSmooth</sender> +   <signal>valueChanged(int)</signal> +   <receiver>minSmooth</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>330</x> +     <y>12</y> +    </hint> +    <hint type="destinationlabel"> +     <x>185</x> +     <y>17</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>maxSmooth</sender> +   <signal>valueChanged(int)</signal> +   <receiver>spinMaxSmooth</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>181</x> +     <y>48</y> +    </hint> +    <hint type="destinationlabel"> +     <x>335</x> +     <y>54</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>spinMaxSmooth</sender> +   <signal>valueChanged(int)</signal> +   <receiver>maxSmooth</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>324</x> +     <y>42</y> +    </hint> +    <hint type="destinationlabel"> +     <x>259</x> +     <y>43</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>powCurve</sender> +   <signal>valueChanged(int)</signal> +   <receiver>spinPowCurve</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>145</x> +     <y>74</y> +    </hint> +    <hint type="destinationlabel"> +     <x>339</x> +     <y>78</y> +    </hint> +   </hints> +  </connection> +  <connection> +   <sender>spinPowCurve</sender> +   <signal>valueChanged(int)</signal> +   <receiver>powCurve</receiver> +   <slot>setValue(int)</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>330</x> +     <y>69</y> +    </hint> +    <hint type="destinationlabel"> +     <x>176</x> +     <y>76</y> +    </hint> +   </hints> +  </connection> + </connections> + <slots> +  <slot>startEngineClicked()</slot> +  <slot>stopEngineClicked()</slot> +  <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp index fac0e13c..5f196533 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp @@ -25,7 +25,9 @@  #include "ftnoir_filter_ewma2.h"
  #include "math.h"
  #include <QDebug>
 -
 +#include <QWidget>
 +#include "facetracknoir/global-settings.h"
 +#include <algorithm>
  //#define LOG_OUTPUT
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 @@ -47,11 +49,6 @@ FTNoIR_Filter::~FTNoIR_Filter()  }
 -void FTNoIR_Filter::Release()
 -{
 -    delete this;
 -}
 -
  void FTNoIR_Filter::Initialize()
  {
  	qDebug() << "FTNoIR_Filter::Initialize says: Starting ";
 @@ -82,7 +79,7 @@ void FTNoIR_Filter::loadSettings() {  }
 -void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, bool newTarget)
 +void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, THeadPoseData *last_post_filter, bool newTarget)
  {
  	//non-optimised version for clarity
  	float prev_output[6];
 @@ -149,7 +146,7 @@ void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, T  	//normalise the deltas
  	for (i=0;i<6;i++)
  	{
 -		norm_output_delta[i]=std::min(std::max(fabs(output_delta[i])/scale[i],0.0f),1.0f);
 +        norm_output_delta[i]=std::min<double>(std::max<double>(fabs(output_delta[i])/scale[i],0.0),1.0);
  	}
  	//calculate the alphas
 @@ -228,9 +225,9 @@ void FTNoIR_Filter::FilterHeadPoseData(THeadPoseData *current_camera_position, T  //   GetFilter     - Undecorated name, which can be easily used with GetProcAddress
  //                Win32 API function.
  //   _GetFilter@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilter=_GetFilter@0")
 +//#pragma comment(linker, "/export:GetFilter=_GetFilter@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterPtr __stdcall GetFilter()
 +extern "C" FTNOIR_FILTER_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Filter;
 +    return (IFilter*) new FTNoIR_Filter;
  }
 diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h index 18afe3bd..cade740f 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h @@ -26,8 +26,10 @@  #ifndef INCLUDED_FTN_FILTER_H
  #define INCLUDED_FTN_FILTER_H
 -#include "..\ftnoir_filter_base\ftnoir_filter_base.h"
 -#include "ui_FTNoIR_FilterControls.h"
 +#include "ftnoir_filter_base/ftnoir_filter_base.h"
 +#include "facetracknoir/global-settings.h"
 +#include "ui_ftnoir_ewma_filtercontrols.h"
 +#include <QWidget>
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //
 @@ -38,12 +40,10 @@ class FTNoIR_Filter : public IFilter  {
  public:
  	FTNoIR_Filter();
 -	~FTNoIR_Filter();
 +    ~FTNoIR_Filter();
 -	void Release();
      void Initialize();
 -    void StartFilter();
 -	void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, bool newTarget);
 +    void FilterHeadPoseData(THeadPoseData *current_camera_position, THeadPoseData *target_camera_position, THeadPoseData *new_camera_position, THeadPoseData *last_post_filter, bool newTarget);
  private:
  	void loadSettings();									// Load the settings from the INI-file
 @@ -76,7 +76,7 @@ public:  	void showEvent ( QShowEvent * event );
  	void Release();											// Member functions which are accessible from outside the DLL
 -    void Initialize(QWidget *parent, IFilterPtr ptr);
 +    void Initialize(QWidget *parent, IFilter* ptr);
  private:
  	Ui::UICFilterControls ui;
 @@ -86,7 +86,7 @@ private:  	/** helper **/
  	bool settingsDirty;
 -	IFilterPtr pFilter;										// If the filter was active when the dialog was opened, this will hold a pointer to the Filter instance
 +    IFilter* pFilter;										// If the filter was active when the dialog was opened, this will hold a pointer to the Filter instance
  private slots:
  	void doOK();
 @@ -98,7 +98,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter
  //*******************************************************************************************************
 -class FTNoIR_FilterDll : public IFilterDll
 +class FTNoIR_FilterDll : public Metadata
  {
  public:
  	FTNoIR_FilterDll();
 diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp index c7798ac0..3e0fdb25 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp @@ -22,9 +22,11 @@  * with this program; if not, see <http://www.gnu.org/licenses/>.				*
  *																				*
  ********************************************************************************/
 -#include "ftnoir_filter_EWMA2.h"
 +#include "ftnoir_filter_ewma2.h"
  #include "math.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
 +#include "ui_ftnoir_ewma_filtercontrols.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Filter Settings-dialog.
 @@ -72,7 +74,7 @@ void FilterControls::Release()  //
  // Initialize tracker-client-dialog
  //
 -void FilterControls::Initialize(QWidget *parent, IFilterPtr ptr) {
 +void FilterControls::Initialize(QWidget *parent, IFilter* ptr) {
  	//
  	// The dialog can be opened, while the Tracker is running.
 @@ -189,9 +191,9 @@ void FilterControls::save() {  //   GetFilterDialog     - Undecorated name, which can be easily used with GetProcAddress
  //                          Win32 API function.
  //   _GetFilterDialog@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0")
 +//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterDialogPtr __stdcall GetFilterDialog( )
 +extern "C" FTNOIR_FILTER_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new FilterControls;
 +    return (IFilterDialog*) new FilterControls;
  }
 diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp index 4e644446..a01b0661 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_filter_ewma2.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_FilterDll::FTNoIR_FilterDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_FilterDll::~FTNoIR_FilterDll()  //   GetFilterDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetFilterDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0")
 +//#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0")
 -FTNOIR_FILTER_BASE_EXPORT IFilterDllPtr __stdcall GetFilterDll()
 +extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_FilterDll;
  }
 diff --git a/ftnoir_posewidget/glwidget.cpp b/ftnoir_posewidget/glwidget.cpp index 55b65619..32723dc9 100644 --- a/ftnoir_posewidget/glwidget.cpp +++ b/ftnoir_posewidget/glwidget.cpp @@ -28,10 +28,14 @@  #include <QtOpenGL>
  #include "glwidget.h"
 +#include <QWidget>
  GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
      : QGLWidget(parent, shareWidget)
  {
 +#if !defined(_WIN32)
 +    setAttribute(Qt::WA_NativeWindow, true);
 +#endif
      clearColor = Qt::black;
      xRot = 0;
      yRot = 0;
 @@ -74,7 +78,7 @@ void GLWidget::initializeGL()  {
      makeObject();
 -    glEnable(GL_DEPTH_TEST);
 +    glDisable(GL_DEPTH_TEST);
      glEnable(GL_CULL_FACE);
  #ifndef QT_OPENGL_ES_2
      glEnable(GL_TEXTURE_2D);
 @@ -117,16 +121,20 @@ void GLWidget::initializeGL()      program->bind();
      program->setUniformValue("texture", 0);
 -
 +#else
 +    glEnableClientState(GL_VERTEX_ARRAY);
 +    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 +    glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
 +    glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
  #endif
  }
  void GLWidget::paintGL()
  {
 -    qglClearColor(clearColor);
 +    glClearColor(0, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 -#if !defined(QT_OPENGL_ES_2)
 +#if 1
      glLoadIdentity();
      glTranslatef(0.0f, 0.0f, -10.0f);
 @@ -135,11 +143,6 @@ void GLWidget::paintGL()      glRotatef(yRot, 0.0f, 1.0f, 0.0f);
      glRotatef(-1.0f * zRot, 0.0f, 0.0f, 1.0f);
 -    glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
 -    glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
 -    glEnableClientState(GL_VERTEX_ARRAY);
 -    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 -
  #else
      QMatrix4x4 m;
 @@ -163,6 +166,7 @@ void GLWidget::paintGL()          glBindTexture(GL_TEXTURE_2D, textures[i]);
          glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
      }
 +    glFlush();
  }
  void GLWidget::resizeGL(int width, int height)
 diff --git a/ftnoir_posewidget/glwidget.h b/ftnoir_posewidget/glwidget.h index cff8cb83..3d0e590a 100644 --- a/ftnoir_posewidget/glwidget.h +++ b/ftnoir_posewidget/glwidget.h @@ -29,10 +29,11 @@  #include <QtGui>
  #include <QGLWidget>
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
  class QGLShaderProgram;
 -class GLWidget : public QGLWidget
 +class FTNOIR_TRACKER_BASE_EXPORT GLWidget : public QGLWidget
  {
      Q_OBJECT
 diff --git a/ftnoir_protocol_base/ftnoir_protocol_base.h b/ftnoir_protocol_base/ftnoir_protocol_base.h index 3f598d35..5d88a508 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base.h @@ -33,12 +33,12 @@  #define FTNOIR_PROTOCOL_BASE_H
  #include "ftnoir_protocol_base_global.h"
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_types.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
  #include <QtGui/QWidget>
  #include <QtGui/QFrame>
  //#include "winbase.h"
 -#include "windows.h"
 +//#include "windows.h"
  //#include "winable.h"
  ////////////////////////////////////////////////////////////////////////////////
 @@ -58,43 +58,11 @@ struct IProtocol  {
  	virtual ~IProtocol() {}
  	virtual void Initialize() = 0;
 -	virtual bool checkServerInstallationOK ( HANDLE handle ) = 0;
 +    virtual bool checkServerInstallationOK() = 0;
  	virtual void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose ) = 0;
  	virtual void getNameFromGame( char *dest ) = 0;				// Take care dest can handle up to 100 chars...
  };
 -typedef IProtocol* IProtocolPtr;
 -
 -// Factory function that creates instances of the Protocol object.
 -EXTERN_C
 -FTNOIR_PROTOCOL_BASE_EXPORT
 -IProtocolPtr
 -__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 ~IProtocolDialog() {}
 -	virtual void Initialize(QWidget *parent) = 0;
 -	virtual void registerProtocol(IProtocol *protocol) = 0;
 -	virtual void unRegisterProtocol() = 0;
 -};
 -
 -typedef IProtocolDialog* IProtocolDialogPtr;
 -
 -// Factory function that creates instances of the Protocol object.
 -EXTERN_C
 -FTNOIR_PROTOCOL_BASE_EXPORT
 -IProtocolDialogPtr
 -__stdcall
 -GetProtocolDialog(void);
 -
  ////////////////////////////////////////////////////////////////////////////////
  // COM-Like abstract interface.
  // This interface doesn't require __declspec(dllexport/dllimport) specifier.
 @@ -111,14 +79,14 @@ struct IProtocolDll  	virtual void getIcon(QIcon *icon) = 0;
  };
 -typedef IProtocolDll* IProtocolDllPtr;
 -
 -// Factory function that creates instances of the Protocol object.
 -EXTERN_C
 -FTNOIR_PROTOCOL_BASE_EXPORT
 -IProtocolDllPtr
 -__stdcall
 -GetProtocolDll(void);
 +struct IProtocolDialog
 +{
 +    virtual ~IProtocolDialog() {}
 +	virtual void Initialize(QWidget *parent) = 0;
 +    virtual void showEvent ( QShowEvent * event ) = 0;
 +    virtual void registerProtocol(IProtocol *protocol) = 0;
 +    virtual void unRegisterProtocol() = 0;
 +};
  #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 index 3527bad7..ca51e26d 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base_global.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base_global.h @@ -1,7 +1,7 @@  #ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H
  #define FTNOIR_PROTOCOL_BASE_GLOBAL_H
 -#include <Qt/qglobal.h>
 +#include <QtGlobal>
  #ifdef FTNOIR_PROTOCOL_BASE_LIB
  # define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT
 diff --git a/ftnoir_protocol_fg/fgtypes.h b/ftnoir_protocol_fg/fgtypes.h index 949dc213..68f85877 100644 --- a/ftnoir_protocol_fg/fgtypes.h +++ b/ftnoir_protocol_fg/fgtypes.h @@ -14,15 +14,14 @@  #ifndef INCLUDED_FGTYPES_H
  #define INCLUDED_FGTYPES_H
 -#include "Windows.h" 
 -
  //
  // x,y,z position in metres, heading, pitch and roll in degrees...
  //
 -#pragma pack(2)
 +#pragma pack(push, 2)
  struct TFlightGearData {
  	double x, y, z, h, p, r;
  	int status;
  };
 +#pragma pack(pop)
  #endif//INCLUDED_FGTYPES_H
 diff --git a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui index 3469e7aa..116f830b 100644 --- a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui +++ b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp index 5506f534..0c259d61 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp @@ -33,6 +33,7 @@  */
  #include "ftnoir_protocol_fg.h"
  #include <QFile>
 +#include "facetracknoir/global-settings.h"
  // For Todd and Arda Kutlu
  //#define SEND_ASCII_DATA
 @@ -42,7 +43,6 @@  FTNoIR_Protocol::FTNoIR_Protocol()
  {
  	blnConnectionActive = false;
 -	hMainWindow = NULL;
  	loadSettings();
  }
 @@ -103,7 +103,6 @@ void FTNoIR_Protocol::sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData  int no_bytes;
  QHostAddress sender;
  quint16 senderPort;
 -PDWORD_PTR MsgResult = 0;
  #ifdef SEND_ASCII_DATA
  char data[100];
 @@ -152,7 +151,7 @@ char data[100];  	//! [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);
 +        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 );
  		}
 @@ -181,9 +180,6 @@ char data[100];  			if (!blnConnectionActive) {
  				blnConnectionActive = true;
 -				if (hMainWindow != NULL) {
 -					SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult);
 -				}
  			}
  		}
  	}
 @@ -193,7 +189,7 @@ char data[100];  // Check if the Client DLL exists and load it (to test it), if so.
  // Returns 'true' if all seems OK.
  //
 -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
  	// Init. the data
  	FlightData.x = 0.0f;
 @@ -208,8 +204,6 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  	inSocket = 0;
  	outSocket = 0;
 -	hMainWindow = handle;
 -
  	//
  	// Create UDP-sockets.
  	//
 @@ -238,7 +232,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "FlightGear");
 +    sprintf(dest, "FlightGear");
  	return;
  }
 @@ -249,9 +243,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Protocol;
 +    return (IProtocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.h b/ftnoir_protocol_fg/ftnoir_protocol_fg.h index 34773540..4ff2846f 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.h +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.h @@ -29,17 +29,17 @@  #ifndef INCLUDED_FGSERVER_H
  #define INCLUDED_FGSERVER_H
 -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h"
 -#include "ui_FTNoIR_FGcontrols.h"
 -#include "FGTypes.h"
 +#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
 +#include "ui_ftnoir_fgcontrols.h"
 +#include "fgtypes.h"
  #include <QThread>
  #include <QUdpSocket>
  #include <QMessageBox>
  #include <QSettings>
 -#include "Windows.h"
 -#include "math.h"
 +#include <math.h>
 +#include "facetracknoir/global-settings.h"
 -static const char* FT_PROGRAMID = "FT_ProgramID";				// For message to FaceTrackNoIR main-window.
 +#define FT_PROGRAMID "FT_ProgramID"
  class FTNoIR_Protocol : public IProtocol
  {
 @@ -50,14 +50,13 @@ public:  	void Release();
      void Initialize();
 -	bool checkServerInstallationOK( HANDLE handle );
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );						// Take care dest can handle up to 100 chars...
  private:
  	bool blnConnectionActive;
 -	HANDLE hMainWindow;										// Save the handle to FaceTrackNoIR main-window
  	//	Tracker *headTracker;								// For upstream messages...
  	TFlightGearData FlightData;
 @@ -81,7 +80,6 @@ public:      virtual ~FGControls();
  	void showEvent ( QShowEvent * event );
 -	void Release();											// Member functions which are accessible from outside the DLL
      void Initialize(QWidget *parent);
  	void registerProtocol(IProtocol *protocol) {
  		theProtocol = (FTNoIR_Protocol *) protocol;			// Accept the pointer to the Protocol
 @@ -109,7 +107,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
 @@ -119,7 +117,7 @@ public:  	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear"); };
  	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear UDP protocol"); };
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/FlightGear.ico"); };
 +    void getIcon(QIcon *icon) { *icon = QIcon(":/images/flightgear.png"); };
  };
 diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp index 0138a4c1..9867ea2f 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp @@ -33,6 +33,7 @@  */
  #include "ftnoir_protocol_fg.h"
  #include <QFile>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -74,11 +75,6 @@ FGControls::~FGControls() {  	qDebug() << "~FGControls() says: started";
  }
 -void FGControls::Release()
 -{
 -    delete this;
 -}
 -
  //
  // Initialize tracker-client-dialog
  //
 @@ -217,9 +213,9 @@ void FGControls::chkLocalPCOnlyChanged() {  //   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")
 +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new FGControls;
 -}
\ No newline at end of file +    return (IProtocolDialog*) new FGControls;
 +}
 diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp index ca71063b..45d6271c 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_fg.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   GetProtocolDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
 -	return new FTNoIR_ProtocolDll;
 +    return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_fg/images/flightgear.ico b/ftnoir_protocol_fg/images/flightgear.icoBinary files differ new file mode 100644 index 00000000..f96c0f88 --- /dev/null +++ b/ftnoir_protocol_fg/images/flightgear.ico diff --git a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui index b6120378..d02297f3 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui +++ b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp index 5a4663a1..c750ae26 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp @@ -3,7 +3,7 @@  *					gamers from Holland, who don't like to pay much for			*
  *					head-tracking.												*
  *																				*
 -* Copyright (C) 2010-2013	Wim Vriend (Developing)								*
 +* Copyright (C) 2010-2011	Wim Vriend (Developing)								*
  *							Ron Hendriks (Researching and Testing)				*
  *																				*
  * Homepage																		*
 @@ -31,6 +31,7 @@  					is called from run() of Tracker.cpp
  */
  #include "ftnoir_protocol_fsuipc.h"
 +#include "facetracknoir/global-settings.h"
  /** constructor **/
  FTNoIR_Protocol::FTNoIR_Protocol()
 @@ -38,9 +39,6 @@ FTNoIR_Protocol::FTNoIR_Protocol()  	loadSettings();
  	ProgramName = "Microsoft FS2004";
 -	blnConnectionActive = false;
 -	hMainWindow = NULL;
 -
  	prevPosX = 0.0f;
  	prevPosY = 0.0f;
  	prevPosZ = 0.0f;
 @@ -121,8 +119,6 @@ float virtRotX;  float virtRotY;
  float virtRotZ;
 -PDWORD_PTR MsgResult = 0;
 -
  //	qDebug() << "FSUIPCServer::run() says: started!";
  	virtRotX = -1.0f * headpose->pitch;				// degrees
 @@ -178,14 +174,6 @@ PDWORD_PTR MsgResult = 0;  			if (result == FSUIPC_ERR_SENDMSG) {
  				FSUIPC_Close();							//timeout (1 second) so assume FS closed
  			}
 -
 -			if (!blnConnectionActive) {
 -				blnConnectionActive = true;
 -				if (hMainWindow != NULL) {
 -					SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult);
 -				}
 -			}
 -
  		}
  	}
 @@ -200,11 +188,21 @@ PDWORD_PTR MsgResult = 0;  //
  // Returns 'true' if all seems OK.
  //
 -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
  	qDebug() << "checkServerInstallationOK says: Starting Function";
 -	hMainWindow = handle;
 +	//
 +	// Load the DLL.
 +	//
 +    FSUIPCLib.setFileName( LocationOfDLL );
 +    if (FSUIPCLib.load() != true) {
 +        qDebug() << "checkServerInstallationOK says: Error loading FSUIPC DLL";
 +        return false;
 +    }
 +    else {
 +        qDebug() << "checkServerInstallationOK says: FSUIPC DLL loaded.";
 +    }
  	return true;
  }
 @@ -214,7 +212,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "Microsoft FS2002/2004");
 +	sprintf_s(dest, 99, "FS2002/2004");
  	return;
  }
 @@ -225,9 +223,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor(void)
  {
 -	return new FTNoIR_Protocol;
 +    return (FTNoIR_Protocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h index 8503f6e7..84d5d180 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h @@ -31,6 +31,7 @@  #include "Windows.h"
  #include <stdlib.h>
  #include "FSUIPC_User.h"
 +#include "facetracknoir/global-settings.h"
  #include "..\ftnoir_protocol_base\ftnoir_protocol_base.h"
  #include "ui_FTNoIR_FSUIPCcontrols.h"
 @@ -43,7 +44,6 @@  #include <QFileDialog>
  static const char* FSUIPC_FILENAME = "C:\\Program Files\\Microsoft Games\\Flight Simulator 9\\Modules\\FSUIPC.dll";
 -static const char* FT_PROGRAMID = "FT_ProgramID";				// For message to FaceTrackNoIR main-window.
  //
  // Define the structures necessary for the FSUIPC_Write calls
 @@ -65,7 +65,7 @@ public:  	void Release();
      void Initialize();
 -	bool checkServerInstallationOK( HANDLE handle );
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );					// Take care dest can handle up to 100 chars...
 @@ -76,9 +76,6 @@ private:  	QString LocationOfDLL;
  	float prevPosX, prevPosY, prevPosZ, prevRotX, prevRotY, prevRotZ;
 -	bool blnConnectionActive;
 -	HANDLE hMainWindow;										// Save the handle to FaceTrackNoIR main-window
 -
  	static int scale2AnalogLimits( float x, float min_x, float max_x );
  	void loadSettings();
  };
 @@ -121,7 +118,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
 @@ -131,7 +128,7 @@ public:  	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FSUIPC"); };
  	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft FS2004 protocol"); };
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/FS9.ico"); };
 +	void getIcon(QIcon *icon) { *icon = QIcon(":/images/FS9.png"); };
  };
 diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp index 08c13c08..eca04985 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp @@ -31,6 +31,7 @@  						The functions to get the name(s) and icon were removed from the two other classes.
  */
  #include "ftnoir_protocol_fsuipc.h"
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -189,9 +190,9 @@ void FSUIPCControls::getLocationOfDLL()  //   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")
 +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog(void)
  {
 -	return new FSUIPCControls;
 +    return (IProtocolDialog*) new FSUIPCControls;
  }
 diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp index d61c2d83..72d99fb9 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_fsuipc.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   GetProtocolDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata(void)
  {
  	return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_fsuipc/images/fs9.ico b/ftnoir_protocol_fsuipc/images/fs9.icoBinary files differ new file mode 100644 index 00000000..9afd1953 --- /dev/null +++ b/ftnoir_protocol_fsuipc/images/fs9.ico diff --git a/ftnoir_protocol_ft/FreeTrackClient.c b/ftnoir_protocol_ft/FreeTrackClient.c new file mode 100644 index 00000000..b1b62123 --- /dev/null +++ b/ftnoir_protocol_ft/FreeTrackClient.c @@ -0,0 +1,330 @@ +/******************************************************************************** +* FreeTrackClientDll Implements the FreeTrack 2.0 interface for FT-enabled		* +*					games.														* +*					It uses the FreeTrack protocol (memory mapping) to			* +*					receive data from FaceTrackNoIR (or FreeTrack, or ...).		* +*																				* +* Copyright (C) 2013	Wim Vriend (Developing)									* +*						Ron Hendriks (Testing and Research)						* +*																				* +* Homepage				<http://facetracknoir.sourceforge.net/home/default.htm>	* +*																				* +* 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 <http://www.gnu.org/licenses/>.				* +*																				* +********************************************************************************/ +/* +	Modifications (last one on top): + +	20130208 - WVR: The old DLL from FreeTrack seems to crash ArmA2. And we need 64-bit support. +	 +*/ + +/* + * COMPILE WITH: + * % i686-w64-mingw32-gcc -shared -o FreeTrackClient.dll -O2 FreeTrackClient.c + * DO NOT USE MSVC! IT INTRODUCES FAULTY MANIFEST!!! + * -- sthalik + */ + +#ifdef WIN64 +#pragma comment(linker, "/export:FTGetData") +#pragma comment(linker, "/export:FTReportName") +#pragma comment(linker, "/export:FTGetDllVersion") +#pragma comment(linker, "/export:FTProvider") +#endif + +#define FT_DECLSPEC __declspec(dllexport) + +#define FT_EXPORT(t) FT_DECLSPEC t __stdcall +#define	NP_AXIS_MAX				16383 + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <windows.h> +#include <tchar.h> + +typedef struct TFreeTrackData { +	int DataID; +	int CamWidth; +    int CamHeight; +    // virtual pose +    float Yaw;   // positive yaw to the left +    float Pitch; // positive pitch up +    float Roll;  // positive roll to the left +    float X; +    float Y; +    float Z; +    // raw pose with no smoothing, sensitivity, response curve etc.  +    float RawYaw; +    float RawPitch; +    float RawRoll; +    float RawX; +    float RawY; +    float RawZ; +    // raw points, sorted by Y, origin top left corner +    float X1; +    float Y1; +    float X2; +    float Y2; +    float X3; +    float Y3; +    float X4; +    float Y4; +} TFreeTrackData; +typedef TFreeTrackData * PFreetrackData; + +// +// Functions to create/open the file-mapping +// and to destroy it again. +// +float scale2AnalogLimits( float x, float min_x, float max_x ); +float getDegreesFromRads ( float rads ); +FT_EXPORT(BOOL) FTCreateMapping(void); + +#if 0 +static FILE *debug_stream; +#define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); } +#else +#define dbg_report(...) +#endif + +// +// Handles to 'handle' the memory mapping +// +#define FT_MM_DATA "FT_SharedMem" +#define FREETRACK_MUTEX "FT_Mutext" + +static HANDLE hFTMemMap = 0; +static TFreeTrackData *pMemData = 0; +static HANDLE hFTMutex = 0; +static const char* dllVersion = "1.0.0.0"; +static const char* dllProvider = "FreeTrack"; + +static unsigned short gameid = 0; + +// +// DllMain gets called, when the DLL is (un)loaded or a process attaches. +// +FT_EXPORT(BOOL) WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ +    switch (fdwReason) { +		case DLL_PROCESS_ATTACH: +#ifdef WIN64 +		    dbg_report("\n= WIN64 =========================================================================================\n"); +#else +		    dbg_report("\n= WIN32 =========================================================================================\n"); +#endif +			dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); +            dbg_report("DllMain: Attach request\n"); +//			debug_stream = fopen("c:\\FreeTrackClient.log", "a"); +            DisableThreadLibraryCalls(hinstDLL); +            break; + +		case DLL_PROCESS_DETACH: +			dbg_report("DllMain: Detach\n"); +			dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); +		    dbg_report("==========================================================================================\n"); +            break; +    } +    return TRUE; +} + +/****************************************************************** + *		FTGetData (FreeTrackClient.1) + */ +#pragma comment(linker, "/export:FTGetData@4=FTGetData") +FT_EXPORT(BOOL) FTGetData(TFreeTrackData* data) +{ +  static int frame = 0; +  static int prevDataID = 0; +  static int dlyTrackingOff = 0; +  static int tracking = 0; + +//  dbg_report("NP_GetData called."); +  if (FTCreateMapping() == FALSE) return FALSE; + +  if (hFTMutex && WaitForSingleObject(hFTMutex, 5) == WAIT_OBJECT_0) { +	if (pMemData) { + +		// +		// When FaceTrackNoIR does not update frames (any more), don't update the data. +		// +		if (prevDataID != pMemData->DataID) { +			*data = *pMemData; +			dlyTrackingOff = 0; +		} +		else { +			dlyTrackingOff++; +			if (dlyTrackingOff > 20) { +				dlyTrackingOff = 100; +				tracking = FALSE; +			} +		} +		prevDataID = pMemData->DataID; +		 +		// +		// Limit the range of DataID +		// +		if (pMemData->DataID > 1000) { +			pMemData->DataID = 0; +		} +		data->DataID = pMemData->DataID; + +		// +		// Send the ID to FaceTrackNoIR, so it can display the game-name. +		// This could be a FreeTrack-specific ID +		// +		//sprintf(pMemData->GameID, "%d", gameid ); + +	} +	ReleaseMutex(hFTMutex); +  } +  return TRUE; +} + +/****************************************************************** + *		FTReportName (FreeTrackClient.2) + */ +#pragma comment(linker, "/export:FTReportName@4=FTReportName") +// +// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument. +// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing). +// Thanks guys! +// +FT_EXPORT(void) FTReportName( int name ) +{ +	dbg_report("FTReportName request (ID = %d).\n", name); +	gameid = name;												// They might have really passed the name here... but they didn't! +	return; +} + +/****************************************************************** + *		FTGetDllVersion (FreeTrackClient.3) + */ +#pragma comment(linker, "/export:FTGetDllVersion@0=FTGetDllVersion") +FT_EXPORT(const char*) FTGetDllVersion(void) +{ +    dbg_report("FTGetDllVersion request.\n"); + +	return dllVersion; +} + +/****************************************************************** + *		FTProvider (FreeTrackClient.4) + */ +#pragma comment(linker, "/export:FTProvider@0=FTProvider") +FT_EXPORT(const char*) FTProvider(void) +{ +    dbg_report("FTProvider request.\n"); + +	return dllProvider; +} + +// +// Create a memory-mapping to the Freetrack data. +// It contains the tracking data, a handle to the main-window and the program-name of the Game! +// +// +#pragma comment(linker, "/export:FTCreateMapping@0=FTCreateMapping") +FT_EXPORT(BOOL) FTCreateMapping(void) +{ +	BOOL bMappingExists = FALSE; +	PDWORD_PTR MsgResult = 0; + +	// +	// Memory-mapping already exists! +	// +	if ( pMemData != NULL ) { +		return TRUE; +	} + +    dbg_report("FTCreateMapping request (pMemData == NULL).\n"); + +	// +	// A FileMapping is used to create 'shared memory' between the FTClient and the FTServer. +	// +	// Try to create a FileMapping to the Shared Memory. This is done to check if it's already there (what +	// may mean the face-tracker program is already running). +	// +	// If one already exists: close it and open the file-mapping to the existing one. +	// +	hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 ,  +		                           sizeof( TFreeTrackData ),  +								   (LPCSTR) FT_MM_DATA ); + +	if ( ( hFTMemMap != 0 ) && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) { +		dbg_report("FTCreateMapping: Mapping already exists.\n"); +		bMappingExists = TRUE;				// So the server was (probably) already started! +		CloseHandle( hFTMemMap ); +		hFTMemMap = 0; +	} + +	// +	// Create a new FileMapping, Read/Write access +	// +	hFTMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , FALSE , (LPCSTR) FT_MM_DATA ); +	if ( ( hFTMemMap != 0 ) ) { +		dbg_report("FTCreateMapping: Mapping opened.\n"); +		pMemData = (TFreeTrackData *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof( TFreeTrackData ) ); +	    hFTMutex = CreateMutexA(NULL, FALSE, FREETRACK_MUTEX); +	} +	else { +		return FALSE; +	} +	return TRUE; +} + +// +// Destory the FileMapping to the shared memory +// +#pragma comment(linker, "/export:FTDestroyMapping@0=FTDestroyMapping") +FT_EXPORT(void) FTDestroyMapping(void) +{ +	if ( pMemData != NULL ) { +		UnmapViewOfFile ( pMemData ); +	} +	 +	CloseHandle( hFTMutex ); +	CloseHandle( hFTMemMap ); +	pMemData = 0; +	hFTMemMap = 0; +} + +// +// 4 convenience +// +float getDegreesFromRads ( float rads ) {  +	return (rads * 57.295781f);  +} + +// +// Scale the measured value to the TIR values +// +float scale2AnalogLimits( float x, float min_x, float max_x ) { +double y; +double local_x; +	 +	local_x = x; +	if (local_x > max_x) { +		local_x = max_x; +	} +	if (local_x < min_x) { +		local_x = min_x; +	} +	y = ( NP_AXIS_MAX * local_x ) / max_x; + +	return (float) y; +} diff --git a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui index fc5abbcf..34873c76 100644 --- a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui +++ b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui @@ -6,22 +6,16 @@     <rect>
      <x>0</x>
      <y>0</y>
 -    <width>645</width>
 -    <height>416</height>
 +    <width>411</width>
 +    <height>112</height>
     </rect>
    </property>
 -  <property name="minimumSize">
 -   <size>
 -    <width>645</width>
 -    <height>0</height>
 -   </size>
 -  </property>
    <property name="windowTitle">
 -   <string>FreeTrack 2.0 settings FaceTrackNoIR</string>
 +   <string>FreeTrack settings FaceTrackNoIR</string>
    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/freetrack.png</normaloff>images/freetrack.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 @@ -31,282 +25,7 @@    </property>
    <layout class="QVBoxLayout" name="_vertical_layout">
     <item>
 -    <layout class="QVBoxLayout" name="verticalLayout_2">
 -     <item>
 -      <widget class="QGroupBox" name="groupBox">
 -       <property name="minimumSize">
 -        <size>
 -         <width>0</width>
 -         <height>70</height>
 -        </size>
 -       </property>
 -       <property name="title">
 -        <string>TIRViews</string>
 -       </property>
 -       <widget class="QCheckBox" name="chkTIRViews">
 -        <property name="geometry">
 -         <rect>
 -          <x>80</x>
 -          <y>30</y>
 -          <width>88</width>
 -          <height>17</height>
 -         </rect>
 -        </property>
 -        <property name="layoutDirection">
 -         <enum>Qt::RightToLeft</enum>
 -        </property>
 -        <property name="text">
 -         <string>Use TIRViews</string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_4">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>10</y>
 -          <width>421</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>TIRViews is only required for some older games (like CFS3). For it to work, TIRViews.dll</string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_5">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>30</y>
 -          <width>421</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>must be placed in the FaceTrackNoIR program folder. If the checkbox is disabled, the</string>
 -        </property>
 -        <property name="wordWrap">
 -         <bool>true</bool>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_6">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>50</y>
 -          <width>411</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>the DLL was not found. You can get it from NaturalPoint.</string>
 -        </property>
 -       </widget>
 -      </widget>
 -     </item>
 -     <item>
 -      <widget class="QGroupBox" name="groupBox_2">
 -       <property name="minimumSize">
 -        <size>
 -         <width>0</width>
 -         <height>70</height>
 -        </size>
 -       </property>
 -       <property name="title">
 -        <string>TrackIR.exe</string>
 -       </property>
 -       <widget class="QCheckBox" name="chkStartDummy">
 -        <property name="geometry">
 -         <rect>
 -          <x>20</x>
 -          <y>30</y>
 -          <width>145</width>
 -          <height>17</height>
 -         </rect>
 -        </property>
 -        <property name="layoutDirection">
 -         <enum>Qt::RightToLeft</enum>
 -        </property>
 -        <property name="text">
 -         <string>Start dummy TrackIR.exe</string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_3">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>10</y>
 -          <width>351</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Some programs check, to see if a process called TrackIR.exe is running,</string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>30</y>
 -          <width>261</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>before enabling head-tracking (EZCA is one of them).</string>
 -        </property>
 -        <property name="wordWrap">
 -         <bool>true</bool>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_7">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>50</y>
 -          <width>231</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Check the checkbox, to overcome this problem.</string>
 -        </property>
 -       </widget>
 -      </widget>
 -     </item>
 -     <item>
 -      <widget class="QGroupBox" name="groupBox_3">
 -       <property name="minimumSize">
 -        <size>
 -         <width>0</width>
 -         <height>70</height>
 -        </size>
 -       </property>
 -       <property name="title">
 -        <string>Select interface</string>
 -       </property>
 -       <widget class="QLabel" name="label_8">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>10</y>
 -          <width>351</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Some games support both FreeTrack and TrackIR and may get confused,</string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_2">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>30</y>
 -          <width>261</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>when both interfaces are visible.</string>
 -        </property>
 -        <property name="wordWrap">
 -         <bool>true</bool>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_9">
 -        <property name="geometry">
 -         <rect>
 -          <x>189</x>
 -          <y>50</y>
 -          <width>381</width>
 -          <height>16</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Try to disable one interface, if you experience problems.</string>
 -        </property>
 -       </widget>
 -       <widget class="QComboBox" name="cbxSelectInterface">
 -        <property name="geometry">
 -         <rect>
 -          <x>6</x>
 -          <y>30</y>
 -          <width>168</width>
 -          <height>22</height>
 -         </rect>
 -        </property>
 -       </widget>
 -      </widget>
 -     </item>
 -     <item>
 -      <widget class="QGroupBox" name="groupBox_4">
 -       <property name="minimumSize">
 -        <size>
 -         <width>0</width>
 -         <height>70</height>
 -        </size>
 -       </property>
 -       <property name="title">
 -        <string>Repair NPClient location</string>
 -       </property>
 -       <widget class="QLabel" name="label_10">
 -        <property name="geometry">
 -         <rect>
 -          <x>188</x>
 -          <y>10</y>
 -          <width>381</width>
 -          <height>20</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Users who use other software with an NPClient DLL (like TrackIR, FreeTrack or </string>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_11">
 -        <property name="geometry">
 -         <rect>
 -          <x>184</x>
 -          <y>30</y>
 -          <width>411</width>
 -          <height>20</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string> GlovePIE) may need to repair the location of the DLL, after running FaceTrackNoIR.</string>
 -        </property>
 -        <property name="wordWrap">
 -         <bool>true</bool>
 -        </property>
 -       </widget>
 -       <widget class="QLabel" name="label_12">
 -        <property name="geometry">
 -         <rect>
 -          <x>187</x>
 -          <y>50</y>
 -          <width>391</width>
 -          <height>20</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Use this button to locate the desired NPClient DLL.</string>
 -        </property>
 -       </widget>
 -       <widget class="QPushButton" name="bntLocateNPClient">
 -        <property name="geometry">
 -         <rect>
 -          <x>4</x>
 -          <y>30</y>
 -          <width>171</width>
 -          <height>23</height>
 -         </rect>
 -        </property>
 -        <property name="text">
 -         <string>Locate DLL</string>
 -        </property>
 -       </widget>
 -      </widget>
 -     </item>
 +    <layout class="QHBoxLayout">
       <item>
        <spacer name="horizontalSpacer_3">
         <property name="orientation">
 @@ -336,6 +55,17 @@      </spacer>
     </item>
     <item>
 +    <layout class="QVBoxLayout" name="verticalLayout">
 +     <item>
 +      <widget class="QLabel" name="label_2">
 +       <property name="text">
 +        <string>There are no settings necessary for the FreeTrack protocol.</string>
 +       </property>
 +      </widget>
 +     </item>
 +    </layout>
 +   </item>
 +   <item>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <spacer name="horizontalSpacer_2">
 diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp index b8461993..1482d76c 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp @@ -3,7 +3,7 @@  *					gamers from Holland, who don't like to pay much for			*
  *					head-tracking.												*
  *																				*
 -* Copyright (C) 2013	Wim Vriend (Developing)									*
 +* Copyright (C) 2010	Wim Vriend (Developing)									*
  *						Ron Hendriks (Researching and Testing)					*
  *																				*
  * Homepage																		*
 @@ -26,10 +26,6 @@  ********************************************************************************/
  /*
  	Modifications (last one on top):
 -	20130209 - WVR: Some games support both interfaces and cause trouble. Added ComboBox to fix this (hide one interface 
 -					by clearing the appropriate Registry-setting).
 -	20130203 - WVR: Added Tirviews and dummy checkboxes to the Settings dialog. This is necessary for CFS3 etc.
 -	20130125 - WVR: Upgraded to FT2.0: now the FreeTrack protocol supports all TIR-enabled games.
  	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
 @@ -39,154 +35,48 @@  					Now it works direcly in shared memory!
  */
  #include "ftnoir_protocol_ft.h"
 -#include "csv.h"
 +#include "facetracknoir/global-settings.h"
  /** constructor **/
  FTNoIR_Protocol::FTNoIR_Protocol()
  {
  	comhandle = 0;
 -	useTIRViews	= false;
 -	useDummyExe	= false;
 -	intUsedInterface = 0;
 -
 -	//
 -	// Load the INI-settings.
 -	//
  	loadSettings();
 -
  	ProgramName = "";
 -	intGameID = 0;
 -
 -	dummyTrackIR = 0;
 -	viewsStart = 0;
 -	viewsStop = 0;
 -
  }
  /** destructor **/
  FTNoIR_Protocol::~FTNoIR_Protocol()
  {
 -
 -	qDebug()<< "~FTNoIR_Protocol: Destructor started.";
 -
  	//
 -	// Stop if started
 -	//
 -	if (viewsStop != NULL) {
 -		qDebug()<< "~FTNoIR_Protocol: Stopping TIRViews.";
 -		viewsStop();
 -		FTIRViewsLib.unload();
 -	}
 -
 -	//
 -	// Kill the dummy TrackIR process.
 +	// Destroy the File-mapping
  	//
 -	qDebug() << "~FTNoIR_Protocol() about to kill TrackIR.exe process";
 -	try {
 -		if (dummyTrackIR) {
 -			qDebug() << "FTServer::~FTServer() about to kill TrackIR.exe process";
 -//			dummyTrackIR->close();
 -			dummyTrackIR->kill();
 -		}
 -	} 
 -	catch (...)
 -    {
 -		qDebug() << "~FTServer says: some error occurred";
 -	}
 +	FTDestroyMapping();
  	//
 -	// Destroy the File-mapping
 +	// Free the DLL's
  	//
 -	FTDestroyMapping();
 +	//////FTClientLib.unload();
  }
 -void FTNoIR_Protocol::Initialize()
 +/** helper to Auto-destruct **/
 +void FTNoIR_Protocol::Release()
  {
 -	return;
 +    delete this;
  }
 -//
 -// Read the game-data from CSV
 -//
 -bool FTNoIR_Protocol::getGameData( QString gameID ){
 -QStringList gameLine;
 -
 -	qDebug() << "getGameData, ID = " << gameID;
 -
 -	//
 -	// Open the supported games list, to get the Name.
 -	//
 -	QFile file(QCoreApplication::applicationDirPath() + "/Settings/FaceTrackNoIR Supported Games.csv");
 -	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
 -		QString strError( "Cannot load file: FaceTrackNoIR Supported Games.csv" );
 -		sprintf_s(pMemData->ProgramName, 99, strError.toAscii());
 -		sprintf_s(pMemData->FTNVERSION, 9, "V160");
 -
 -		//
 -		// Return true anyway, because maybe it's V160 compatible.
 -		//
 -		return true;
 -	}
 -	CSV csv(&file);
 -	gameLine = csv.parseLine();
 -	
 -	while (gameLine.count() > 2) {
 -		//qDebug() << "Column 0: " << gameLine.at(0);		// No.
 -		//qDebug() << "Column 1: " << gameLine.at(1);		// Game Name
 -		//qDebug() << "Column 2: " << gameLine.at(2);		// Game Protocol
 -		//qDebug() << "Column 3: " << gameLine.at(3);		// Supported since version
 -		//qDebug() << "Column 4: " << gameLine.at(4);		// Verified
 -		//qDebug() << "Column 5: " << gameLine.at(5);		// By
 -		//qDebug() << "Column 6: " << gameLine.at(6);		// International ID
 -		//qDebug() << "Column 7: " << gameLine.at(7);		// FaceTrackNoIR ID
 -		
 -		//
 -		// If the gameID was found, fill the shared memory
 -		//
 -		if (gameLine.count() > 6) {
 -			if (gameLine.at(6).compare( gameID, Qt::CaseInsensitive ) == 0) {
 -				if (pMemData != NULL) {		
 -					sprintf_s(pMemData->ProgramName, 99, gameLine.at(1).toAscii());
 -					sprintf_s(pMemData->FTNVERSION, 9, gameLine.at(3).toAscii());
 -					sprintf_s(pMemData->FTNID, 24, gameLine.at(7).toAscii());
 -				}
 -				file.close();
 -				return true;
 -			}
 -		}
 -
 -		gameLine = csv.parseLine();
 -	}
 -
 -	//
 -	// If the gameID was NOT found, fill only the name "Unknown game connected"
 -	//
 -	QString strUnknown("Unknown game connected (ID = " + gameID + ")");
 -	sprintf_s(pMemData->ProgramName, 99, strUnknown.toAscii());
 -	file.close();
 -	return true;
 +void FTNoIR_Protocol::Initialize()
 +{
 +	QSettings settings("NaturalPoint", "NATURALPOINT\\NPClient Location"); 
 +	QString aLocation =  QCoreApplication::applicationDirPath() + "/";
 +	if (QFile::exists( aLocation + "/npclient.dll" ))
 +		settings.setValue( "Path" , aLocation );
  }
  //
  // Load the current Settings from the currently 'active' INI-file.
  //
  void FTNoIR_Protocol::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 ( "FT" );
 -	intUsedInterface = iniFile.value ( "UsedInterface", 0 ).toInt();
 -	iniFile.endGroup ();
 -
 -	//
 -	// Use the settings-section from the deprecated fake-TIR protocol, as they are most likely to be found there.
 -	//
 -	iniFile.beginGroup ( "FTIR" );
 -	useTIRViews	= iniFile.value ( "useTIRViews", 0 ).toBool();
 -	useDummyExe	= iniFile.value ( "useDummyExe", 1 ).toBool();
 -	iniFile.endGroup ();
  }
  //
 @@ -209,10 +99,7 @@ float headRotX;  float headRotY;
  float headRotZ;
 -PDWORD_PTR MsgResult = 0;
 -
 -
 -	//
 +    //
  	// Scale the Raw measurements to the client measurements.
  	//
  	headRotX = getRadsFromDegrees(headpose->pitch);
 @@ -265,145 +152,82 @@ PDWORD_PTR MsgResult = 0;  		pMemData->data.Y3 = 0;
  		pMemData->data.Y4 = 0;
 -		//
 -		// Check if the handle that was sent to the Game, was changed (on x64, this will be done by the ED-API)
 -		// If the "Report Program Name" command arrives (which is a '1', for now), raise the event from here!
 -		//
 -		if (hMainWindow != pMemData->handle) {			// Handle in memory-mapping was changed!
 -			comhandle = (__int32) pMemData->handle;		// Get the command from the Game.
 -			if (comhandle == 1) {						// "Report Program Name"
 -				SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult);
 -				pMemData->handle = 0;					// Reset the command, to enable future commands...
 -			}
 -		}
 +		//qDebug() << "FTServer says: pMemData.DataID =" << pMemData->data.DataID;
 +		//qDebug() << "FTServer says: ProgramName =" << pMemData->ProgramName;
  		//
 -		// The game-ID was changed?
 -		//
 -		QString gameID = QString(pMemData->GameID);
 -	//QString gameID = QString("9999");
 -
 -//		qDebug() << "sendHeadposeToGame: gameID = " << gameID;
 -		if (gameID.length() > 0) {
 -			if ( gameID.toInt() != intGameID ) {
 -				if (getGameData( gameID ) ) {
 -					SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult);
 -				}
 -				intGameID = gameID.toInt();
 -			}
 -		}
 -		else {
 -			intGameID = 0;
 -			pMemData->ProgramName[0] = NULL;
 -			pMemData->FTNID[0] = NULL;
 -			pMemData->FTNVERSION[0] = NULL;
 -		}
 -
  		ReleaseMutex(hFTMutex);
  	}
 -	pMemData->data.DataID += 1;
 +    if (pMemData)
 +        pMemData->data.DataID += 1;
  }
  //
 -// Set the Path variables and load the memory-mapping.
 -// Simplified function: No need to check if the DLL's actually exist. The are installed by the installer.
 -// If they are absent, something went terribly wrong anyway...
 -//
 +// Check if the Client DLL exists and load it (to test it), if so.
  // Returns 'true' if all seems OK.
  //
 -//
 -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
 -	QSettings settings("Freetrack", "FreetrackClient");							// Registry settings (in HK_USER)
 -	QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location");	// Registry settings (in HK_USER)
 -	QString aLocation;															// Location of Client DLL
 +	QSettings settings("Freetrack", "FreetrackClient");				// Registry settings (in HK_USER)
 +	QString aLocation;												// Location of Client DLL
 +	QString aFileName;												// File Path and Name
 -	qDebug() << "checkServerInstallationOK says: Starting Function";
 +	qDebug() << "FTCheckClientDLL says: Starting Function";
  	try {
  		//
 -		// Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s).
 +		// Load the FreeTrackClient.dll from the current path of FaceTrackNoIR, because there is no
 +		// guarantee FreeTrack is also installed.
 +		//
 +		// Write this path in the registry (under FreeTrack/FreeTrackClient, for the game(s).
  		//
  		aLocation =  QCoreApplication::applicationDirPath() + "/";
 -
 -		qDebug() << "checkServerInstallationOK says: used interface = " << intUsedInterface;
 -		switch (intUsedInterface) {
 -			case 0:									// Use both interfaces
 -				settings.setValue( "Path" , aLocation );
 -				settingsTIR.setValue( "Path" , aLocation );
 -				break;
 -			case 1:									// Use FreeTrack, disable TrackIR
 -				settings.setValue( "Path" , aLocation );
 -				settingsTIR.setValue( "Path" , "" );
 -				break;
 -			case 2:									// Use TrackIR, disable FreeTrack
 -				settings.setValue( "Path" , "" );
 -				settingsTIR.setValue( "Path" , aLocation );
 -				break;
 -			default:
 -				// should never be reached
 -			break;
 -		}
 +		qDebug() << "FTCheckClientDLL says: Location of DLL =" << aLocation;
  		//
 -		// TIRViews must be started first, or the NPClient DLL will never be loaded.
 +		// Append a '/' to the Path and then the name of the dll.
  		//
 -		if (useTIRViews) {
 -
 -			QString aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll";
 -			if ( QFile::exists( aFileName ) ) {
 -
 -				FTIRViewsLib.setFileName(aFileName);
 -				FTIRViewsLib.load();
 -
 -				viewsStart = (importTIRViewsStart) FTIRViewsLib.resolve("TIRViewsStart");
 -				if (viewsStart == NULL) {
 -					qDebug() << "FTServer::run() says: TIRViewsStart function not found in DLL!";
 -				}
 -				else {
 -					qDebug() << "FTServer::run() says: TIRViewsStart executed!";
 -					viewsStart();
 -				}
 -
 -				//
 -				// Load the Stop function from TIRViews.dll. Call it when terminating the thread.
 -				//
 -				viewsStop = (importTIRViewsStop) FTIRViewsLib.resolve("TIRViewsStop");
 -				if (viewsStop == NULL) {
 -					qDebug() << "FTServer::run() says: TIRViewsStop function not found in DLL!";
 -				}
 -			}
 +		aFileName = aLocation;
 +		aFileName.append(FT_CLIENT_FILENAME);
 +		qDebug() << "FTCheckClientDLL says: Full path of DLL =" << aFileName;
 +						
 +		if ( QFile::exists( aFileName ) ) {
 +			qDebug() << "FTCheckClientDLL says: DLL exists!";
 +			//
 +			// Write the path to the key in the Registry, so the game(s) can find it too...
 +			//
 +			settings.setValue( "Path" , aLocation );
 +
 +			//
 +			// Load the DLL and map to the functions in it.
 +			//
 +			////////FTClientLib.setFileName(aFileName);
 +			////////FTClientLib.load();
 +			////////provider = (importProvider) FTClientLib.resolve("FTProvider");
 +			////////if (provider) {
 +			////////	pProvider = provider();
 +			////////	qDebug() << "FTCheckClientDLL says: Provider =" << pProvider;
 +			////////}
  		}
 -
 -		//
 -		// Check if TIRViews or dummy TrackIR.exe is required for this game
 -		//
 -		if (useDummyExe) {
 -			QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe";
 -			dummyTrackIR = new QProcess();
 -			dummyTrackIR->start(program);
 -
 -			qDebug() << "FTServer::run() says: TrackIR.exe executed!";
 +		else {
 +			QMessageBox::information(0, "FaceTrackNoIR error", QString("Necessary file (FreeTrackClient.dll) was NOT found!\n"));
 +			return false;
  		}
 -
 -
  	} catch(...) {
  		settings.~QSettings();
  	}
 -	return FTCreateMapping( handle );
 +    return FTCreateMapping();
  }
  //
 -// Create a memory-mapping to the FreeTrack data.
 +// Create a memory-mapping to the TrackIR data.
  // It contains the tracking data, a handle to the main-window and the program-name of the Game!
  //
  //
 -bool FTNoIR_Protocol::FTCreateMapping( HANDLE handle )
 +bool FTNoIR_Protocol::FTCreateMapping()
  {
 -bool bFirst = false;
 -
  	qDebug() << "FTCreateMapping says: Starting Function";
  	//
 @@ -413,18 +237,14 @@ bool bFirst = false;  	// If one already exists: close it.
  	//
  	hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , 
 -//		                           sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, 
 -		                           sizeof( FTMemMap ), 
 +		                           sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, 
  								   (LPCSTR) FT_MM_DATA );
  	if ( hFTMemMap != 0 ) {
 -		bFirst = true;
  		qDebug() << "FTCreateMapping says: FileMapping Created!" << hFTMemMap;
  	}
  	if ( ( hFTMemMap != 0 ) && ( (long) GetLastError == ERROR_ALREADY_EXISTS ) ) {
 -		bFirst = false;
 -		qDebug() << "FTCreateMapping says: FileMapping already exists!" << hFTMemMap;
  		CloseHandle( hFTMemMap );
  		hFTMemMap = 0;
  	}
 @@ -435,16 +255,7 @@ bool bFirst = false;  	hFTMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , false , (LPCSTR) FT_MM_DATA );
  	if ( ( hFTMemMap != 0 ) ) {
  		qDebug() << "FTCreateMapping says: FileMapping Opened:" << hFTMemMap;
 -		pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, 
 -//					sizeof(TFreeTrackData) + sizeof(hFTMemMap) + 100);
 -					sizeof(FTMemMap));
 -		if (pMemData != NULL) {
 -			if (bFirst) {
 -				memset(pMemData, 0, sizeof(FTMemMap));			// Write zero's, if first...
 -			}
 -			pMemData->handle = handle;	// The game uses the handle, to send a message that the Program-Name was set!
 -			hMainWindow = handle;
 -		}
 +		pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TFreeTrackData) + sizeof(hFTMemMap) + 100);
  	    hFTMutex = CreateMutexA(NULL, false, FREETRACK_MUTEX);
  	}
  	else {
 @@ -481,7 +292,7 @@ void FTNoIR_Protocol::FTDestroyMapping()  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "FreeTrack interface");
 +    sprintf(dest, "FreeTrack interface");
  	qDebug() << "FTNoIR_Protocol::getNameFromGame says: Started, pMemData = " << pMemData << ", mutex = " << hFTMutex;
 @@ -491,7 +302,7 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //	if ( (pMemData != NULL) && (WaitForSingleObject(hFTMutex, 100) == WAIT_OBJECT_0) ) {
  	if (pMemData != NULL) {
  		qDebug() << "FTNoIR_Protocol::getNameFromGame says: Inside MemData";
 -		sprintf_s(dest, 99, "%s", pMemData->ProgramName);
 +        sprintf(dest, "%s", pMemData->ProgramName);
  	}
  	return;
 @@ -505,9 +316,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Protocol;
 +    return (IProtocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.h b/ftnoir_protocol_ft/ftnoir_protocol_ft.h index c82c3e79..690984a4 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.h +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.h @@ -28,21 +28,21 @@  #ifndef INCLUDED_FTSERVER_H
  #define INCLUDED_FTSERVER_H
 -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h"
 -#include "ui_FTNoIR_FTcontrols.h"
 -#include "FTTypes.h"
 +#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
 +#include "ui_ftnoir_ftcontrols.h"
 +#include "fttypes.h"
  #include <QMessageBox>
  #include <QSettings>
  #include <QLibrary>
  #include <QProcess>
  #include <QDebug>
  #include <QFile>
 -#include "Windows.h"
 +#include <windows.h>
 +// todo wine glue
  //#include "math.h"
 +#include "facetracknoir/global-settings.h"
 -//typedef char *(WINAPI *importProvider)(void);
 -typedef void (WINAPI *importTIRViewsStart)(void);
 -typedef void (WINAPI *importTIRViewsStop)(void);
 +typedef char *(WINAPI *importProvider)(void);
  class FTNoIR_Protocol : public IProtocol
  {
 @@ -53,35 +53,25 @@ public:  	void Release();
      void Initialize();
 -	bool checkServerInstallationOK( HANDLE handle );
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );					// Take care dest can handle up to 100 chars...
  private:
 -	bool FTCreateMapping(HANDLE handle);
 +    bool FTCreateMapping();
  	void FTDestroyMapping();
 -	importTIRViewsStart viewsStart;						// Functions inside TIRViews.dll
 -	importTIRViewsStop viewsStop;
 -
  	HANDLE hFTMemMap;
  	FTMemMap *pMemData;
  	HANDLE hFTMutex;
 -	HANDLE hMainWindow;									// Save the handle to FaceTrackNoIR main-window
  	__int32 comhandle;									// Handle on x32, command on x64
  	// Private properties
  	QString ProgramName;
 -	QLibrary FTIRViewsLib;
 -	QProcess *dummyTrackIR;
 -	int intGameID;
 -	int intUsedInterface;								// Determine which interface to use (or to hide from the game)
 -	bool useTIRViews;									// Needs to be in the Settings dialog
 -	bool useDummyExe;
 +	QLibrary FTClientLib;
  	float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); }
 -	bool getGameData( QString gameID );
  	void loadSettings();
  };
 @@ -115,27 +105,25 @@ private:  	FTNoIR_Protocol *theProtocol;
  private slots:
 -	void selectDLL();
  	void doOK();
  	void doCancel();
  	void settingChanged() { settingsDirty = true; };
 -	void settingChanged(int) { settingsDirty = true; };
  };
  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
  	~FTNoIR_ProtocolDll();
 -	void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); };
 -	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); };
 -	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Enhanced FreeTrack protocol"); };
 +	void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); };
 +	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); };
 +	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack protocol"); };
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/Freetrack.ico"); };
 +    void getIcon(QIcon *icon) { *icon = QIcon(":/images/freetrack.png"); };
  };
 diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp index 2e6c91f7..46dd263f 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp @@ -32,7 +32,7 @@  */
  #include "ftnoir_protocol_ft.h"
  #include <QDebug>
 -#include <QFileDialog>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -51,36 +51,12 @@ QWidget()  	// Connect Qt signals to member-functions
  	connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
  	connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
 -	connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL()));
 -	connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(settingChanged()));
 -	connect(ui.chkStartDummy, SIGNAL(stateChanged(int)), this, SLOT(settingChanged()));
 -	connect(ui.cbxSelectInterface, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int )));
 -
 -	ui.cbxSelectInterface->addItem("Enable both");
 -	ui.cbxSelectInterface->addItem("Use FreeTrack, hide TrackIR");
 -	ui.cbxSelectInterface->addItem("Use TrackIR, hide FreeTrack");
 +//	connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(chkTIRViewsChanged()));
  	theProtocol = NULL;
  	// Load the settings from the current .INI-file
  	loadSettings();
 -
 -
 -	aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll";
 -	if ( !QFile::exists( aFileName ) ) {
 -		ui.chkTIRViews->setChecked( false );
 -		ui.chkTIRViews->setEnabled ( false );
 -
 -		//
 -		// Best do this save() last, or it will continually reset the settings... :-(
 -		//
 -		save();
 -	}
 -	else {
 -		ui.chkTIRViews->setEnabled ( true );
 -	}
 -
 -
  }
  //
 @@ -90,6 +66,11 @@ FTControls::~FTControls() {  	qDebug() << "~FTControls() says: started";
  }
 +void FTControls::Release()
 +{
 +    delete this;
 +}
 +
  //
  // Initialize tracker-client-dialog
  //
 @@ -161,12 +142,7 @@ void FTControls::loadSettings() {  	qDebug() << "loadSettings says: iniFile = " << currentFile;
  	iniFile.beginGroup ( "FT" );
 -	ui.cbxSelectInterface->setCurrentIndex( iniFile.value ( "UsedInterface", 0 ).toInt() );
 -	iniFile.endGroup ();
 -
 -	iniFile.beginGroup ( "FTIR" );
 -	ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool());
 -	ui.chkStartDummy->setChecked (iniFile.value ( "useDummyExe", 1 ).toBool());
 +//	ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool());
  	iniFile.endGroup ();
  	settingsDirty = false;
 @@ -182,44 +158,12 @@ void FTControls::save() {  	QSettings iniFile( currentFile, QSettings::IniFormat );		// Application settings (in INI-file)
  	iniFile.beginGroup ( "FT" );
 -	iniFile.setValue ( "UsedInterface", ui.cbxSelectInterface->currentIndex());
 -	iniFile.endGroup ();
 -
 -	iniFile.beginGroup ( "FTIR" );
 -	iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() );
 -	iniFile.setValue ( "useDummyExe", ui.chkStartDummy->isChecked() );
 +//	iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() );
  	iniFile.endGroup ();
  	settingsDirty = false;
  }
 -//
 -// Select a NPClient.dll file, to repair the Location in the Registry.
 -// Several program distribute their own version of this file.
 -//
 -void FTControls::selectDLL() {
 -	QFileDialog::Options options;
 -	QFileDialog::FileMode mode;
 -
 -    options |= QFileDialog::DontUseNativeDialog;
 -	mode = QFileDialog::ExistingFile;
 -    QString selectedFilter;
 -	QString fileName = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)"));
 -
 -	//
 -	// Write the location of the file in the required Registry-key.
 -	//
 -	if (! fileName.isEmpty() ) {
 -		if (fileName.endsWith("NPClient.dll", Qt::CaseInsensitive) ) {
 -			QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location");			// Registry settings (in HK_USER)
 -			QString aLocation = fileName.left(fileName.length() - 12);							// Location of Client DLL
 -
 -			settingsTIR.setValue( "Path" , aLocation );
 -		}
 -	}
 -}
 -
 -
  ////////////////////////////////////////////////////////////////////////////////
  // Factory function that creates instances if the Protocol-settings dialog object.
 @@ -227,9 +171,9 @@ void FTControls::selectDLL() {  //   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")
 +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new FTControls;
 +    return (IProtocolDialog*) new FTControls;
  }
 diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp index 4513c6ba..1209e38b 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_ft.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   GetProtocolDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
 -	return new FTNoIR_ProtocolDll;
 +    return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_ft/fttypes.h b/ftnoir_protocol_ft/fttypes.h index 1f389711..3f411cfe 100644 --- a/ftnoir_protocol_ft/fttypes.h +++ b/ftnoir_protocol_ft/fttypes.h @@ -4,7 +4,7 @@  *					It was loosely translated from FTTypes.pas					*
  *					which was created by the FreeTrack-team.					*
  *																				*
 -* Copyright (C) 2013	Wim Vriend (Developing)									*
 +* Copyright (C) 2010	Wim Vriend (Developing)									*
  *						Ron Hendriks (Testing and Research)						*
  *																				*
  * Homepage				<http://www.free-track.net>								*
 @@ -25,26 +25,23 @@  * We would like to extend our grattitude to the creators of SweetSpotter,		*
  * which has become the basis of this program: "Great work guys!"				*
  ********************************************************************************/
 -/*
 -	Modifications (last one on top):
 -	20130125 - WVR: Upgraded to FT2.0: now the FreeTrack protocol supports all TIR-enabled games. The memory-mapping was expanded for this purpose.
 -*/
  #pragma once
  #ifndef INCLUDED_FTTYPES_H
  #define INCLUDED_FTTYPES_H
 -#include "Windows.h" 
 +#include <windows.h>
  #include <tchar.h>
  #include <stdio.h>
  //#include "Registry.h"
  //  static const char* FT_CLIENT_LOCATION = "Software\\Freetrack\\FreetrackClient";
 -  static const char* FT_CLIENT_FILENAME = "FreeTrackClient.Dll";
 -  static const char* FT_MM_DATA = "FT_SharedMem";
 -  static const char* FREETRACK = "Freetrack";
 -  static const char* FREETRACK_MUTEX = "FT_Mutext";
 -  static const char* FT_PROGRAMID = "FT_ProgramID";
 +
 +#define FT_CLIENT_FILENAME "FreeTrackClient.Dll"
 +#define FT_MM_DATA "FT_SharedMem"
 +#define FREETRACK "Freetrack"
 +#define FREETRACK_MUTEX "FT_Mutext"
 +#define FT_PROGRAMID "FT_ProgramID"
  struct TFreeTrackData {
 @@ -85,20 +82,10 @@ struct FTMemMap {  #else
  	HANDLE handle;
  #endif
 -    char ProgramName[100];		// The name of the game
 -	char GameID[10];			// The international game-ID
 -	char FTNID[30];				// The FaceTrackNoIR game-ID
 -	char FTNVERSION[10];		// The version of FaceTrackNoIR, in which the game was first supported
 +    char ProgramName[100];
  };
  typedef FTMemMap * PFTMemMap;
 -//extern bool (*FTGetData) (PFreetrackData data); 
 -// DLL function signatures
 -// These match those given in FTTypes.pas
 -// WINAPI is macro for __stdcall defined somewhere in the depths of windows.h
 -typedef bool (WINAPI *importGetData)(TFreeTrackData * data);
 -typedef char *(WINAPI *importGetDllVersion)(void);
 -typedef void (WINAPI *importReportID)(int name);
 -typedef char *(WINAPI *importProvider)(void);
 +extern bool (*FTGetData) (PFreetrackData data); 
  #endif//INCLUDED_FTTYPES_H
 diff --git a/ftnoir_protocol_ft/images/freetrack.ico b/ftnoir_protocol_ft/images/freetrack.icoBinary files differ new file mode 100644 index 00000000..02554c3d --- /dev/null +++ b/ftnoir_protocol_ft/images/freetrack.ico diff --git a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui index 56983fbe..d8efec61 100644 --- a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui +++ b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/facetracknoir.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp index cfb6c618..26f331b3 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp @@ -33,36 +33,27 @@  */
  #include "ftnoir_protocol_ftn.h"
  #include <QFile>
 +#include "facetracknoir/global-settings.h"
  /** constructor **/
  FTNoIR_Protocol::FTNoIR_Protocol()
  {
  	loadSettings();
 +    outSocket = 0;
  }
  /** destructor **/
  FTNoIR_Protocol::~FTNoIR_Protocol()
  {
 -	if (inSocket != 0) {
 -		inSocket->close();
 -		delete inSocket;
 -	}
 -	
  	if (outSocket != 0) {
  		outSocket->close();
  		delete outSocket;
  	}
  }
 -/** helper to Auto-destruct **/
 -void FTNoIR_Protocol::Release()
 -{
 -    delete this;
 -}
 -
  void FTNoIR_Protocol::Initialize()
  {
 -	return;
 +    loadSettings();
  }
  //
 @@ -88,15 +79,13 @@ void FTNoIR_Protocol::loadSettings() {  //
  void FTNoIR_Protocol::sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose ) {
  int no_bytes;
 -QHostAddress sender;
 -quint16 senderPort;
 +THeadPoseData TestData;
  	//
  	// Copy the Raw measurements directly to the client.
  	//
 -	frame_counter += 1;
  	TestData = *headpose;
 -	TestData.frame_number = frame_counter;
 +    TestData.frame_number = 0;
  	//
  	// Try to send an UDP-message to the receiver
 @@ -112,63 +101,14 @@ quint16 senderPort;  			qDebug() << "FTNServer::writePendingDatagrams says: nothing sent!";
  		}
  	}
 -
 -	//
 -	// Receiver may send 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() << "FTNServer::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::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
 -	// Init. the data
 -	TestData.x = 0.0f;
 -	TestData.y = 0.0f;
 -	TestData.z = 0.0f;
 -	TestData.yaw = 0.0f;
 -	TestData.pitch = 0.0f;
 -	TestData.roll = 0.0f;
 -	fg_cmd = 1;
 -
 -	inSocket = 0;
 -	outSocket = 0;
 -
 -	frame_counter = 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, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
 -			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();
  	}
 @@ -181,7 +121,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "FaceTrackNoIR");
 +    sprintf(dest, "FaceTrackNoIR UDP");
  	return;
  }
 @@ -192,9 +132,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Protocol;
 +    return (IProtocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h index 24f760c5..7dca6842 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h @@ -29,15 +29,15 @@  #ifndef INCLUDED_FTNSERVER_H
  #define INCLUDED_FTNSERVER_H
 -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h"
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 -#include "ui_FTNoIR_FTNcontrols.h"
 +#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
 +#include "ui_ftnoir_ftncontrols.h"
  #include <QThread>
  #include <QUdpSocket>
  #include <QMessageBox>
  #include <QSettings>
 -#include "Windows.h"
 -#include "math.h"
 +#include <math.h>
 +#include "facetracknoir/global-settings.h"
  class FTNoIR_Protocol : public IProtocol
  {
 @@ -45,24 +45,17 @@ public:  	FTNoIR_Protocol();
  	~FTNoIR_Protocol();
 -	void Release();
      void Initialize();
 -	bool checkServerInstallationOK( HANDLE handle );
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );						// Take care dest can handle up to 100 chars...
  private:
 -	THeadPoseData TestData;
 -	long frame_counter;
 -	QUdpSocket *inSocket;									// Receive from FaceTrackNoIR
  	QUdpSocket *outSocket;									// Send to FaceTrackNoIR
 -	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.
 @@ -77,12 +70,8 @@ public:  	void Release();											// Member functions which are accessible from outside the DLL
      void Initialize(QWidget *parent);
 -	void registerProtocol(IProtocol *protocol) {
 -		theProtocol = (FTNoIR_Protocol *) protocol;			// Accept the pointer to the Protocol
 -	};
 -	void unRegisterProtocol() {
 -		theProtocol = NULL;									// Reset the pointer
 -	};
 +    void registerProtocol(IProtocol *protocol) {}
 +    void unRegisterProtocol() {}
  private:
  	Ui::UICFTNControls ui;
 @@ -91,28 +80,27 @@ private:  	/** helper **/
  	bool settingsDirty;
 -	FTNoIR_Protocol *theProtocol;
  private slots:
  	void doOK();
  	void doCancel();
 -	void settingChanged() { settingsDirty = true; };
 +    void settingChanged() { settingsDirty = true; }
  };
  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
  	~FTNoIR_ProtocolDll();
 -	void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR"); };
 -	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FTN Client"); };
 -	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR Client protocol"); };
 +    void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR"); }
 +    void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FTN Client"); }
 +    void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR Client protocol"); }
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/FaceTrackNoIR.ico"); };
 +    void getIcon(QIcon *icon) { *icon = QIcon(":/images/facetracknoir.png"); }
  };
  #endif//INCLUDED_FTNSERVER_H
 diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp index 58dbfbad..24ccc8b9 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_ftn.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -59,8 +60,6 @@ QWidget()  	connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged()));
  	connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged()));
 -	theProtocol = NULL;
 -
  	// Load the settings from the current .INI-file
  	loadSettings();
  }
 @@ -186,9 +185,9 @@ void FTNControls::save() {  //   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")
 +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new FTNControls;
 +    return (IProtocolDialog*) new FTNControls;
  }
 diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp index 00badedf..61f06914 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_ftn.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   GetProtocolDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_ftn/images/facetracknoir.ico b/ftnoir_protocol_ftn/images/facetracknoir.icoBinary files differ new file mode 100644 index 00000000..5115066c --- /dev/null +++ b/ftnoir_protocol_ftn/images/facetracknoir.ico diff --git a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui index 4a6cc3b9..1a7712f2 100644 --- a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui +++ b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset resource="Protocol.qrc">
 -    <normaloff>:/images/Mouse.ico</normaloff>:/images/Mouse.ico</iconset>
 +    <normaloff>:/images/Mouse.png</normaloff>:/images/Mouse.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp index f81a38f7..953482a5 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp @@ -33,6 +33,7 @@  					is called from run() of Tracker.cpp
  */
  #include "ftnoir_protocol_mouse.h"
 +#include "facetracknoir/global-settings.h"
  /** constructor **/
  FTNoIR_Protocol::FTNoIR_Protocol()
 @@ -106,9 +107,9 @@ void FTNoIR_Protocol::loadSettings() {  // Update Headpose in Game.
  //
  void FTNoIR_Protocol::sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose ) {
 -float fMouse_X;							// The actual value
 -float fMouse_Y;
 -float fMouse_Wheel;
 +float fMouse_X = 0;							// The actual value
 +float fMouse_Y = 0;
 +float fMouse_Wheel = 0;
  	//
 @@ -214,39 +215,6 @@ float fMouse_Wheel;  	}
  	//
 -	// Determine which style is used.
 -	//
 -	SecureZeroMemory(&MouseStruct, sizeof(MouseStruct));
 -	MouseStruct.type = INPUT_MOUSE;
 -	switch (Mouse_Style) {
 -		case FTN_ABSOLUTE:
 -			MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE;
 -			if (useVirtualDesk) {
 -				MouseStruct.mi.dwFlags |= MOUSEEVENTF_VIRTUALDESK;
 -			}
 -			MouseStruct.mi.dx = scale2AnalogLimits(-1.0f * fMouse_X * mouse_X_factor, -150, 150);
 -			MouseStruct.mi.dy = scale2AnalogLimits(fMouse_Y * mouse_Y_factor, -150, 150);
 -			MouseStruct.mi.mouseData = mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel);
 -
 -			frame_delay = 9999;					// Seems no problem with Absolute positioning
 -			break;
 -
 -		case FTN_RELATIVE:
 -			MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL;
 -			MouseStruct.mi.dx = -1.0f * mouse_X_factor * (fMouse_X - prev_fMouse_X);
 -			MouseStruct.mi.dy = mouse_Y_factor * (fMouse_Y - prev_fMouse_Y);
 -			MouseStruct.mi.mouseData = - 1.0f * mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel);
 -
 -			frame_delay += 1;					// Add 1 to the counter
 -			qDebug() << "sendHeadposeToGame(): FTN_RELATIVE x = " << MouseStruct.mi.dx << ", y = " << MouseStruct.mi.dy;
 -			break;
 -
 -		default:
 -			Mouse_Style = FTN_ABSOLUTE;			// Force to a valid value...
 -			break;
 -	}
 -
 -	//
  	// Only send Input, when it has changed.
  	// This releases the Mouse, when tracking is stopped (for a while).
  	//
 @@ -264,7 +232,7 @@ float fMouse_Wheel;  //
  // Returns 'true' if all seems OK.
  //
 -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
  	return true;
 @@ -275,7 +243,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "Mouse");
 +    sprintf(dest, "Mouse");
  	return;
  }
 @@ -286,9 +254,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Protocol;
 +    return (IProtocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h index b7765b96..e4bc6256 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h @@ -30,17 +30,17 @@  #ifndef INCLUDED_MOUSESERVER_H
  #define INCLUDED_MOUSESERVER_H
 -//#include <Windows.h>
 -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h"
 -#include "ui_FTNoIR_MOUSEcontrols.h"
 +#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
 +#include "ui_ftnoir_mousecontrols.h"
  #include <QMessageBox>
  #include <QSettings>
  #include <QLibrary>
  #include <QProcess>
  #include <QDebug>
  #include <QFile>
 -
 -#include "winable.h"
 +#include <windows.h>
 +#include <winuser.h>
 +#include "facetracknoir/global-settings.h"
  #define MOUSE_AXIS_MIN 0
  #define MOUSE_AXIS_MAX 65535
 @@ -69,7 +69,7 @@ public:  	void Release();
      void Initialize();
 -	bool checkServerInstallationOK( HANDLE handle );
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );					// Take care dest can handle up to 100 chars...
 @@ -133,7 +133,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
 @@ -143,7 +143,7 @@ public:  	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look"); };
  	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look protocol"); };
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/Mouse.ico"); };
 +    void getIcon(QIcon *icon) { *icon = QIcon(":/images/mouse.png"); };
  };
 diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp index b8d7d7ee..263be205 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp @@ -30,8 +30,9 @@  						The ProtocolDll class solves this.
  						The functions to get the name(s) and icon were removed from the two other classes.
  */
 -#include "ftnoir_protocol_MOUSE.h"
 +#include "ftnoir_protocol_mouse.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -227,9 +228,9 @@ void MOUSEControls::save() {  //   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")
 +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new MOUSEControls;
 +    return (IProtocolDialog*) new MOUSEControls;
  }
 diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp index cc6ddc17..219f62af 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp @@ -30,8 +30,9 @@  						The ProtocolDll class solves this.
  						The functions to get the name(s) and icon were removed from the two other classes.
  */
 -#include "ftnoir_protocol_MOUSE.h"
 +#include "ftnoir_protocol_mouse.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   GetProtocolDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_mouse/images/mouse.ico b/ftnoir_protocol_mouse/images/mouse.icoBinary files differ new file mode 100644 index 00000000..1151ab2b --- /dev/null +++ b/ftnoir_protocol_mouse/images/mouse.ico diff --git a/ftnoir_protocol_sc/ftnoir-protocol-sc.rc b/ftnoir_protocol_sc/ftnoir-protocol-sc.rc new file mode 100644 index 00000000..3838d941 --- /dev/null +++ b/ftnoir_protocol_sc/ftnoir-protocol-sc.rc @@ -0,0 +1,2 @@ +#include "winuser.h" +2 RT_MANIFEST scserver.manifest
\ No newline at end of file diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp index 7ca38e64..c01096bf 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp @@ -33,6 +33,7 @@  					is called from run() of Tracker.cpp
  */
  #include "ftnoir_protocol_sc.h"
 +#include "facetracknoir/global-settings.h"
  importSimConnect_CameraSetRelative6DOF FTNoIR_Protocol::simconnect_set6DOF;
  HANDLE FTNoIR_Protocol::hSimConnect = 0;			// Handle to SimConnect
 @@ -59,7 +60,6 @@ FTNoIR_Protocol::FTNoIR_Protocol()  	ProgramName = "Microsoft FSX";
  	blnSimConnectActive = false;
  	hSimConnect = 0;
 -	hMainWindow = 0;
  }
  /** destructor **/
 @@ -76,17 +76,6 @@ FTNoIR_Protocol::~FTNoIR_Protocol()  //	SCClientLib.unload(); Generates crash when tracker is ended...
  }
 -/** helper to Auto-destruct **/
 -void FTNoIR_Protocol::Release()
 -{
 -    delete this;
 -}
 -
 -void FTNoIR_Protocol::Initialize()
 -{
 -	return;
 -}
 -
  //
  // Load the current Settings from the currently 'active' INI-file.
  //
 @@ -101,7 +90,7 @@ void FTNoIR_Protocol::sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData  PDWORD_PTR MsgResult = 0;
 -	virtSCRotX = -1.0f * headpose->pitch;					// degrees
 +    virtSCRotX = -1.0f * headpose->pitch;					// degrees
  	virtSCRotY = -1.0f * headpose->yaw;
  	virtSCRotZ = headpose->roll;
 @@ -113,25 +102,22 @@ PDWORD_PTR MsgResult = 0;  	// It's only useful to send data, if the connection was made.
  	//
  	if (!blnSimConnectActive) {
 -		if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) {
 -			qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: SimConnect active!";
 +        if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) {
 +            qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: SimConnect active!";
 -			//set up the events we want to listen for
 -			HRESULT hr;
 +            //set up the events we want to listen for
 +            HRESULT hr;
 -			simconnect_subscribetosystemevent(hSimConnect, EVENT_PING, "Frame"); 
 +            simconnect_subscribetosystemevent(hSimConnect, EVENT_PING, "Frame");
 -			hr = simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, "");
 -			hr = simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false);
 -			hr = simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
 -			////hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "VK_COMMA", EVENT_INIT);
 -			////hr = SimConnect_SetInputGroupState(hSimConnect, INPUT0, SIMCONNECT_STATE_ON);
 +            hr = simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, "");
 +            hr = simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false);
 +            hr = simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
 +            ////hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "VK_COMMA", EVENT_INIT);
 +            ////hr = SimConnect_SetInputGroupState(hSimConnect, INPUT0, SIMCONNECT_STATE_ON);
 -			blnSimConnectActive = true;
 -			if (hMainWindow != NULL) {
 -				SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult);
 -			}
 -		}
 +            blnSimConnectActive = true;
 +        }
  	}
  	else {
  		//
 @@ -165,33 +151,29 @@ PDWORD_PTR MsgResult = 0;  //
  // Returns 'true' if all seems OK.
  //
 -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )
 +bool FTNoIR_Protocol::checkServerInstallationOK()
  {   
  	QString aFileName;														// File Path and Name
  	// Code to activate the context for the SimConnect DLL
 -	ACTCTX act = { 0 };
 +    ACTCTX act = { 0 };
  	HANDLE hctx;
  	ULONG_PTR ulCookie;
 -	hMainWindow = handle;
 -
  	qDebug() << "SCCheckClientDLL says: Starting Function";
  	try {
 -
 +#if 0
  		act.cbSize = sizeof(act);
  		act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
 +        char full_path[2048];
 +        strcpy(full_path, QCoreApplication::applicationDirPath().toLatin1().constData());
 +        strcat(full_path, "\\libftnoir-proto-simconnect.dll");
 -		QString manifest(QCoreApplication::applicationDirPath());
 -//		manifest += "\\FaceTrackNoIR.exe";
 -		manifest += "\\FTNoIR_Protocol_SC.dll";
 -		const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(manifest.utf16());
 -		
 -		act.lpSource = encodedName;
 -		act.lpResourceName = MAKEINTRESOURCE(101);
 +        act.lpSource = full_path;
 +        act.lpResourceName = MAKEINTRESOURCEA(101);
 -		hctx = CreateActCtx (&act);
 +        hctx = CreateActCtxA (&act);
  		if (hctx != INVALID_HANDLE_VALUE) { 
  			if (!ActivateActCtx(hctx, &ulCookie)) { 
 @@ -203,32 +185,26 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle )  			qDebug() << "SCCheckClientDLL says: Error INVALID_HANDLE: " << GetLastError();
  			return false;
  		}
 -
  		//
  		// Just try to load the DLL. Let Windows handle the PATH's and such trivialities...
  		//
 -		aFileName = SC_CLIENT_FILENAME;
 -						
 -		//
 -		// Load the DLL.
 -		//
 -		SCClientLib.setFileName(aFileName);
 -		if (SCClientLib.load() != true) {
 -			qDebug() << "SCCheckClientDLL says: Error loading SimConnect DLL";
 -			return false;
 -		}
 -
  		//
  		// Deactivate the context again: the function-references should stay in-tact...
  		//
  		DeactivateActCtx(0, ulCookie);
  		ReleaseActCtx(hctx);
 -
 +#endif
  	} catch(...) {
  		qDebug() << "SCCheckClientDLL says: Error loading SimConnect DLL";
  		return false;
  	}
 +    SCClientLib.setFileName(SC_CLIENT_FILENAME);
 +    if (SCClientLib.load() != true) {
 +        qDebug() << "SCCheckClientDLL says: Error loading SimConnect DLL";
 +        return false;
 +    }
 +
  	//
  	// Get the functions from the DLL.
  	//
 @@ -374,7 +350,7 @@ void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData  //
  void FTNoIR_Protocol::getNameFromGame( char *dest )
  {   
 -	sprintf_s(dest, 99, "Microsoft FSX");
 +    sprintf(dest, "Microsoft FSX");
  	return;
  }
 @@ -385,9 +361,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest )  //   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")
 +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Protocol;
 +    return (IProtocol*) new FTNoIR_Protocol;
  }
 diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.h b/ftnoir_protocol_sc/ftnoir_protocol_sc.h index 42eca457..57919193 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.h +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.h @@ -29,6 +29,7 @@  #pragma once
  #ifndef INCLUDED_SCSERVER_H
  #define INCLUDED_SCSERVER_H
 +#include "facetracknoir/global-settings.h"
  //
  // Prevent the SimConnect manifest from being merged in the application-manifest
 @@ -59,8 +60,7 @@ typedef HRESULT (WINAPI *importSimConnect_MapClientEventToSimEvent)(HANDLE hSimC  typedef HRESULT (WINAPI *importSimConnect_AddClientEventToNotificationGroup)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_CLIENT_EVENT_ID EventID, BOOL bMaskable);
  typedef HRESULT (WINAPI *importSimConnect_SetNotificationGroupPriority)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, DWORD uPriority);
 -static const char* SC_CLIENT_FILENAME = "SimConnect.dll";
 -static const char* FT_PROGRAMID = "FT_ProgramID";				// For message to FaceTrackNoIR main-window.
 +#define SC_CLIENT_FILENAME "SimConnect.dll"
  enum GROUP_ID
  {
 @@ -83,11 +83,8 @@ class FTNoIR_Protocol : public IProtocol  public:
  	FTNoIR_Protocol();
  	~FTNoIR_Protocol();
 -
 -	void Release();
 -    void Initialize();
 -
 -	bool checkServerInstallationOK( HANDLE handle );
 +    void Initialize() {}
 +    bool checkServerInstallationOK();
  	void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose );
  	void getNameFromGame( char *dest );					// Take care dest can handle up to 100 chars...
 @@ -112,10 +109,9 @@ private:  	static float prevSCRotY;
  	static float prevSCRotZ;
 -	bool blnSimConnectActive;
 -	HANDLE hMainWindow;												// Save the handle to FaceTrackNoIR main-window
 +    bool blnSimConnectActive;
 -	importSimConnect_Open simconnect_open;							// SimConnect function(s) in DLL
 +    importSimConnect_Open simconnect_open;							// SimConnect function(s) in DLL
  	importSimConnect_Close simconnect_close;
  	static importSimConnect_CameraSetRelative6DOF simconnect_set6DOF;
  	importSimConnect_CallDispatch simconnect_calldispatch;
 @@ -166,7 +162,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
  //*******************************************************************************************************
 -class FTNoIR_ProtocolDll : public IProtocolDll
 +class FTNoIR_ProtocolDll : public Metadata
  {
  public:
  	FTNoIR_ProtocolDll();
 @@ -176,7 +172,7 @@ public:  	void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("SimConnect"); };
  	void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft SimConnect protocol"); };
 -	void getIcon(QIcon *icon) { *icon = QIcon(":/images/FSX.ico"); };
 +    void getIcon(QIcon *icon) { *icon = QIcon(":/images/fsx.png"); };
  };
  #endif//INCLUDED_SCSERVER_H
 diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp index 9047fa61..32abf64a 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp @@ -30,8 +30,9 @@  						The ProtocolDll class solves this.
  						The functions to get the name(s) and icon were removed from the two other classes.
  */
 -#include "ftnoir_protocol_SC.h"
 +#include "ftnoir_protocol_sc.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -151,7 +152,7 @@ void SCControls::save() {  //   _GetProtocolDialog@0  - Common name decoration for __stdcall functions in C language.
  #pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( )
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new SCControls;
 +    return (IProtocolDialog*) new SCControls;
  }
 diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp index f67f95db..3d59ef48 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_protocol_SC.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
  }
 @@ -50,7 +51,7 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()  //   _GetProtocolDll@0  - Common name decoration for __stdcall functions in C language.
  #pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
 -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll()
 +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_ProtocolDll;
  }
 diff --git a/ftnoir_protocol_sc/ftnoir_sccontrols.ui b/ftnoir_protocol_sc/ftnoir_sccontrols.ui index 3e7a5062..a0cbf393 100644 --- a/ftnoir_protocol_sc/ftnoir_sccontrols.ui +++ b/ftnoir_protocol_sc/ftnoir_sccontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_protocol_sc/images/fsx.ico b/ftnoir_protocol_sc/images/fsx.icoBinary files differ new file mode 100644 index 00000000..1c71d409 --- /dev/null +++ b/ftnoir_protocol_sc/images/fsx.ico diff --git a/ftnoir_protocol_wine/images/wine.ico b/ftnoir_protocol_wine/images/wine.icoBinary files differ new file mode 100644 index 00000000..58edbb62 --- /dev/null +++ b/ftnoir_protocol_wine/images/wine.ico diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h index 396df4d1..416d3944 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base.h @@ -35,6 +35,9 @@  #include "ftnoir_tracker_types.h"
  #include <QtGui/QWidget>
  #include <QtGui/QFrame>
 +#include <QWaitCondition>
 +#include <QMutex>
 +#include <QFrame>
  ////////////////////////////////////////////////////////////////////////////////
  #ifdef __cplusplus
 @@ -52,29 +55,14 @@  struct ITracker
  {
      virtual ~ITracker() {}
 -	virtual void Initialize( QFrame *videoframe ) = 0;
 -	virtual void StartTracker( HWND parent_window ) = 0;
 -	virtual void StopTracker(bool exit) = 0;
 -	virtual bool GiveHeadPoseData(THeadPoseData *data) = 0;
 +    virtual void StartTracker( QFrame* frame ) = 0;
 +    virtual bool GiveHeadPoseData(THeadPoseData *data) = 0;
 -	virtual bool notifyZeroed() {
 -		return false;
 -	}
 -	virtual void refreshVideo() {}
 -	virtual void notifyCenter() {
 -		return;
 -	}
 +    virtual void WaitForExit() = 0;
  };
  typedef ITracker* ITrackerPtr;
 -// Factory function that creates instances of the Tracker object.
 -EXTERN_C
 -FTNOIR_TRACKER_BASE_EXPORT
 -ITrackerPtr
 -__stdcall
 -GetTracker(void);
 -
  ////////////////////////////////////////////////////////////////////////////////
  // COM-Like abstract interface.
  // This interface doesn't require __declspec(dllexport/dllimport) specifier.
 @@ -83,20 +71,12 @@ GetTracker(void);  // Instances are obtained via factory function.
  struct ITrackerDialog
  {
 -	virtual ~ITrackerDialog() {}
 +    virtual ~ITrackerDialog() {}
  	virtual void Initialize(QWidget *parent) = 0;
  	virtual void registerTracker(ITracker *tracker) = 0;
  	virtual void unRegisterTracker() = 0;
  };
 -typedef ITrackerDialog* ITrackerDialogPtr;
 -
 -// Factory function that creates instances of the Tracker object.
 -EXTERN_C
 -FTNOIR_TRACKER_BASE_EXPORT
 -ITrackerDialogPtr
 -__stdcall
 -GetTrackerDialog(void);
  ////////////////////////////////////////////////////////////////////////////////
  // COM-Like abstract interface.
 @@ -115,14 +95,5 @@ struct ITrackerDll  	virtual void getIcon(QIcon *icon) = 0;
  };
 -typedef ITrackerDll* ITrackerDllPtr;
 -
 -// Factory function that creates instances of the Tracker object.
 -EXTERN_C
 -FTNOIR_TRACKER_BASE_EXPORT
 -ITrackerDllPtr
 -__stdcall
 -GetTrackerDll(void);
 -
  #endif // FTNOIR_TRACKER_BASE_H
 diff --git a/ftnoir_tracker_base/ftnoir_tracker_base_global.h b/ftnoir_tracker_base/ftnoir_tracker_base_global.h index 9f4a6118..a449c282 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base_global.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base_global.h @@ -1,7 +1,7 @@  #ifndef FTNOIR_TRACKER_BASE_GLOBAL_H
  #define FTNOIR_TRACKER_BASE_GLOBAL_H
 -#include <Qt/qglobal.h>
 +#include <QtGlobal>
  #ifdef FTNOIR_TRACKER_BASE_LIB
  # define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT
 diff --git a/ftnoir_tracker_base/ftnoir_tracker_sm_types.h b/ftnoir_tracker_base/ftnoir_tracker_sm_types.h index a8802e4a..1faf893f 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_sm_types.h +++ b/ftnoir_tracker_base/ftnoir_tracker_sm_types.h @@ -1,10 +1,11 @@  //
  // Definitions for the Shared Memory to send the data to FaceTrackNoIR
  //
 -static const char* SM_MM_DATA = "SM_SharedMem";
 -static const char* SM_FACEAPI = "SM_FaceAPI";
 -static const char* SM_MUTEX = "SM_Mutex";
 +#define SM_MM_DATA "SM_SharedMem"
 +#define SM_FACEAPI "SM_FaceAPI"
 +#define SM_MUTEX "SM_Mutex"
 +#include "faceapi/stdafx.h"
  #include <sm_api.h>
  struct TFaceData {
 diff --git a/ftnoir_tracker_base/ftnoir_tracker_types.h b/ftnoir_tracker_base/ftnoir_tracker_types.h index ace7a6e3..ee443b95 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_types.h +++ b/ftnoir_tracker_base/ftnoir_tracker_types.h @@ -44,7 +44,7 @@ struct THeadPoseData {  		: x(x), y(y), z(z), yaw(yaw), pitch(pitch), roll(roll), frame_number(0) {}
  	double x, y, z, yaw, pitch, roll;
 -	long frame_number;
 +    unsigned char frame_number;
  };
  #pragma pack(pop)
 diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp index 336ede2d..5785b21a 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp @@ -1,13 +1,11 @@  #include "stdafx.h" -#include "../ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"  #include "headtracker-ftnoir.h"  #include "ftnoir_tracker_ht.h"  #include "ftnoir_tracker_ht_dll.h"  #include "ui_trackercontrols.h" -#include "../facetracknoir/global-settings.h" - -#define WIDGET_WIDTH 250 -#define WIDGET_HEIGHT 188 +#include "facetracknoir/global-settings.h" +#include <cmath>  #if defined(_WIN32) || defined(__WIN32)  #include <dshow.h> @@ -98,31 +96,48 @@ static void load_settings(ht_config_t* config, Tracker* tracker)  	QSettings iniFile( currentFile, QSettings::IniFormat );  	iniFile.beginGroup( "HT-Tracker" ); -	config->classification_delay = 4000; -	config->field_of_view = iniFile.value("fov", 69).toFloat(); +    config->classification_delay = 500; +    config->field_of_view = iniFile.value("fov", 52).toFloat();  	config->pyrlk_pyramids = 3; -	config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21; -	config->max_keypoints = 250; -	config->keypoint_quality = 12; -	config->keypoint_distance = 2.3f; -	config->keypoint_3distance = 6; -	//config->force_width = 640; -	//config->force_height = 480; -	config->force_fps = iniFile.value("fps", 0).toInt(); -	config->camera_index = iniFile.value("camera-index", -1).toInt(); -	config->ransac_num_iters = 100; -    config->ransac_max_reprojection_error = 6.5f; -    config->ransac_max_inlier_error = 6.5f; -    config->ransac_max_mean_error = 4.0f; -    config->ransac_abs_max_mean_error = 7.0f; -	config->debug = 0; -	config->ransac_min_features = 0.75f; +    config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21; +    config->max_keypoints = 300; +    config->keypoint_quality = 2; +    config->keypoint_distance = 2.5; +    config->keypoint_3distance = 6; +    //config->force_width = 640; +    //config->force_height = 480; +    config->force_fps = iniFile.value("fps", 0).toInt(); +    config->camera_index = iniFile.value("camera-index", -1).toInt(); +    config->ransac_num_iters = 100; +    config->ransac_max_reprojection_error = 3.63637; +    config->ransac_max_inlier_error = 3; +    config->ransac_max_mean_error = 3.5; +    config->ransac_abs_max_mean_error = 7; +    config->debug = 1; +    config->ransac_min_features = 0.80;      int res = iniFile.value("resolution", 0).toInt();      if (res < 0 || res >= (int)(sizeof(*resolution_choices) / sizeof(resolution_tuple)))  		res = 0;  	resolution_tuple r = resolution_choices[res];  	config->force_width = r.width; -	config->force_height = r.height; +    config->force_height = r.height; +    config->user_landmarks = iniFile.value("use-bashed-coords").toBool(); +    if (config->user_landmarks) +    { +        config->user_landmark_locations[0][0] = iniFile.value("b1").toDouble(); +        config->user_landmark_locations[1][0] = iniFile.value("b2").toDouble(); +        config->user_landmark_locations[2][0] = iniFile.value("b3").toDouble(); +        config->user_landmark_locations[0][1] = iniFile.value("b4").toDouble(); +        config->user_landmark_locations[1][1] = iniFile.value("b5").toDouble(); +        config->user_landmark_locations[2][1] = iniFile.value("b6").toDouble(); +        config->user_landmark_locations[0][2] = iniFile.value("b7").toDouble(); +        config->user_landmark_locations[1][2] = iniFile.value("b8").toDouble(); +        config->user_landmark_locations[2][2] = iniFile.value("b9").toDouble(); +        config->user_landmark_locations[0][3] = iniFile.value("b10").toDouble(); +        config->user_landmark_locations[1][3] = iniFile.value("b11").toDouble(); +        config->user_landmark_locations[2][3] = iniFile.value("b12").toDouble(); +    } +    qDebug() << "width" << r.width << "height" << r.height;  	if (tracker)  	{  		tracker->enableRX = iniFile.value("enable-rx", true).toBool(); @@ -159,7 +174,6 @@ Tracker::~Tracker()  void Tracker::StartTracker(QFrame* videoframe)  { -    videoframe->setAttribute(Qt::WA_NativeWindow);      videoframe->show();      videoWidget = new VideoWidget(videoframe);      QHBoxLayout* layout = new QHBoxLayout(); @@ -168,7 +182,6 @@ void Tracker::StartTracker(QFrame* videoframe)      if (videoframe->layout())          delete videoframe->layout();      videoframe->setLayout(layout); -    videoWidget->resize(WIDGET_WIDTH, WIDGET_HEIGHT);      videoWidget->show();      this->layout = layout;      load_settings(&shm->config, this); @@ -181,8 +194,8 @@ void Tracker::StartTracker(QFrame* videoframe)  #else      subprocess.start(QCoreApplication::applicationDirPath() + "/tracker-ht/headtracker-ftnoir");  #endif -    connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget())); -    timer.start(15); +    connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget()), Qt::QueuedConnection); +    timer.start(40);  }  void Tracker::paint_widget() { @@ -209,8 +222,12 @@ bool Tracker::GiveHeadPoseData(THeadPoseData* data)              data->yaw = shm->result.rotx;          if (enableRY)              data->pitch = shm->result.roty; -        if (enableRZ) +        if (enableRZ) {              data->roll = shm->result.rotz; +            double sign = data->roll >= 0 ? 1 : -1; +            if (fabs(fabs(data->roll) - 180) < fabs(data->roll)) +                data->roll = fabs(fabs(data->roll) - 180) * sign; +        }          if (enableTX)              data->x = shm->result.tx;          if (enableTY) @@ -227,7 +244,7 @@ bool Tracker::GiveHeadPoseData(THeadPoseData* data)  //-----------------------------------------------------------------------------  void TrackerDll::getFullName(QString *strToBeFilled)  { -	*strToBeFilled = "HT 0.7"; +    *strToBeFilled = "HT 0.8";  }  void TrackerDll::getShortName(QString *strToBeFilled) @@ -278,7 +295,6 @@ extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )  TrackerControls::TrackerControls()  {  	ui.setupUi(this); -	loadSettings();  	connect(ui.cameraName, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int)));  	connect(ui.cameraFPS, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int)));  	connect(ui.cameraFOV, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(double))); @@ -290,6 +306,7 @@ TrackerControls::TrackerControls()  	connect(ui.tz, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));  	connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(doCancel()));  	connect(ui.buttonOK, SIGNAL(clicked()), this, SLOT(doOK())); +    loadSettings();  	settingsDirty = false;  } @@ -303,6 +320,7 @@ void TrackerControls::showEvent(QShowEvent *event)  void TrackerControls::Initialize(QWidget* parent)  { +    loadSettings();  	show();  } @@ -343,6 +361,19 @@ void TrackerControls::loadSettings()  	ui.ty->setCheckState(iniFile.value("enable-ty", true).toBool() ? Qt::Checked : Qt::Unchecked);  	ui.tz->setCheckState(iniFile.value("enable-tz", true).toBool() ? Qt::Checked : Qt::Unchecked);      ui.resolution->setCurrentIndex(iniFile.value("resolution", 0).toInt()); +    ui.groupBox_2->setChecked(iniFile.value("use-bashed-coords").toBool()); +    ui.doubleSpinBox_1->setValue(iniFile.value("b1", 0).toDouble()); +    ui.doubleSpinBox_2->setValue(iniFile.value("b2", 0).toDouble()); +    ui.doubleSpinBox_3->setValue(iniFile.value("b3", 0).toDouble()); +    ui.doubleSpinBox_4->setValue(iniFile.value("b4", 0).toDouble()); +    ui.doubleSpinBox_5->setValue(iniFile.value("b5", 0).toDouble()); +    ui.doubleSpinBox_6->setValue(iniFile.value("b6", 0).toDouble()); +    ui.doubleSpinBox_7->setValue(iniFile.value("b7", 0).toDouble()); +    ui.doubleSpinBox_8->setValue(iniFile.value("b8", 0).toDouble()); +    ui.doubleSpinBox_9->setValue(iniFile.value("b9", 0).toDouble()); +    ui.doubleSpinBox_10->setValue(iniFile.value("b10", 0).toDouble()); +    ui.doubleSpinBox_11->setValue(iniFile.value("b11", 0).toDouble()); +    ui.doubleSpinBox_12->setValue(iniFile.value("b12", 0).toDouble());  	iniFile.endGroup();  	settingsDirty = false;  } @@ -381,6 +412,19 @@ void TrackerControls::save()  	iniFile.setValue("enable-ty", ui.ty->checkState() != Qt::Unchecked ? true : false);  	iniFile.setValue("enable-tz", ui.tz->checkState() != Qt::Unchecked ? true : false);  	iniFile.setValue("resolution", ui.resolution->currentIndex()); +    iniFile.setValue("b1", ui.doubleSpinBox_1->value()); +    iniFile.setValue("b2", ui.doubleSpinBox_2->value()); +    iniFile.setValue("b3", ui.doubleSpinBox_3->value()); +    iniFile.setValue("b4", ui.doubleSpinBox_4->value()); +    iniFile.setValue("b5", ui.doubleSpinBox_5->value()); +    iniFile.setValue("b6", ui.doubleSpinBox_6->value()); +    iniFile.setValue("b7", ui.doubleSpinBox_7->value()); +    iniFile.setValue("b8", ui.doubleSpinBox_8->value()); +    iniFile.setValue("b9", ui.doubleSpinBox_9->value()); +    iniFile.setValue("b10", ui.doubleSpinBox_10->value()); +    iniFile.setValue("b11", ui.doubleSpinBox_11->value()); +    iniFile.setValue("b12", ui.doubleSpinBox_12->value()); +    iniFile.setValue("use-bashed-coords", ui.groupBox_2->isChecked());  	iniFile.endGroup();  	settingsDirty = false;  } diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.h b/ftnoir_tracker_ht/ftnoir_tracker_ht.h index 1a449dca..f5d0c271 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 Stanislaw Halik <sthalik@misaki.pl> +/* Copyright (c) 2013 Stanis³aw Halik <sthalik@misaki.pl>   *   * Permission to use, copy, modify, and/or distribute this software for any   * purpose with or without fee is hereby granted, provided that the above @@ -9,11 +9,11 @@  #define FTNOIR_TRACKER_HT_H  #include "stdafx.h" -#include "../ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"  #include "headtracker-ftnoir.h"  #include "ui_trackercontrols.h"  #include "video_widget.h" -#include "../compat/compat.h" +#include "compat/compat.h"  #include <QObject>  #include <QTimer> diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h index f3bfd381..1e53f802 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h @@ -5,8 +5,8 @@   * copyright notice and this permission notice appear in all copies.   */ -#include "../ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "../facetracknoir/global-settings.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "facetracknoir/global-settings.h"  //-----------------------------------------------------------------------------  class TrackerDll : public Metadata diff --git a/ftnoir_tracker_ht/ht-api.h b/ftnoir_tracker_ht/ht-api.h index ac8d45cf..81caf16f 100644 --- a/ftnoir_tracker_ht/ht-api.h +++ b/ftnoir_tracker_ht/ht-api.h @@ -1,9 +1,9 @@  #pragma once  #ifndef HT_API  #ifndef __cplusplus -# define HT_EXTERN  +# define HT_EXTERN  #else -# define HT_EXTERN extern "C"  +# define HT_EXTERN extern "C"  #endif  #   if defined(_WIN32) && !defined(MINGW)  #     define HT_API(t) HT_EXTERN __declspec(dllexport) t __stdcall @@ -19,56 +19,58 @@ struct ht_context;  typedef struct ht_context headtracker_t;  typedef struct ht_config { -	float field_of_view; -	float classification_delay; -	int   pyrlk_pyramids; -	int   pyrlk_win_size_w; -	int   pyrlk_win_size_h; +    float field_of_view; +    float classification_delay; +    int   pyrlk_pyramids; +    int   pyrlk_win_size_w; +    int   pyrlk_win_size_h;      float ransac_max_inlier_error;      float ransac_max_reprojection_error; -	int   max_keypoints; +    int   max_keypoints;      int   keypoint_quality; -	float keypoint_distance; +    float keypoint_distance;      float keypoint_3distance;      int   force_width; -	int   force_height; -	int   force_fps; -	int   camera_index; -	bool  debug; +    int   force_height; +    int   force_fps; +    int   camera_index; +    bool  debug;      int   ransac_num_iters;      float ransac_min_features;      float ransac_max_mean_error;      float ransac_abs_max_mean_error; +    bool  user_landmarks; +    float user_landmark_locations[3][4];  } ht_config_t;  typedef struct {      double rotx, roty, rotz;      double tx, ty, tz; -	bool filled; +    bool filled;  } ht_result_t;  typedef enum { -	cfg_type_float = 0, -	cfg_type_int   = 1, -	cfg_type_bool  = 2, +    cfg_type_float = 0, +    cfg_type_int   = 1, +    cfg_type_bool  = 2,      cfg_type_double = 3  } ht_cfg_type_t;  typedef union  { -	double d; -	float f; -	int i; +    double d; +    float f; +    int i;  } ht_cfg_value_t;  typedef struct { -	const char* name; -	int offset; -	ht_cfg_type_t type; -	ht_cfg_value_t default_value; -	ht_cfg_value_t min; -	ht_cfg_value_t max; -	const char* docstring; +    const char* name; +    int offset; +    ht_cfg_type_t type; +    ht_cfg_value_t default_value; +    ht_cfg_value_t min; +    ht_cfg_value_t max; +    const char* docstring;  } ht_reflection_t;  typedef struct { diff --git a/ftnoir_tracker_ht/images/ht.ico b/ftnoir_tracker_ht/images/ht.icoBinary files differ new file mode 100644 index 00000000..7555ce25 --- /dev/null +++ b/ftnoir_tracker_ht/images/ht.ico diff --git a/ftnoir_tracker_ht/trackercontrols.ui b/ftnoir_tracker_ht/trackercontrols.ui index 0a1bc3ae..2f4b1915 100644 --- a/ftnoir_tracker_ht/trackercontrols.ui +++ b/ftnoir_tracker_ht/trackercontrols.ui @@ -9,19 +9,19 @@     <rect>      <x>0</x>      <y>0</y> -    <width>500</width> +    <width>724</width>      <height>160</height>     </rect>    </property>    <property name="sizePolicy"> -   <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> +   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">      <horstretch>0</horstretch>      <verstretch>0</verstretch>     </sizepolicy>    </property>    <property name="maximumSize">     <size> -    <width>500</width> +    <width>750</width>      <height>160</height>     </size>    </property> @@ -38,7 +38,7 @@      </rect>     </property>     <property name="text"> -    <string>Horizontal field of view</string> +    <string>Horizontal FOV</string>     </property>    </widget>    <widget class="QDoubleSpinBox" name="cameraFOV"> @@ -68,7 +68,7 @@      <rect>       <x>10</x>       <y>40</y> -     <width>101</width> +     <width>137</width>       <height>16</height>      </rect>     </property> @@ -111,7 +111,7 @@      <rect>       <x>10</x>       <y>70</y> -     <width>71</width> +     <width>133</width>       <height>16</height>      </rect>     </property> @@ -122,7 +122,7 @@    <widget class="QPushButton" name="buttonOK">     <property name="geometry">      <rect> -     <x>340</x> +     <x>220</x>       <y>130</y>       <width>75</width>       <height>23</height> @@ -135,7 +135,7 @@    <widget class="QPushButton" name="buttonCancel">     <property name="geometry">      <rect> -     <x>420</x> +     <x>300</x>       <y>130</y>       <width>75</width>       <height>23</height> @@ -251,7 +251,7 @@      <rect>       <x>10</x>       <y>100</y> -     <width>61</width> +     <width>128</width>       <height>16</height>      </rect>     </property> @@ -289,6 +289,289 @@      </property>     </item>    </widget> +  <widget class="QGroupBox" name="groupBox_2"> +   <property name="geometry"> +    <rect> +     <x>500</x> +     <y>10</y> +     <width>221</width> +     <height>141</height> +    </rect> +   </property> +   <property name="title"> +    <string>Bashed coordinates</string> +   </property> +   <property name="checkable"> +    <bool>true</bool> +   </property> +   <property name="checked"> +    <bool>false</bool> +   </property> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_1"> +    <property name="geometry"> +     <rect> +      <x>10</x> +      <y>20</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_2"> +    <property name="geometry"> +     <rect> +      <x>80</x> +      <y>20</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_3"> +    <property name="geometry"> +     <rect> +      <x>150</x> +      <y>20</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_6"> +    <property name="geometry"> +     <rect> +      <x>150</x> +      <y>50</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_4"> +    <property name="geometry"> +     <rect> +      <x>10</x> +      <y>50</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_5"> +    <property name="geometry"> +     <rect> +      <x>80</x> +      <y>50</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_9"> +    <property name="geometry"> +     <rect> +      <x>150</x> +      <y>80</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_7"> +    <property name="geometry"> +     <rect> +      <x>10</x> +      <y>80</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_8"> +    <property name="geometry"> +     <rect> +      <x>80</x> +      <y>80</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_12"> +    <property name="geometry"> +     <rect> +      <x>150</x> +      <y>110</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_11"> +    <property name="geometry"> +     <rect> +      <x>80</x> +      <y>110</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +   <widget class="QDoubleSpinBox" name="doubleSpinBox_10"> +    <property name="geometry"> +     <rect> +      <x>10</x> +      <y>110</y> +      <width>61</width> +      <height>22</height> +     </rect> +    </property> +    <property name="frame"> +     <bool>true</bool> +    </property> +    <property name="buttonSymbols"> +     <enum>QAbstractSpinBox::NoButtons</enum> +    </property> +    <property name="decimals"> +     <number>5</number> +    </property> +    <property name="minimum"> +     <double>-99.000000000000000</double> +    </property> +   </widget> +  </widget>   </widget>   <resources/>   <connections/> diff --git a/ftnoir_tracker_ht/video_widget.cpp b/ftnoir_tracker_ht/video_widget.cpp new file mode 100644 index 00000000..51d92967 --- /dev/null +++ b/ftnoir_tracker_ht/video_widget.cpp @@ -0,0 +1,69 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "video_widget.h" + +#include <QDebug> + +using namespace std; + +// ---------------------------------------------------------------------------- +void VideoWidget::initializeGL() +{ +	glClearColor(0.0, 0.0, 0.0, 0.0); +	glMatrixMode(GL_MODELVIEW); +	glLoadIdentity(); +} + +void VideoWidget::resizeGL(int w, int h) +{ +	// setup 1 to 1 projection +	glViewport(0, 0, w, h); +	glMatrixMode(GL_PROJECTION); +	glLoadIdentity(); +	glOrtho(0, w, 0, h, -1, 1); +    resize_frame(resized_qframe); +    glDisable(GL_DEPTH_TEST); +    glBegin(GL_QUADS); +    glVertex2f(0,0); +    glVertex2f(1,0); +    glVertex2f(1,1); +    glVertex2f(0,1); +    glEnd(); +} + +void VideoWidget::paintGL() +{ +    QMutexLocker lck(&mtx); +    if (resized_qframe.size() == size() || (resized_qframe.width() <= width() && resized_qframe.height() <= height())) +    { +        glDrawPixels(resized_qframe.width(), resized_qframe.height(), GL_RGB, GL_UNSIGNED_BYTE, resized_qframe.bits()); +    } +    else +        glClear(GL_DEPTH_BUFFER_BIT); +    glFlush(); +} + +void VideoWidget::resize_frame(QImage& qframe) +{ +    QMutexLocker lck(&mtx); +    if (qframe.size() == size() || (qframe.width() <= width() && qframe.height() <= height())) +        resized_qframe = qframe.copy(); +    else +        resized_qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation).copy(); +} + + +void VideoWidget::updateImage(unsigned char *frame, int width, int height) +{ +    QImage foo = QImage(frame, width, height, 3 * width, QImage::Format_RGB888).rgbSwapped().mirrored(); +    resize_frame(foo); +} + +void VideoWidget::update() { +    updateGL(); +} diff --git a/ftnoir_tracker_ht/video_widget.h b/ftnoir_tracker_ht/video_widget.h new file mode 100644 index 00000000..adc57335 --- /dev/null +++ b/ftnoir_tracker_ht/video_widget.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include <QGLWidget> +#include <QTime> +#include <QFrame> +#include <QImage> +#include <QWidget> +#include <QMutex> +#include <QMutexLocker> +// ---------------------------------------------------------------------------- +class VideoWidget : public QGLWidget +{ +	Q_OBJECT + +public: +    VideoWidget(QWidget *parent) : QGLWidget(parent) { +#if !defined(_WIN32) +        setAttribute(Qt::WA_NativeWindow, true); +#endif +	} + +	void initializeGL(); +	void resizeGL(int w, int h); +	void paintGL(); + +    void updateImage(unsigned char* frame, int width, int height); +    void update(); +private: +    void resize_frame(QImage& qframe); +    QImage resized_qframe; +    QMutex mtx; +}; + +#endif // VIDEOWIDGET_H diff --git a/ftnoir_tracker_pt/Resources/icon.ico b/ftnoir_tracker_pt/Resources/icon.icoBinary files differ new file mode 100644 index 00000000..c4b2aedc --- /dev/null +++ b/ftnoir_tracker_pt/Resources/icon.ico diff --git a/ftnoir_tracker_pt/camera.cpp b/ftnoir_tracker_pt/camera.cpp index fc11c738..96ba3b89 100644 --- a/ftnoir_tracker_pt/camera.cpp +++ b/ftnoir_tracker_pt/camera.cpp @@ -68,45 +68,33 @@ bool Camera::get_frame(float dt, cv::Mat* frame)  }
  // ----------------------------------------------------------------------------
 -/*
  void CVCamera::start()
  {
 -	cap = cvCreateCameraCapture(desired_index);
 -	// extract camera info
 -	if (cap)
 -	{
 -		active = true;
 -		active_index = desired_index;
 -		cam_info.res_x = cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH);
 -		cam_info.res_y = cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT);
 -	}
 +	cap = new VideoCapture(desired_index);
 +// extract camera info
 +    active = true;
 +    active_index = desired_index;
 +    cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
 +    cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
  }
  void CVCamera::stop()
  {
 -	if (cap) cvReleaseCapture(&cap);
 +	if (cap) {
 +        cap->release();
 +        delete cap;
 +        cap = NULL;
 +    }
  	active = false;
  }
  bool CVCamera::_get_frame(Mat* frame)
  {
 -    if (cap && cvGrabFrame(cap) != 0)
 -	{
 -		// retrieve frame
 -		IplImage* _img = cvRetrieveFrame(cap, 0);
 -		if(_img)
 -		{
 -			if(_img->origin == IPL_ORIGIN_TL)
 -				*frame = Mat(_img);
 -			else
 -			{
 -				Mat temp(_img);
 -				flip(temp, *frame, 0);
 -			}
 -			return true;
 -		}
 -	}
 -	return false;
 +    Mat tmp;
 +    bool ret = cap->read(tmp);
 +    if (ret)
 +        flip(tmp, *frame, 0);
 +    return ret;
  }
  void CVCamera::_set_index()
 @@ -121,21 +109,21 @@ void CVCamera::_set_f()  void CVCamera::_set_fps()
  {
 -	if (cap) cvSetCaptureProperty(cap, CV_CAP_PROP_FPS, cam_desired.fps);
 +	if (cap) cap->set(CV_CAP_PROP_FPS, cam_desired.fps);
  }
  void CVCamera::_set_res()
  {
  	if (cap)
  	{
 -		cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH,  cam_desired.res_x);
 -		cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y);
 -		cam_info.res_x = cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH);
 -		cam_info.res_y = cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT);
 +		cap->set(CV_CAP_PROP_FRAME_WIDTH,  cam_desired.res_x);
 +		cap->set(CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y);
 +		cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
 +		cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
  	}
  }
 -*/
 +#if 0
  // ----------------------------------------------------------------------------
  VICamera::VICamera() : frame_buffer(NULL)
  {
 @@ -223,4 +211,4 @@ void VICamera::_set_res()  {
  	if (active) restart();
  }
 -
 +#endif
 diff --git a/ftnoir_tracker_pt/camera.h b/ftnoir_tracker_pt/camera.h index cd1f0842..9977431b 100644 --- a/ftnoir_tracker_pt/camera.h +++ b/ftnoir_tracker_pt/camera.h @@ -9,7 +9,7 @@  #define CAMERA_H
  #include <opencv2/opencv.hpp>
 -#include "videoInput/videoInput.h"
 +//#include "videoInput/videoInput.h"
  // ----------------------------------------------------------------------------
  struct CamInfo
 @@ -27,7 +27,7 @@ struct CamInfo  class Camera
  {
  public:
 -	Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1), active(false) {}
 +    Camera() : desired_index(0), active_index(-1), active(false), dt_valid(0), dt_mean(0) {}
  	virtual ~Camera() {}
  	// start/stop capturing
 @@ -57,19 +57,19 @@ protected:  	virtual void _set_fps() = 0;
  	virtual void _set_res() = 0;
 +    int desired_index;
 +    int active_index;
  	bool active;
 -	int desired_index;
 -	int active_index;
 +    float dt_valid;
 +    float dt_mean;
  	CamInfo cam_info;
  	CamInfo cam_desired;
 -	float dt_valid;
 -	float dt_mean;
  };
  // ----------------------------------------------------------------------------
  // OpenCV camera
 -/*
 +
  class CVCamera : public Camera
  {
  public:
 @@ -86,12 +86,13 @@ protected:  	void _set_fps();
  	void _set_res();
 -	CvCapture* cap;
 +	cv::VideoCapture* cap;
  };
 -*/
 +
  // ----------------------------------------------------------------------------
  // videoInput camera
 +#if 0
  class VICamera : public Camera
  {
  public:
 @@ -112,5 +113,6 @@ protected:  	cv::Mat new_frame;
  	unsigned char* frame_buffer;
  };
 +#endif
  #endif //CAMERA_H
 diff --git a/ftnoir_tracker_pt/ftnoir_pt_controls.ui b/ftnoir_tracker_pt/ftnoir_pt_controls.ui index 0174df23..0934a4fb 100644 --- a/ftnoir_tracker_pt/ftnoir_pt_controls.ui +++ b/ftnoir_tracker_pt/ftnoir_pt_controls.ui @@ -9,7 +9,7 @@     <rect>
      <x>0</x>
      <y>0</y>
 -    <width>405</width>
 +    <width>451</width>
      <height>489</height>
     </rect>
    </property>
 @@ -23,8 +23,8 @@     <string>PointTracker Settings</string>
    </property>
    <property name="windowIcon">
 -   <iconset resource="ftnoir_tracker_pt.qrc">
 -    <normaloff>:/Resources/icon.ico</normaloff>:/Resources/icon.ico</iconset>
 +   <iconset>
 +    <normaloff>:/Resources/icon.png</normaloff>:/Resources/icon.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 @@ -54,7 +54,7 @@        <locale language="English" country="UnitedStates"/>
       </property>
       <property name="currentIndex">
 -      <number>0</number>
 +      <number>1</number>
       </property>
       <widget class="QWidget" name="tab">
        <attribute name="title">
 @@ -561,6 +561,9 @@                  <property name="toolTip">
                   <string>Desired capture framerate</string>
                  </property>
 +                <property name="maximum">
 +                 <number>300</number>
 +                </property>
                 </widget>
                </item>
               </layout>
 @@ -959,7 +962,7 @@                    <string/>
                   </property>
                   <property name="pixmap">
 -                  <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_side.png</pixmap>
 +                  <pixmap resource="ftnoir_tracker_pt.qrc">:/resources/clip_side.png</pixmap>
                   </property>
                  </widget>
                  <widget class="QSpinBox" name="clip_theight_spin">
 @@ -1082,7 +1085,7 @@                    <string/>
                   </property>
                   <property name="pixmap">
 -                  <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_front.png</pixmap>
 +                  <pixmap resource="ftnoir_tracker_pt.qrc">:/resources/clip_front.png</pixmap>
                   </property>
                  </widget>
                  <widget class="QLabel" name="label_53">
 @@ -1137,7 +1140,7 @@                    <string/>
                   </property>
                   <property name="pixmap">
 -                  <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_side.png</pixmap>
 +                  <pixmap resource="ftnoir_tracker_pt.qrc">:/resources/cap_side.png</pixmap>
                   </property>
                  </widget>
                  <widget class="QSpinBox" name="cap_height_spin">
 @@ -1247,7 +1250,7 @@                    <string/>
                   </property>
                   <property name="pixmap">
 -                  <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_front.png</pixmap>
 +                  <pixmap resource="ftnoir_tracker_pt.qrc">:/resources/cap_front.png</pixmap>
                   </property>
                  </widget>
                  <widget class="QSpinBox" name="cap_width_spin">
 @@ -1656,7 +1659,7 @@          <string/>
         </property>
         <property name="pixmap">
 -        <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/Logo_IR.png</pixmap>
 +        <pixmap resource="ftnoir_tracker_pt.qrc">:/resources/logo_ir.png</pixmap>
         </property>
        </widget>
       </widget>
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp index 5b77da69..db863e3a 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp @@ -11,23 +11,22 @@  #include <QDebug>
  #include <QFile>
  #include <QCoreApplication>
 +#include "facetracknoir/global-settings.h"
  using namespace std;
  using namespace cv;
 -using namespace boost;
  //#define PT_PERF_LOG	//log performance
  //-----------------------------------------------------------------------------
  Tracker::Tracker()
 -	: frame_count(0), commands(0), video_widget(NULL), tracking_valid(false)
 +    : tracking_valid(false), frame_count(0), commands(0), video_widget(NULL), fresh(false)
  {
 +    should_quit = false;
  	qDebug()<<"Tracker::Tracker";
  	TrackerSettings settings;
 -	settings.load_ini();
 +    settings.load_ini();
  	apply(settings);
 -	camera.start();
 -	start();
  }
  Tracker::~Tracker()
 @@ -66,8 +65,12 @@ void Tracker::run()  	forever
  	{
  		{	
 +            
 +            refreshVideo();
  			QMutexLocker lock(&mutex);
 -			
 +            if (should_quit)
 +                break;
 +
  			if (commands & ABORT) break;
  			if (commands & PAUSE) continue;
  			commands = 0;
 @@ -105,7 +108,7 @@ void Tracker::apply(const TrackerSettings& settings)  	point_extractor.threshold_val = settings.threshold;
  	point_extractor.min_size = settings.min_point_size;
  	point_extractor.max_size = settings.max_point_size;
 -	point_tracker.point_model = boost::shared_ptr<PointModel>(new PointModel(settings.M01, settings.M02));
 +	point_tracker.point_model = std::auto_ptr<PointModel>(new PointModel(settings.M01, settings.M02));
  	point_tracker.dynamic_pose_resolution = settings.dyn_pose_res;
  	sleep_time = settings.sleep_time;
  	point_tracker.dt_reset = settings.reset_time / 1000.0;
 @@ -138,57 +141,60 @@ void Tracker::center()  	X_CH_0 = X_CM_0 * X_MH;
  }
 -//-----------------------------------------------------------------------------
 -// ITracker interface
 -void Tracker::Initialize(QFrame *videoframe)
 -{
 -	const int VIDEO_FRAME_WIDTH = 252;
 -	const int VIDEO_FRAME_HEIGHT = 189;
 -
 -	qDebug("Tracker::Initialize");
 -	// setup video frame
 -	videoframe->setAttribute(Qt::WA_NativeWindow);
 -	videoframe->show();
 -	video_widget = new VideoWidget(videoframe);
 -	QHBoxLayout* layout = new QHBoxLayout();
 -	layout->setContentsMargins(0, 0, 0, 0);
 -	layout->addWidget(video_widget);
 -	if (videoframe->layout()) delete videoframe->layout();
 -	videoframe->setLayout(layout);
 -	video_widget->resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT);
 -}
 -
  void Tracker::refreshVideo()
  {	
  	if (video_widget)
  	{
  		Mat frame_copy;
 -		shared_ptr< vector<Vec2f> > points;
 +		std::auto_ptr< vector<Vec2f> > points;
  		{
  			QMutexLocker lock(&mutex);
  			if (!draw_frame || frame.empty()) return;
  			// copy the frame and points from the tracker thread
  			frame_copy = frame.clone();
 -			points = shared_ptr< vector<Vec2f> >(new vector<Vec2f>(point_extractor.get_points()));
 +			points = std::auto_ptr< vector<Vec2f> >(new vector<Vec2f>(point_extractor.get_points()));
  		}
 -		video_widget->update(frame_copy, points);
 +		video_widget->update_image(frame_copy, points);
 +        fresh = true;
  	}
  }
 -void Tracker::StartTracker(HWND parent_window)
 +void Tracker::StartTracker(QFrame* videoframe)
  {
 +    const int VIDEO_FRAME_WIDTH = 252;
 +    const int VIDEO_FRAME_HEIGHT = 189;
 +    TrackerSettings settings;
 +    settings.load_ini();
 +    apply(settings);
 +    camera.start();
 +    start();
 +    qDebug("Tracker::Initialize");
 +    // setup video frame
 +    video_widget = new VideoWidget(videoframe);
 +    QHBoxLayout* layout = new QHBoxLayout();
 +    layout->setContentsMargins(0, 0, 0, 0);
 +    layout->addWidget(video_widget);
 +    if (videoframe->layout()) delete videoframe->layout();
 +    videoframe->setLayout(layout);
 +    video_widget->resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT);
 +    videoframe->show();
  	reset_command(PAUSE);
 +    connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget()), Qt::QueuedConnection);
 +    timer.start(40);
  }
 -void Tracker::StopTracker(bool exit)
 -{
 -	set_command(PAUSE);
 +void Tracker::paint_widget() {
 +    if (fresh) {
 +        fresh = false;
 +        video_widget->update();
 +    }
  }
  bool Tracker::GiveHeadPoseData(THeadPoseData *data)
  {
 +    refreshVideo();
  	const float rad2deg = 180.0/3.14159265;
  	const float deg2rad = 1.0/rad2deg;
  	{
 @@ -249,9 +255,9 @@ bool Tracker::GiveHeadPoseData(THeadPoseData *data)  }
  //-----------------------------------------------------------------------------
 -#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 +//#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new Tracker;
 -}
\ No newline at end of file +    return (ITracker*) new Tracker;
 +}
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.h b/ftnoir_tracker_pt/ftnoir_tracker_pt.h index 2533a39b..49881b69 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.h @@ -8,7 +8,7 @@  #ifndef FTNOIR_TRACKER_PT_H
  #define FTNOIR_TRACKER_PT_H
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
  #include "ftnoir_tracker_pt_settings.h"
  #include "camera.h"
  #include "point_extractor.h"
 @@ -20,18 +20,19 @@  #include <QMutex>
  #include <QTime>
  #include <opencv2/opencv.hpp>
 +#include <QFrame>
 +#include <QTimer>
  //-----------------------------------------------------------------------------
 -class Tracker : public ITracker, QThread
 +class Tracker : public QThread, public ITracker
  {
 +    Q_OBJECT
  public:
  	Tracker();
  	~Tracker();
  	// ITracker interface
 -	void Initialize(QFrame *videoframe);
 -	void StartTracker(HWND parent_window);
 -	void StopTracker(bool exit);
 +    void StartTracker(QFrame* videoFrame);
  	bool GiveHeadPoseData(THeadPoseData *data);
  	void refreshVideo();
 @@ -40,6 +41,10 @@ public:  	void center();
  	void reset();	// reset the trackers internal state variables
  	void run();
 +    void WaitForExit() {
 +        should_quit = true;
 +        wait();
 +    }
  	void get_pose(FrameTrafo* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.get_pose(); }
  	int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); }
 @@ -47,8 +52,6 @@ public:  protected:	
  	FrameTrafo X_CH_0; // for centering
 -
 -	QMutex mutex;
  	cv::Mat frame;	// the output frame for display
  	enum Command {
 @@ -57,9 +60,8 @@ protected:  	};
  	void set_command(Command command);
  	void reset_command(Command command);
 -	int commands;
 -	VICamera camera;
 +    CVCamera camera;
  	PointExtractor point_extractor;
  	PointTracker point_tracker;
  	bool tracking_valid;
 @@ -78,9 +80,17 @@ protected:  	bool bEnableZ;
  	long frame_count;
 +    int commands;
  	VideoWidget* video_widget;
  	Timer time;
 +    QMutex mutex;
 +    volatile bool should_quit;
 +    volatile bool fresh;
 +    QTimer timer;
 +    
 +protected slots:
 +    void paint_widget();
  };
  #endif // FTNOIR_TRACKER_PT_H
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp index a1531dd7..c1067ba7 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp @@ -9,10 +9,11 @@  #include <QMessageBox>
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  //-----------------------------------------------------------------------------
  TrackerDialog::TrackerDialog()
 -	: settings_dirty(false), tracker(NULL), timer(this), trans_calib_running(false)
 +    : settings_dirty(false), tracker(NULL), trans_calib_running(false), timer(this)
  {
  	qDebug()<<"TrackerDialog::TrackerDialog";
  	setAttribute(Qt::WA_DeleteOnClose, false);
 @@ -328,9 +329,9 @@ void TrackerDialog::unRegisterTracker()  }
  //-----------------------------------------------------------------------------
 -#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 +//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( )
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new TrackerDialog;
 -}
\ No newline at end of file +    return (ITrackerDialog*) new TrackerDialog;
 +}
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h index 0f836dfe..28120692 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h @@ -8,10 +8,10 @@  #ifndef FTNOIR_TRACKER_PT_DIALOG_H
  #define FTNOIR_TRACKER_PT_DIALOG_H
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
  #include "ftnoir_tracker_pt_settings.h"
  #include "ftnoir_tracker_pt.h"
 -#include "ui_FTNoIR_PT_Controls.h"
 +#include "ui_ftnoir_pt_controls.h"
  #include "trans_calib.h"
  #include <QTimer>
 @@ -99,4 +99,4 @@ protected:  	Ui::UICPTClientControls ui;
  };
 -#endif //FTNOIR_TRACKER_PT_DIALOG_H
\ No newline at end of file +#endif //FTNOIR_TRACKER_PT_DIALOG_H
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp index 7f58d77d..22c4a33d 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp @@ -6,8 +6,8 @@   */
  #include "ftnoir_tracker_pt_dll.h"
 -
  #include <QIcon>
 +#include "facetracknoir/global-settings.h"
  //-----------------------------------------------------------------------------
  void TrackerDll::getFullName(QString *strToBeFilled)
 @@ -27,14 +27,14 @@ void TrackerDll::getDescription(QString *strToBeFilled)  void TrackerDll::getIcon(QIcon *icon)
  {
 -	*icon = QIcon(":/Resources/icon.ico");
 +    *icon = QIcon(":/resources/icon.png");
  }
  //-----------------------------------------------------------------------------
 -#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 +//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new TrackerDll;
  }
 diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h index 15ad63aa..f684c55b 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h @@ -5,10 +5,11 @@   * copyright notice and this permission notice appear in all copies.
   */
 -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
 +#include "facetracknoir/global-settings.h"
  //-----------------------------------------------------------------------------
 -class TrackerDll : public ITrackerDll
 +class TrackerDll : public Metadata
  {
  	// ITrackerDll interface
  	void Initialize() {}
 @@ -16,4 +17,4 @@ class TrackerDll : public ITrackerDll  	void getShortName(QString *strToBeFilled);
  	void getDescription(QString *strToBeFilled);
  	void getIcon(QIcon *icon);
 -};
\ No newline at end of file +};
 diff --git a/ftnoir_tracker_pt/point_extractor.cpp b/ftnoir_tracker_pt/point_extractor.cpp index 4aa1a658..b6e9ad3a 100644 --- a/ftnoir_tracker_pt/point_extractor.cpp +++ b/ftnoir_tracker_pt/point_extractor.cpp @@ -11,6 +11,14 @@  using namespace cv;
  using namespace std;
 +struct BlobInfo
 +{
 +    BlobInfo() : m00(0), m10(0), m01(0) {}
 +    long m00;
 +    long m10;
 +    long m01;
 +};
 +
  // ----------------------------------------------------------------------------
  const vector<Vec2f>& PointExtractor::extract_points(Mat frame, float dt, bool draw_output)
  {
 @@ -39,13 +47,6 @@ const vector<Vec2f>& PointExtractor::extract_points(Mat frame, float dt, bool dr  	// find connected components...
  	// extract blobs with floodfill
 -	struct BlobInfo
 -	{
 -		BlobInfo() : m00(0), m10(0), m01(0) {}
 -		long m00;
 -		long m10;
 -		long m01;
 -	};
  	vector<BlobInfo> blobs;
      int blob_count = 1;
 diff --git a/ftnoir_tracker_pt/point_tracker.cpp b/ftnoir_tracker_pt/point_tracker.cpp index d617de19..c08d6d83 100644 --- a/ftnoir_tracker_pt/point_tracker.cpp +++ b/ftnoir_tracker_pt/point_tracker.cpp @@ -14,7 +14,6 @@  #include <QDebug>
  using namespace cv;
 -using namespace boost;
  using namespace std;
  const float PI = 3.14159265358979323846f;
 @@ -68,26 +67,27 @@ PointModel::PointModel(Vec3f M01, Vec3f M02)  	get_d_order(points, d_order);
  }
 +static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b)
 +{
 +    return a.first < b.first;
 +}
 +
  void PointModel::get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const
  {
  	// get sort indices with respect to d scalar product
  	vector< pair<float,int> > d_vals;
 -	for (int i = 0; i<points.size(); ++i)
 +    for (int i = 0; i<(int)points.size(); ++i)
  		d_vals.push_back(pair<float, int>(d.dot(points[i]), i));
 -	struct
 -	{
 -		bool operator()(const pair<float, int>& a, const pair<float, int>& b) { return a.first < b.first; }
 -	} comp;
 -	sort(d_vals.begin(), d_vals.end(), comp);
 +    sort(d_vals.begin(), d_vals.end(), d_vals_sort);
 -	for (int i = 0; i<points.size(); ++i)
 +    for (int i = 0; i<(int)points.size(); ++i)
  		d_order[i] = d_vals[i].second;
  }
  // ----------------------------------------------------------------------------
 -PointTracker::PointTracker() : init_phase(true), dt_valid(0), dt_reset(1), v_t(0,0,0), v_r(0,0,0), dynamic_pose_resolution(true)
 +PointTracker::PointTracker() : dynamic_pose_resolution(true), dt_reset(1), init_phase(true), dt_valid(0), v_t(0,0,0), v_r(0,0,0)
  {
  	X_CM.t[2] = 1000;	// default position: 1 m away from cam;
  }
 @@ -120,7 +120,7 @@ bool PointTracker::track(const vector<Vec2f>& points, float f, float dt)  	}
  	// if there is a pointtracking problem, reset the velocities
 -	if (!point_model || points.size() != PointModel::N_POINTS) 
 +    if (!point_model.get() || (int) points.size() != PointModel::N_POINTS)
  	{
  		//qDebug()<<"Wrong number of points!";
  		reset_velocities();
 @@ -141,7 +141,7 @@ bool PointTracker::track(const vector<Vec2f>& points, float f, float dt)  		return false;
  	}
 -	int n_iter = POSIT(f);
 +    (void) POSIT(f);
  	//qDebug()<<"Number of POSIT iterations: "<<n_iter;
  	if (!init_phase)
 diff --git a/ftnoir_tracker_pt/point_tracker.h b/ftnoir_tracker_pt/point_tracker.h index 21baad19..7eee580d 100644 --- a/ftnoir_tracker_pt/point_tracker.h +++ b/ftnoir_tracker_pt/point_tracker.h @@ -8,8 +8,8 @@  #ifndef POINTTRACKER_H
  #define POINTTRACKER_H
 +#include <memory>
  #include <opencv2/opencv.hpp>
 -#include <boost/shared_ptr.hpp>
  #include <list>
  // ----------------------------------------------------------------------------
 @@ -76,7 +76,7 @@ public:  	// f : (focal length)/(sensor width)
  	// dt : time since last call
  	bool track(const std::vector<cv::Vec2f>& points, float f, float dt);
 -	boost::shared_ptr<PointModel> point_model;
 +	std::auto_ptr<PointModel> point_model;
  	bool dynamic_pose_resolution;
  	float dt_reset;
 diff --git a/ftnoir_tracker_pt/timer.cpp b/ftnoir_tracker_pt/timer.cpp index 363b5b09..9e6ca8b8 100644 --- a/ftnoir_tracker_pt/timer.cpp +++ b/ftnoir_tracker_pt/timer.cpp @@ -55,8 +55,7 @@ double Timer::elapsed()      startTime = startCount.QuadPart * (1e3 / frequency.QuadPart);
      endTime = endCount.QuadPart * (1e3 / frequency.QuadPart);
  #else
 -    if(!stopped)
 -        gettimeofday(&endCount, NULL);
 +	(void) gettimeofday(&endCount, NULL);
      startTime = (startCount.tv_sec * 1e3) + startCount.tv_usec;
      endTime = (endCount.tv_sec * 1e3) + endCount.tv_usec;
 diff --git a/ftnoir_tracker_pt/video_widget.cpp b/ftnoir_tracker_pt/video_widget.cpp index c2b41da1..c297c455 100644 --- a/ftnoir_tracker_pt/video_widget.cpp +++ b/ftnoir_tracker_pt/video_widget.cpp @@ -3,8 +3,6 @@   * Permission to use, copy, modify, and/or distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
 - *
 - * 20130312, WVR: Add 7 lines to resizeGL after resize_frame. This should lower CPU-load.
   */
  #include "video_widget.h"
 @@ -13,7 +11,6 @@  using namespace cv;
  using namespace std;
 -using namespace boost;
  // ----------------------------------------------------------------------------
  void VideoWidget::initializeGL()
 @@ -31,21 +28,20 @@ void VideoWidget::resizeGL(int w, int h)  	glLoadIdentity();
  	glOrtho(0, w, 0, h, -1, 1);
  	resize_frame();
 -	glDisable(GL_DEPTH_TEST);
 -	glBegin(GL_QUADS);
 -	glVertex2f(0,0);
 -	glVertex2f(1,0);
 -	glVertex2f(1,1);
 -	glVertex2f(0,1);
 -	glEnd(); 
 +    glDisable(GL_DEPTH_TEST);
 +    glBegin(GL_QUADS);
 +    glVertex2f(0,0);
 +    glVertex2f(1,0);
 +    glVertex2f(1,1);
 +    glVertex2f(0,1);
 +    glEnd();
  }
  void VideoWidget::paintGL()
  {
 -	glClear(GL_COLOR_BUFFER_BIT);
 -	if (!resized_qframe.isNull())
 -	{
 -		glDrawPixels(resized_qframe.width(), resized_qframe.height(), GL_RGBA, GL_UNSIGNED_BYTE, resized_qframe.bits());
 +    QMutexLocker lck(&mtx);
 +    if (resized_qframe.size() == size() || (resized_qframe.width() <= width() && resized_qframe.height() <= height())) {
 +        glDrawPixels(resized_qframe.width(), resized_qframe.height(), GL_RGB, GL_UNSIGNED_BYTE, resized_qframe.bits());
  		const int crosshair_radius = 10;
  		const int crosshair_thickness = 1;
 @@ -69,30 +65,44 @@ void VideoWidget::paintGL()  			glVertex2i(x, y+crosshair_radius);
  			glEnd();
  		}
 -	}
 -	glFlush();
 +
 +    } else {
 +        glClear(GL_DEPTH_BUFFER_BIT);
 +    }
 +    glFlush();
  }
  void VideoWidget::resize_frame()
  {
 -	if (!qframe.isNull())
 -		resized_qframe = qframe.scaled(this->size(), Qt::KeepAspectRatio);
 +    QMutexLocker lck(&mtx);
 +#ifdef _WIN32
 +    if (qframe.size() == size() || (qframe.width() <= width() && qframe.height() <= height()))
 +        resized_qframe = qframe.mirrored();
 +    else
 +        resized_qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation).mirrored();
 +#else
 +    if (qframe.size() == size() || (qframe.width() <= width() && qframe.height() <= height()))
 +        resized_qframe = qframe.copy();
 +    else
 +        resized_qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
 +#endif
  }
 +void VideoWidget::update()
 +{
 +    updateGL();
 +}
 -void VideoWidget::update(Mat frame, shared_ptr< vector<Vec2f> > points)
 +void VideoWidget::update_image(Mat frame, std::auto_ptr< vector<Vec2f> > points)
  {
  	this->frame = frame;
  	this->points = points;
 -	// convert to QImage
 +	// convert to QImage 
  	if (frame.channels() == 3)
 -		qframe = QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888).rgbSwapped();
 +		qframe = QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, frame.cols * 3, QImage::Format_RGB888).rgbSwapped();
  	else if (frame.channels() == 1)
 -		qframe = QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_Indexed8);
 -	qframe = QGLWidget::convertToGLFormat(qframe);
 -
 +		qframe = QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, frame.cols, QImage::Format_Indexed8);
  	resize_frame();
 -	updateGL();
  }
 diff --git a/ftnoir_tracker_pt/video_widget.h b/ftnoir_tracker_pt/video_widget.h index f49fef18..2425603b 100644 --- a/ftnoir_tracker_pt/video_widget.h +++ b/ftnoir_tracker_pt/video_widget.h @@ -11,7 +11,10 @@  #include <QGLWidget>
  #include <QTime>
  #include <opencv2/opencv.hpp>
 -#include <boost/shared_ptr.hpp>
 +#include <memory>
 +#include <QWidget>
 +#include <QMutex>
 +#include <QMutexLocker>
  // ----------------------------------------------------------------------------
  class VideoWidget : public QGLWidget
 @@ -19,13 +22,18 @@ class VideoWidget : public QGLWidget  	Q_OBJECT
  public:
 -	VideoWidget(QWidget *parent) : QGLWidget(parent) {}
 +    VideoWidget(QWidget *parent) : QGLWidget(parent) {
 +#if !defined(_WIN32)
 +        setAttribute(Qt::WA_NativeWindow, true);
 +#endif
 +	}
  	void initializeGL();
  	void resizeGL(int w, int h);
  	void paintGL();
 -	void update(cv::Mat frame, boost::shared_ptr< std::vector<cv::Vec2f> > points);
 +    void update_image(cv::Mat frame, std::auto_ptr< std::vector<cv::Vec2f> > points);
 +    void update();
  private:
  	void resize_frame();
 @@ -34,7 +42,8 @@ private:  	QImage qframe;
  	QImage resized_qframe;
 -	boost::shared_ptr< std::vector<cv::Vec2f> > points;
 +    std::auto_ptr< std::vector<cv::Vec2f> > points;
 +    QMutex mtx;
  };
  #endif // VIDEOWIDGET_H
 diff --git a/ftnoir_tracker_sm/ftnoir_sm_controls.ui b/ftnoir_tracker_sm/ftnoir_sm_controls.ui index 93befd19..06ebc9ca 100644 --- a/ftnoir_tracker_sm/ftnoir_sm_controls.ui +++ b/ftnoir_tracker_sm/ftnoir_sm_controls.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/sm.png</normaloff>images/sm.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 @@ -103,7 +103,7 @@       <property name="title">
        <string>Enable Axis</string>
       </property>
 -     <widget class="QWidget" name="">
 +     <widget class="QWidget" name="layoutWidget">
        <property name="geometry">
         <rect>
          <x>10</x>
 diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp index 624e35a0..35d3a3db 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp @@ -24,6 +24,7 @@  ********************************************************************************/
  #include "ftnoir_tracker_sm.h"
  #include <QtGui>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_Tracker::FTNoIR_Tracker()
  {
 @@ -49,67 +50,60 @@ FTNoIR_Tracker::~FTNoIR_Tracker()  	hSMMemMap = 0;
  }
 -void FTNoIR_Tracker::Initialize( QFrame *videoframe )
 -{
 -	qDebug() << "FTNoIR_Tracker::Initialize says: Starting ";
 -
 -	if (SMCreateMapping()) {
 -		qDebug() << "FTNoIR_Tracker::Initialize Mapping created.";
 -	}
 -	else {
 -		QMessageBox::warning(0,"FaceTrackNoIR Error","Memory mapping not created!",QMessageBox::Ok,QMessageBox::NoButton);
 -	}
 -
 -	loadSettings();
 -
 -	if ( pMemData != NULL ) {
 -		pMemData->command = 0;							// Reset any and all commands
 -		if (videoframe != NULL) {
 -			pMemData->handle = videoframe->winId();		// Handle of Videoframe widget
 -		}
 -		else {
 -			pMemData->handle = NULL;					// reset Handle of Videoframe widget
 -		}
 -	}
 -
 -	//
 -	// Start FTNoIR_FaceAPI_EXE.exe. The exe contains all faceAPI-stuff and is non-Qt...
 -	//
 -	QString program = "FTNoIR_FaceAPI_EXE.exe";
 -	faceAPI = new QProcess(0);
 -	faceAPI->start(program);
 -
 -	// Show the video widget
 -	qDebug() << "FTNoIR_Tracker::Initialize says: videoframe = " << videoframe;
 -
 -	if (videoframe != NULL) {
 -		videoframe->show();
 -	}
 -	return;
 -}
 -
 -void FTNoIR_Tracker::StartTracker( HWND parent_window )
 +void FTNoIR_Tracker::StartTracker(QFrame *videoframe )
  {
 +    qDebug() << "FTNoIR_Tracker::Initialize says: Starting ";
 +
 +    if (SMCreateMapping()) {
 +        qDebug() << "FTNoIR_Tracker::Initialize Mapping created.";
 +    }
 +    else {
 +        QMessageBox::warning(0,"FaceTrackNoIR Error","Memory mapping not created!",QMessageBox::Ok,QMessageBox::NoButton);
 +    }
 +
 +    loadSettings();
 +
 +    if ( pMemData != NULL ) {
 +        pMemData->command = 0;							// Reset any and all commands
 +        if (videoframe != NULL) {
 +            pMemData->handle = videoframe->winId();		// Handle of Videoframe widget
 +        }
 +        else {
 +            pMemData->handle = NULL;					// reset Handle of Videoframe widget
 +        }
 +    }
 +
 +    //
 +    // Start FTNoIR_FaceAPI_EXE.exe. The exe contains all faceAPI-stuff and is non-Qt...
 +    //
 +    // XXX TODO isolate it into separate directory
 +    faceAPI = new QProcess();
 +    faceAPI->setWorkingDirectory(QCoreApplication::applicationDirPath() + "/faceapi");
 +    faceAPI->start("\"" + QCoreApplication::applicationDirPath() + "/faceapi/ftnoir-faceapi-wrapper" + "\"");
 +    // Show the video widget
 +    qDebug() << "FTNoIR_Tracker::Initialize says: videoframe = " << videoframe;
 +
 +    if (videoframe != NULL) {
 +        videoframe->show();
 +    }
  	if ( pMemData != NULL ) {
  		pMemData->command = FT_SM_START;				// Start command
  	}
 -	return;
  }
 -void FTNoIR_Tracker::StopTracker( bool exit )
 +void FTNoIR_Tracker::WaitForExit()
  {
  	qDebug() << "FTNoIR_Tracker::StopTracker says: Starting ";
  	// stops the faceapi engine
  	if ( pMemData != NULL ) {
  //		if (exit == true) {
 -			pMemData->command = (exit) ? FT_SM_EXIT : FT_SM_STOP;			// Issue 'stop' command
 +            pMemData->command = FT_SM_EXIT;
  		//}
  		//else {
  		//	pMemData->command = FT_SM_STOP;				// Issue 'stop' command
  		//}
  	}
 -	return;
  }
  bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)
 @@ -246,9 +240,9 @@ bool FTNoIR_Tracker::SMCreateMapping()  //   GetTracker     - Undecorated name, which can be easily used with GetProcAddress
  //                Win32 API function.
  //   _GetTracker@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 +//#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Tracker;
 +	return (ITracker*) new FTNoIR_Tracker;
  }
 diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp index 5c422402..b62f652c 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp @@ -24,6 +24,7 @@  ********************************************************************************/
  #include "ftnoir_tracker_sm.h"
  #include <QtGui>
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // faceAPI Client Settings-dialog.
 @@ -338,9 +339,9 @@ void TrackerControls::doCommand(int command, int value)  //   GetTrackerDialog     - Undecorated name, which can be easily used with GetProcAddress
  //                          Win32 API function.
  //   _GetTrackerDialog@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 +//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( )
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetDialog()
  {
 -	return new TrackerControls;
 +	return (ITrackerDialog*) new TrackerControls;
  }
 diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp index 5f01568f..70326499 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_tracker_sm.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_TrackerDll::FTNoIR_TrackerDll() {
  	//populate the description strings
 @@ -67,7 +68,7 @@ void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled)  void FTNoIR_TrackerDll::getIcon(QIcon *icon)
  {
 -	*icon = QIcon(":/images/SeeingMachines.ico");
 +    *icon = QIcon(":/images/sm.png");
  };
  ////////////////////////////////////////////////////////////////////////////////
 @@ -77,9 +78,9 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)  //   GetTrackerDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetTrackerDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 +//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_TrackerDll;
  }
 diff --git a/ftnoir_tracker_sm/ftnoir_tracker_sm.h b/ftnoir_tracker_sm/ftnoir_tracker_sm.h index b7aed1d0..39997970 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_sm.h +++ b/ftnoir_tracker_sm/ftnoir_tracker_sm.h @@ -31,6 +31,8 @@  #include <QProcess>
  #include "Windows.h"
  #include "math.h"
 +#include "facetracknoir/global-settings.h"
 +#include <QFrame>
  using namespace std;
 @@ -40,10 +42,10 @@ public:  	FTNoIR_Tracker();
  	~FTNoIR_Tracker();
 -    void Initialize( QFrame *videoframe );
 -    void StartTracker( HWND parent_window );
 +    void StartTracker( QFrame* parent_window );
      void StopTracker( bool exit );
  	bool GiveHeadPoseData(THeadPoseData *data);				// Returns true if confidence is good
 +    void WaitForExit();
  	void loadSettings();
  	bool SMCreateMapping();
 @@ -137,7 +139,7 @@ signals:  //*******************************************************************************************************
  // FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker
  //*******************************************************************************************************
 -class FTNoIR_TrackerDll : public ITrackerDll
 +class FTNoIR_TrackerDll : public Metadata
  {
  public:
  	FTNoIR_TrackerDll();
 diff --git a/ftnoir_tracker_sm/images/sm.ico b/ftnoir_tracker_sm/images/sm.icoBinary files differ new file mode 100644 index 00000000..19b24c84 --- /dev/null +++ b/ftnoir_tracker_sm/images/sm.ico diff --git a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui index 7ac6c0f4..5883e317 100644 --- a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui +++ b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui @@ -15,7 +15,7 @@    </property>
    <property name="windowIcon">
     <iconset>
 -    <normaloff>images/FaceTrackNoIR.ico</normaloff>images/FaceTrackNoIR.ico</iconset>
 +    <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
    </property>
    <property name="layoutDirection">
     <enum>Qt::LeftToRight</enum>
 diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp index 102c85bd..4978fa8d 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp @@ -23,16 +23,13 @@  *																				*
  ********************************************************************************/
  #include "ftnoir_tracker_udp.h"
 +#include "facetracknoir/global-settings.h"
  FTNoIR_Tracker::FTNoIR_Tracker()
  {
  	inSocket = 0;
  	outSocket = 0;
 -	// Create events
 -	m_StopThread = CreateEvent(0, TRUE, FALSE, 0);
 -	m_WaitThread = CreateEvent(0, TRUE, FALSE, 0);
 -
  	bEnableRoll = true;
  	bEnablePitch = true;
  	bEnableYaw = true;
 @@ -51,18 +48,6 @@ FTNoIR_Tracker::FTNoIR_Tracker()  FTNoIR_Tracker::~FTNoIR_Tracker()
  {
 -	// Trigger thread to stop
 -	::SetEvent(m_StopThread);
 -
 -	// Wait until thread finished
 -	if (isRunning()) {
 -		::WaitForSingleObject(m_WaitThread, INFINITE);
 -	}
 -
 -	// Close handles
 -	::CloseHandle(m_StopThread);
 -	::CloseHandle(m_WaitThread);
 -
  	if (inSocket) {
  		inSocket->close();
  		delete inSocket;
 @@ -77,7 +62,6 @@ FTNoIR_Tracker::~FTNoIR_Tracker()  /** QThread run @override **/
  void FTNoIR_Tracker::run() {
 -int no_bytes;
  QHostAddress sender;
  quint16 senderPort;
 @@ -85,77 +69,51 @@ quint16 senderPort;  	// Read the data that was received.
  	//
  	forever {
 -
 -	    // Check event for stop thread
 -		if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0)
 -		{
 -			// Set event
 -			::SetEvent(m_WaitThread);
 -			qDebug() << "FTNoIR_Tracker::run() terminated run()";
 -			return;
 -		}
 -
 +        if (should_quit)
 +            break;
  		if (inSocket != 0) {
  			while (inSocket->hasPendingDatagrams()) {
  				QByteArray datagram;
  				datagram.resize(inSocket->pendingDatagramSize());
 -
 +                mutex.lock();
  				inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort);
 +                mutex.unlock();
  			}
  		}
  		else {
 -			qDebug() << "FTNoIR_Tracker::run() insocket not ready: exit run()";
 -			return;
 +            break;
  		}
 -		//for lower cpu load 
  		usleep(10000);
 -//		yieldCurrentThread(); 
 -	}
 -}
 -
 -void FTNoIR_Tracker::Initialize( QFrame *videoframe )
 -{
 -	qDebug() << "FTNoIR_Tracker::Initialize says: Starting ";
 -	loadSettings();
 -
 -	//
 -	// Create UDP-sockets if they don't exist already.
 -	// They must be created here, because they must be in the new thread (FTNoIR_Tracker::run())
 -	//
 -	if (inSocket == 0) {
 -		qDebug() << "FTNoIR_Tracker::Initialize() creating insocket";
 -		inSocket = new QUdpSocket();
 -		// Connect the inSocket to the port, to receive messages
 -		
 -		if (!inSocket->bind(QHostAddress::Any, (int) portAddress, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
 -			QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton);
 -			delete inSocket;
 -			inSocket = 0;
 -		}
  	}
 -
 -	return;
 -}
 -
 -void FTNoIR_Tracker::StartTracker( HWND parent_window )
 -{
 -	start( QThread::TimeCriticalPriority );
 -	return;
  }
 -void FTNoIR_Tracker::StopTracker( bool exit )
 +void FTNoIR_Tracker::StartTracker(QFrame* videoFrame)
  {
 -	//
 -	// OK, the thread is not stopped, doing this. That might be dangerous anyway...
 -	//
 -	if (exit || !exit) return;
 +    loadSettings();
 +    //
 +    // Create UDP-sockets if they don't exist already.
 +    // They must be created here, because they must be in the new thread (FTNoIR_Tracker::run())
 +    //
 +    if (inSocket == 0) {
 +        qDebug() << "FTNoIR_Tracker::Initialize() creating insocket";
 +        inSocket = new QUdpSocket();
 +        // Connect the inSocket to the port, to receive messages
 +
 +        if (!inSocket->bind(QHostAddress::Any, (int) portAddress, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
 +            QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton);
 +            delete inSocket;
 +            inSocket = 0;
 +        }
 +    }
 +	start();
  	return;
  }
  bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)
  {
 +    mutex.lock();
  	if (bEnableX) {
  		data->x = newHeadPose.x;
  	}
 @@ -165,15 +123,16 @@ bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)  	if (bEnableX) {
  		data->z = newHeadPose.z;
  	}
 -	if (bEnableX) {
 +    if (bEnableYaw) {
  		data->yaw = newHeadPose.yaw;
  	}
 -	if (bEnableX) {
 +    if (bEnablePitch) {
  		data->pitch = newHeadPose.pitch;
  	}
 -	if (bEnableX) {
 +    if (bEnableRoll) {
  		data->roll = newHeadPose.roll;
  	}
 +    mutex.unlock();
  	return true;
  }
 @@ -209,9 +168,9 @@ void FTNoIR_Tracker::loadSettings() {  //   GetTracker     - Undecorated name, which can be easily used with GetProcAddress
  //                Win32 API function.
  //   _GetTracker@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 +//#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
  {
 -	return new FTNoIR_Tracker;
 +    return (ITracker*) new FTNoIR_Tracker;
  }
 diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.h b/ftnoir_tracker_udp/ftnoir_tracker_udp.h index 94645c84..d60b27a4 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.h +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.h @@ -1,39 +1,38 @@ -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
 -#include "ui_FTNoIR_FTNClientcontrols.h"
 +#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
 +#include "ui_ftnoir_ftnclientcontrols.h"
  #include <QThread>
  #include <QUdpSocket>
  #include <QMessageBox>
  #include <QSettings>
 -#include "Windows.h"
 -#include "math.h"
 +#include <QMutex>
 +#include <QWaitCondition>
 +#include <math.h>
 +#include "facetracknoir/global-settings.h"
 -class FTNoIR_Tracker : public ITracker, QThread
 +class FTNoIR_Tracker : public ITracker, public QThread
  {
  public:
  	FTNoIR_Tracker();
  	~FTNoIR_Tracker();
 -    void Initialize( QFrame *videoframe );
 -    void StartTracker( HWND parent_window );
 -    void StopTracker( bool exit );
 +    void StartTracker( QFrame *videoframe );
  	bool GiveHeadPoseData(THeadPoseData *data);
  	void loadSettings();
 +    volatile bool should_quit;
 +    void WaitForExit() {
 +        should_quit = true;
 +        wait();
 +    }
  protected:
  	void run();												// qthread override run method
  private:
 -	// Handles to neatly terminate thread...
 -	HANDLE m_StopThread;
 -	HANDLE m_WaitThread;
 -
  	// UDP socket-variables
  	QUdpSocket *inSocket;									// Receive from ...
  	QUdpSocket *outSocket;									// Send to ...
  	QHostAddress destIP;									// Destination IP-address
 -	int destPort;											// Destination port-number
  	QHostAddress srcIP;										// Source IP-address
 -	int srcPort;											// Source port-number
  	THeadPoseData newHeadPose;								// Structure with new headpose
 @@ -44,6 +43,7 @@ private:  	bool bEnableX;
  	bool bEnableY;
  	bool bEnableZ;
 +    QMutex mutex;
  };
  // Widget that has controls for FTNoIR protocol client-settings.
 @@ -53,7 +53,7 @@ class TrackerControls: public QWidget, Ui::UICFTNClientControls, public ITracker  public:
  	explicit TrackerControls();
 -    virtual ~TrackerControls();
 +    ~TrackerControls();
  	void showEvent ( QShowEvent * event );
      void Initialize(QWidget *parent);
 @@ -78,7 +78,7 @@ private slots:  //*******************************************************************************************************
  // FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker
  //*******************************************************************************************************
 -class FTNoIR_TrackerDll : public ITrackerDll
 +class FTNoIR_TrackerDll : public Metadata
  {
  public:
  	FTNoIR_TrackerDll();
 diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp index b489822a..b67afc66 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp @@ -23,6 +23,7 @@  *																				*
  ********************************************************************************/
  #include "ftnoir_tracker_udp.h"
 +#include "facetracknoir/global-settings.h"
  //*******************************************************************************************************
  // FaceTrackNoIR Client Settings-dialog.
 @@ -173,9 +174,9 @@ void TrackerControls::save() {  //   GetTrackerDialog     - Undecorated name, which can be easily used with GetProcAddress
  //                          Win32 API function.
  //   _GetTrackerDialog@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 +//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( )
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
  {
 -	return new TrackerControls;
 +    return (ITrackerDialog*) new TrackerControls;
  }
 diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp index a086a888..cbb0c644 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp @@ -32,6 +32,7 @@  */
  #include "ftnoir_tracker_udp.h"
  #include <QDebug>
 +#include "facetracknoir/global-settings.h"
  FTNoIR_TrackerDll::FTNoIR_TrackerDll() {
  	//populate the description strings
 @@ -67,7 +68,7 @@ void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled)  void FTNoIR_TrackerDll::getIcon(QIcon *icon)
  {
 -	*icon = QIcon(":/images/FaceTrackNoIR.ico");
 +    *icon = QIcon(":/images/facetracknoir.png");
  };
  ////////////////////////////////////////////////////////////////////////////////
 @@ -77,9 +78,9 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)  //   GetTrackerDll     - Undecorated name, which can be easily used with GetProcAddress
  //						Win32 API function.
  //   _GetTrackerDll@0  - Common name decoration for __stdcall functions in C language.
 -#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 +//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
 -FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
 +extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
  {
  	return new FTNoIR_TrackerDll;
  }
 diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cppBinary files differ index 243564d1..25d5599a 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.hBinary files differ index 8dc9cf98..281007d6 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index fe2ad49d..e143a536 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -1,721 +1,700 @@ -/********************************************************************************
 -* FaceTrackNoIR		This program is a private project of some enthusiastic		*
 -*					gamers from Holland, who don't like to pay much for			*
 -*					head-tracking.												*
 -*																				*
 -* Copyright (C) 2012	Wim Vriend (Developing)									*
 -*						Ron Hendriks (Researching and Testing)					*
 -*																				*
 -* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				*
 -*																				*
 -* 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 <http://www.gnu.org/licenses/>.				*
 -*																				*
 -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          *
 -* FaceTrackNoIR.																*
 -*																				*
 -* All credits for this nice piece of code should go to Stanislaw.				*
 -*																				*
 -* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					*
 -* Permission to use, copy, modify, and/or distribute this						*
 -* software for any purpose with or without fee is hereby granted,				*
 -* provided that the above copyright notice and this permission					*
 -* notice appear in all copies.													*
 -********************************************************************************/
 -/*
 -	Modifications (last one on top):
 -		20120830 - WVR: Changed functionality a bit. Now only draw the handles, when the function is drawn.
 -						Only check mouseMoves, when they occur 'in range'. Redraw the curve, when a resize occurs.
 -						Somehow, the curve was not drawn correctly, when this was not done (all points were too high). 
 -						After a 'Reset' this would disappear...
 -		20120828 - WVR: Removed bSkipText, which was used to not show a number below each vertical gridline.
 -*/
 -#include "qfunctionconfigurator.h"
 -#include <QPainter>
 -#include <QPaintEvent>
 -#include <QPainterPathStroker>
 -#include <QPainterPath>
 -#include <QBrush>
 -#include <QFileDialog>
 -#include <QPen>
 -#include <QMessageBox>
 -#include <QImage>
 -#include <QPixmap>
 -#include <QTimer>
 -
 -#include <QtDebug>
 -
 -#include <math.h>
 -
 -QFunctionConfigurator::~QFunctionConfigurator()
 -{
 -	WaitForSingleObject(_mutex, INFINITE);
 -	CloseHandle(_mutex);
 -	delete btnReset;
 -}
 -
 -static const int pointSize = 5;
 -
 -QFunctionConfigurator::QFunctionConfigurator(QWidget *parent)
 -    : QWidget(parent)
 -{
 -
 -	//
 -	// Defaults, for when the widget has no values different from the domXML()
 -	//
 -	MaxInput = 50;					// Maximum input limit
 -	MaxOutput = 180;				// Maximum output limit
 -	pPerEGU_Output = 1;				// Number of pixels, per EGU
 -	pPerEGU_Input = 4;				// Number of pixels, per EGU
 -	gDistEGU_Input = 5;				// Distance of gridlines
 -	gDistEGU_Output = 10;			// Distance of gridlines
 -
 -	
 -	// Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output)
 -	// This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..)
 -	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output);
 -
 -    setMouseTracking(true);
 -    moving = NULL;						// Pointer to the curve-point, that's being moved
 -	movingPoint = 1;				// Index of that same point
 -
 -	//
 -	// Add a Reset-button
 -	//
 -	btnReset = new QPushButton(QString("Reset"), this);
 -	connect(btnReset, SIGNAL(clicked()), this, SLOT(resetCurve()));
 -
 -	//
 -	// Variables for FunctionConfig
 -	//
 -	_config = 0;
 -	_points = QList<QPointF>();
 -	_draw_points = QList<QPointF>();
 -	_mutex = CreateMutex(NULL, false, NULL);
 -	_draw_background = true;
 -	_draw_function = true;
 -
 -//	qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created.";
 -
 -}
 -
 -//
 -// Attach an existing FunctionConfig to the Widget.
 -//
 -void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) {
 -QPointF currentPoint;
 -QPointF drawPoint;
 -qreal x;
 -
 -	WaitForSingleObject(_mutex, INFINITE);
 -	_config = config;
 -	_points = config->getPoints();
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -
 -	qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle();
 -	setCaption(config->getTitle());
 -
 -	//
 -	// Get the Function Points, one for each pixel in the horizontal range.
 -	// If the curve does not change, there is no need to run this code every time (it slows down drawing).
 -	//
 -	_draw_points.clear();
 -	for (int j = 0; j < MaxInput * pPerEGU_Input; j++) {
 -		//
 -		// Weird: not casting to float causes C++ to round the number...
 -		//
 -		x = (float) j / (float) pPerEGU_Input;
 -		currentPoint.setX ( x );
 -		currentPoint.setY (_config->getValue( x ));
 -		drawPoint = graphicalizePoint(currentPoint, "setConfig");
 -		if (withinRect(drawPoint, range)) {
 -			_draw_points.append(drawPoint);
 -//	qDebug() << "QFunctionConfigurator::setConfig _draw_Point to add = " << drawPoint;
 -		}
 -	}
 -	
 -	ReleaseMutex(_mutex);
 -	_draw_function = true;
 -	this->update();
 -}
 -
 -//
 -// Load the FunctionConfig (points) from the INI-file.
 -//
 -void QFunctionConfigurator::loadSettings(QString settingsFile) {
 -
 -	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file)
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -	qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile;
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -		_config->loadSettings(iniFile);
 -		setConfig(_config, settingsFile);
 -	}
 -	ReleaseMutex(_mutex);
 -}
 -
 -//
 -// Save the FunctionConfig (points) to the INI-file.
 -//
 -void QFunctionConfigurator::saveSettings(QString settingsFile) {
 -	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file)
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -	qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile;
 -
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -		_config->saveSettings(iniFile);
 -	}
 -	ReleaseMutex(_mutex);
 -}
 -
 -//
 -// Draw the Background for the graph, the gridlines and the gridpoints.
 -// The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up...
 -//
 -void QFunctionConfigurator::drawBackground(const QRectF &fullRect)
 -{
 -int i;
 -QRect scale;
 -
 -	qDebug() << "QFunctionConfigurator::drawBackground.";
 -
 -	_background = QPixmap(fullRect.width(), fullRect.height());
 -	QPainter painter(&_background);
 -
 -	painter.save();
 -	painter.setRenderHint(QPainter::Antialiasing);
 -	painter.fillRect(fullRect, colBackground);
 -	QColor bg_color(112, 154, 209);
 -	painter.fillRect(range, bg_color);
 -
 -	QFont font("ComicSans", 4);
 -    font.setPointSize(8);
 -    painter.setFont(font);
 -
 -    QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine);
 -
 -	//
 -	// Draw the Caption
 -	//
 -	if (_config) {
 -		strCaption = _config->getTitle();
 -	}
 -
 -	scale.setCoords(range.left(), 0, range.right(), 20);
 -	painter.drawText(scale, Qt::AlignCenter, strCaption);
 -
 -	//
 -	// Draw the horizontal grid
 -	//
 -	for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) {
 -		drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen);
 -		scale.setCoords(0, i - 5, range.left() - 5, i + 5);
 -		painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output));
 -	}
 -
 -	//
 -	// Draw the vertical guidelines
 -	//
 -	for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) {
 -		drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen);
 -		scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15);
 -		painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input)));
 -	}
 -
 -	scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35);
 -	painter.drawText(scale, Qt::AlignRight, strInputEGU);
 -
 -	//
 -	// Draw the EGU of the vertical axis (vertically!)
 -	//
 -	font.setPointSize(10);
 -	painter.translate(range.topLeft().x() - 35, range.topLeft().y());
 -	painter.rotate(90);
 -	painter.drawText(0,0,strOutputEGU );
 -
 -	//
 -	// Draw the two axis
 -	//
 -	pen.setWidth(2);
 -	pen.setColor( Qt::black );
 -	drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen);
 -	drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen);
 -
 -	painter.restore();
 -}
 -
 -
 -//
 -// Draw the Function for the graph, on a Pixmap.
 -//
 -void QFunctionConfigurator::drawFunction(const QRectF &fullRect)
 -{
 -	if (!_config)
 -		return;
 -int i;
 -QPointF prevPoint;
 -QPointF currentPoint;
 -
 -	//
 -	// Use the background picture to draw on.
 -	// ToDo: find out how to add Pixmaps, without getting it all green...
 -	//
 -	_function = QPixmap(_background);
 -	QPainter painter(&_function);
 -
 -	painter.save();
 -	painter.setRenderHint(QPainter::Antialiasing, false);
 -
 -	//
 -	// Draw the handles for the Points
 -	//
 -	for (i = 0; i < _points.size(); i++) {
 -		currentPoint = graphicalizePoint( _points[i], "drawFunction handles" );		// Get the next point and convert it to Widget measures 
 -	    drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120));
 -		lastPoint = currentPoint;											// Remember which point is the rightmost in the graph
 -//qDebug() << "QFunctionConfigurator::paintEvent, drawing handle for " << currentPoint;
 -	}
 -
 -
 -	QPen pen(colBezier, 2, Qt::SolidLine);
 -
 -	prevPoint = graphicalizePoint( QPointF(0,0), "drawFunction lines" );		// Start at the Axis
 -	double max = maxInputEGU();
 -	QPointF prev = graphicalizePoint(QPointF(0, 0));
 -    double step = 1 / (double) pixPerEGU_Input();
 -	for (double i = 0; i < max; i += step) {
 -	    double val = _config->getValue(i);
 -	    QPointF cur = graphicalizePoint(QPointF(i, val));
 -	    drawLine(&painter, prev, cur, pen);
 -		prev = cur;
 -	}
 -	painter.restore();
 -}
 -
 -//
 -// The Widget paints the surface every x msecs.
 -//
 -void QFunctionConfigurator::paintEvent(QPaintEvent *e)
 -{
 -QPointF prevPoint;
 -QPointF currentPoint;
 -QPointF actualPos;
 -int i;
 -
 -//	qDebug() << "QFunctionConfigurator::paintEvent.";
 -
 -	QPainter p(this);
 -    p.setRenderHint(QPainter::Antialiasing);
 -    p.setClipRect(e->rect());
 -
 -	if (_draw_background) {
 -		drawBackground(e->rect());						// Draw the static parts on a Pixmap
 -		p.drawPixmap(0, 0, _background);				// Paint the background
 -		_draw_background = false;
 -
 -		btnReset->move(e->rect().left(), e->rect().bottom() - btnReset->height() - 2);
 -	}
 -
 -	if (_draw_function) {
 -		drawFunction(e->rect());						// Draw the Function on a Pixmap
 -		_draw_function = false;
 -	}
 -	p.drawPixmap(0, 0, _function);						// Always draw the background and the function
 -
 -	QPen pen(Qt::white, 1, Qt::SolidLine);
 -
 -	//
 -	// Draw the Points, that make up the Curve
 -	//
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -
 -		//
 -		// When moving, also draw a sketched version of the Function.
 -		//
 -		if (moving) {
 -			prevPoint = graphicalizePoint( QPointF(0,0), "paintEvent moving" );				// Start at the Axis
 -			for (i = 0; i < _points.size(); i++) {
 -				currentPoint = graphicalizePoint( _points[i], "paintEvent moving" );		// Get the next point and convert it to Widget measures 
 -				drawLine(&p, prevPoint, currentPoint, pen);
 -				prevPoint = currentPoint;
 -//	qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint;
 -			}
 -
 -			//
 -			// When moving, also draw a few help-lines, so positioning the point gets easier.
 -			//
 -			pen.setWidth(1);
 -			pen.setColor( Qt::white );
 -			pen.setStyle( Qt::DashLine );
 -			actualPos = graphicalizePoint(*moving, "paintEvent moving help line(s)");
 -			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
 -			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen);
 -		}
 -
 -		//
 -		// If the Tracker is active, the 'Last Point' it requested is recorded.
 -		// Show that point on the graph, with some lines to assist.
 -		// This new feature is very handy for tweaking the curves!
 -		//
 -		if (_config->getLastPoint( currentPoint )) {
 -
 -//	qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint;
 -
 -			actualPos = graphicalizePoint( currentPoint, "paintEvent tracking" );
 -			drawPoint(&p, actualPos, QColor(255, 0, 0, 120));
 -
 -			pen.setWidth(1);
 -			pen.setColor( Qt::black );
 -			pen.setStyle( Qt::SolidLine );
 -			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
 -			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen);
 -		}
 -
 -	}
 -	ReleaseMutex(_mutex);
 -
 -	//
 -	// Draw the delimiters
 -	//
 -	pen.setWidth(1);
 -	pen.setColor( Qt::white );
 -	pen.setStyle( Qt::SolidLine );
 -	drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen);
 -	drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen);
 -
 -	QTimer::singleShot(250, this, SLOT(update()));
 -}
 -
 -//
 -// Draw the handle, to move the Bezier-curve.
 -//
 -void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG )
 -{
 -    painter->save();
 -    painter->setPen(QColor(50, 100, 120, 200));
 -    painter->setBrush( colBG );
 -    painter->drawEllipse(QRectF(pos.x() - pointSize,
 -                                pos.y() - pointSize,
 -                                pointSize*2, pointSize*2));
 -    painter->restore();
 -}
 -
 -void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen)
 -{
 -    painter->save();
 -    painter->setPen(pen);
 -    painter->setBrush(Qt::NoBrush);
 -    painter->drawLine(start, end);
 -    painter->restore();
 -}
 -
 -//
 -// If the mousebutton is pressed, check if it is inside one of the Points.
 -// If so: start moving that Point, until mouse release.
 -//
 -void QFunctionConfigurator::mousePressEvent(QMouseEvent *e)
 -{
 -	//
 -	// First: check the left mouse-button
 -	//
 -	if (e->button() == Qt::LeftButton) {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		bool bTouchingPoint = false;
 -		movingPoint = -1;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent markContains" ), e->pos() ) ) {
 -					bTouchingPoint = true;
 -		            moving = &_points[i];
 -					movingPoint = i;
 -				}
 -			}
 -
 -			//
 -			// If the Left Mouse-button was clicked without touching a Point, add a new Point
 -			//
 -			if (!bTouchingPoint) {
 -				if (withinRect(e->pos(), range)) {
 -					_config->addPoint(normalizePoint(e->pos()));
 -					setConfig(_config, strSettingsFile);
 -					moving = NULL;
 -					emit CurveChanged( true );
 -				}
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -	}
 -
 -	//
 -	// Then: check the right mouse-button
 -	//
 -	if (e->button() == Qt::RightButton) {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		moving = NULL;
 -		movingPoint = -1;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent RightButton" ), e->pos() ) ) {
 -					movingPoint = i;
 -				}
 -			}
 -
 -			//
 -			// If the Right Mouse-button was clicked while touching a Point, remove the Point
 -			//
 -			if (movingPoint >= 0) {
 -				_config->removePoint(movingPoint);
 -				setConfig(_config, strSettingsFile);
 -				movingPoint = -1;
 -				emit CurveChanged( true );
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -	}
 -
 -}
 -
 -//
 -// If the mouse if moving, make sure the Bezier moves along.
 -// Of course, only when a Point is selected...
 -//
 -void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e)
 -{
 -
 -	if (moving) {
 -
 -		setCursor(Qt::ClosedHandCursor);		
 -
 -		//
 -		// Change the currently moving Point.
 -		//
 -		*moving = normalizePoint(e->pos());
 -		update();
 -    }
 -	else {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		bool bTouchingPoint = false;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mouseMoveEvent" ), e->pos() ) ) {
 -					bTouchingPoint = true;
 -				}
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -
 -		if ( bTouchingPoint ) {
 -			setCursor(Qt::OpenHandCursor);
 -		}
 -		else {
 -			setCursor(Qt::ArrowCursor);
 -		}
 -
 -	}
 -}
 -
 -void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e)
 -{
 -    //qDebug()<<"releasing";
 -	if (moving > 0) {
 -		emit CurveChanged( true );
 -
 -		//
 -		// Update the Point in the _config
 -		//
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -			_config->movePoint(movingPoint, normalizePoint(e->pos()));
 -			setConfig(_config, strSettingsFile);
 -		}
 -		ReleaseMutex(_mutex);
 -
 -	}
 -	setCursor(Qt::ArrowCursor);		
 -	moving = NULL;
 -    movingPoint = 0;
 -}
 -
 -//
 -// Determine if the mousebutton was pressed within the range of the Point.
 -//
 -bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const
 -{
 -    QRectF rect(pos.x() - pointSize,
 -                pos.y() - pointSize,
 -                pointSize*2, pointSize*2);
 -    QPainterPath path;
 -    path.addEllipse(rect);
 -    return path.contains(coord);
 -}
 -
 -bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect ) const
 -{
 -    QPainterPath path;
 -    path.addRect(rect);
 -    return path.contains(coord);
 -}
 -
 -//
 -// Convert the Point in the graph, to the real-life Point.
 -//
 -QPointF QFunctionConfigurator::normalizePoint(QPointF point) const
 -{
 -	QPointF norm;
 -
 -	norm.setX( (point.x() - range.left()) / pPerEGU_Input );
 -    norm.setY( (range.bottom() - point.y()) / pPerEGU_Output );
 -
 -	if (norm.x() > maxInputEGU())
 -		norm.setX(maxInputEGU());
 -	else if (norm.x() < 0)
 -		norm.setX(0);
 -	if (norm.y() > maxOutputEGU())
 -		norm.setY(maxOutputEGU());
 -	else if (norm.y() < 0)
 -		norm.setY(0);
 -
 -	return norm;
 -}
 -
 -//
 -// Convert the real-life Point into the graphical Point.
 -//
 -QPointF QFunctionConfigurator::graphicalizePoint(QPointF point, QString source) const
 -{
 -QPointF graph;
 -
 -	graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) );
 -	graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) );
 -
 -//	qDebug() << "QFunctionConfigurator::graphicalizePoint source = " << source << ", point = " << point << ", graph = " << graph;
 -
 -	return graph;
 -}
 -
 -void QFunctionConfigurator::setmaxInputEGU(int value)
 -{
 -    MaxInput = value;
 -	setMinimumWidth(MaxInput * pPerEGU_Input + 55);
 -//	resetCurve();
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -void QFunctionConfigurator::setmaxOutputEGU(int value)
 -{
 -    MaxOutput = value;
 -	setMinimumHeight(MaxOutput * pPerEGU_Output + 60);
 -//	resetCurve();
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined.
 -//
 -void QFunctionConfigurator::setpixPerEGU_Input(int value)
 -{
 -    pPerEGU_Input = value;
 -	setMinimumWidth(MaxInput * pPerEGU_Input + 55);
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined.
 -//
 -void QFunctionConfigurator::setpixPerEGU_Output(int value)
 -{
 -    pPerEGU_Output = value;
 -	setMinimumHeight(MaxOutput * pPerEGU_Output + 60);
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// Define the distance of the grid 'in EGU' points.
 -//
 -void QFunctionConfigurator::setgridDistEGU_Input(int value)
 -{
 -    gDistEGU_Input = value;
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 -
 -//
 -// Define the distance of the grid 'in EGU' points.
 -//
 -void QFunctionConfigurator::setgridDistEGU_Output(int value)
 -{
 -    gDistEGU_Output = value;
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 -
 -void QFunctionConfigurator::setColorBezier(QColor color)
 -{
 -    colBezier = color;
 -    update();
 -}
 -void QFunctionConfigurator::setColorBackground(QColor color)
 -{
 -    colBackground = color;
 -    update();
 -}
 -
 -void QFunctionConfigurator::setInputEGU(QString egu)
 -{
 -    strInputEGU = egu;
 -    update();
 -}
 -void QFunctionConfigurator::setOutputEGU(QString egu)
 -{
 -    strOutputEGU = egu;
 -    update();
 -}
 -void QFunctionConfigurator::setCaption(QString cap)
 -{
 -    strCaption = cap;
 -    update();
 -}
 -
 -void QFunctionConfigurator::resizeEvent(QResizeEvent *e)
 -{
 -    QSize s = e->size();
 -	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output);
 -
 -	qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range;
 -
 -	if (_config) {
 -		setConfig(_config, strSettingsFile);
 -	}
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 +/******************************************************************************** +* FaceTrackNoIR		This program is a private project of some enthusiastic		* +*					gamers from Holland, who don't like to pay much for			* +*					head-tracking.												* +*																				* +* Copyright (C) 2012	Wim Vriend (Developing)									* +*						Ron Hendriks (Researching and Testing)					* +*																				* +* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				* +*																				* +* 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 <http://www.gnu.org/licenses/>.				* +*																				* +* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          * +* FaceTrackNoIR.																* +*																				* +* All credits for this nice piece of code should go to Stanislaw.				* +*																				* +* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					* +* Permission to use, copy, modify, and/or distribute this						* +* software for any purpose with or without fee is hereby granted,				* +* provided that the above copyright notice and this permission					* +* notice appear in all copies.													* +********************************************************************************/ +/* +	Modifications (last one on top): +		20120830 - WVR: Changed functionality a bit. Now only draw the handles, when the function is drawn. +						Only check mouseMoves, when they occur 'in range'. Redraw the curve, when a resize occurs. +						Somehow, the curve was not drawn correctly, when this was not done (all points were too high).  +						After a 'Reset' this would disappear... +		20120828 - WVR: Removed bSkipText, which was used to not show a number below each vertical gridline. +*/ +#include "qfunctionconfigurator/qfunctionconfigurator.h" +#include <QPainter> +#include <QPaintEvent> +#include <QPainterPathStroker> +#include <QPainterPath> +#include <QBrush> +#include <QFileDialog> +#include <QPen> +#include <QMessageBox> +#include <QImage> +#include <QPixmap> +#include <QTimer> + +#include <QtDebug> + +#include <math.h> + +QFunctionConfigurator::~QFunctionConfigurator() +{ +	delete btnReset; +} + +static const int pointSize = 5; + +QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) +    : QWidget(parent) +{ + +	// +	// Defaults, for when the widget has no values different from the domXML() +	// +	MaxInput = 50;					// Maximum input limit +	MaxOutput = 180;				// Maximum output limit +	pPerEGU_Output = 1;				// Number of pixels, per EGU +	pPerEGU_Input = 4;				// Number of pixels, per EGU +	gDistEGU_Input = 5;				// Distance of gridlines +	gDistEGU_Output = 10;			// Distance of gridlines + +	 +	// Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output) +	// This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) +	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + +    setMouseTracking(true); +    moving = NULL;						// Pointer to the curve-point, that's being moved +	movingPoint = 1;				// Index of that same point + +	// +	// Add a Reset-button +	// +	btnReset = new QPushButton(QString("Reset"), this); +	connect(btnReset, SIGNAL(clicked()), this, SLOT(resetCurve())); + +	// +	// Variables for FunctionConfig +	// +	_config = 0; +	_points = QList<QPointF>(); +	_draw_points = QList<QPointF>(); +	_draw_background = true; +	_draw_function = true; + +//	qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created."; + +} + +// +// Attach an existing FunctionConfig to the Widget. +// +void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { +QPointF currentPoint; +QPointF drawPoint; +qreal x; + +	_config = config; +	_points = config->getPoints(); +	strSettingsFile = settingsFile;													// Remember for Reset() + +	qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); +	setCaption(config->getTitle()); + +	// +	// Get the Function Points, one for each pixel in the horizontal range. +	// If the curve does not change, there is no need to run this code every time (it slows down drawing). +	// +	_draw_points.clear(); +	for (int j = 0; j < MaxInput * pPerEGU_Input; j++) { +		// +		// Weird: not casting to float causes C++ to round the number... +		// +		x = (float) j / (float) pPerEGU_Input; +		currentPoint.setX ( x ); +		currentPoint.setY (_config->getValue( x )); +		drawPoint = graphicalizePoint(currentPoint, "setConfig"); +		if (withinRect(drawPoint, range)) { +			_draw_points.append(drawPoint); +//	qDebug() << "QFunctionConfigurator::setConfig _draw_Point to add = " << drawPoint; +		} +	} +	 +	_draw_function = true; +	this->update(); +} + +// +// Load the FunctionConfig (points) from the INI-file. +// +void QFunctionConfigurator::loadSettings(QString settingsFile) { + +	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file) +	strSettingsFile = settingsFile;													// Remember for Reset() +	qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; +	if (_config) { +		_config->loadSettings(iniFile); +		setConfig(_config, settingsFile); +	} +} + +// +// Save the FunctionConfig (points) to the INI-file. +// +void QFunctionConfigurator::saveSettings(QString settingsFile) { +	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file) +	strSettingsFile = settingsFile;													// Remember for Reset() +	qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile; + +	if (_config) { +		_config->saveSettings(iniFile); +	} +} + +// +// Draw the Background for the graph, the gridlines and the gridpoints. +// The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up... +// +void QFunctionConfigurator::drawBackground(const QRectF &fullRect) +{ +int i; +QRect scale; + +	qDebug() << "QFunctionConfigurator::drawBackground."; + +	_background = QPixmap(fullRect.width(), fullRect.height()); +	QPainter painter(&_background); + +	painter.save(); +	painter.setRenderHint(QPainter::Antialiasing); +	painter.fillRect(fullRect, colBackground); +	QColor bg_color(112, 154, 209); +	painter.fillRect(range, bg_color); + +	QFont font("ComicSans", 4); +    font.setPointSize(8); +    painter.setFont(font); + +    QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine); + +	// +	// Draw the Caption +	// +	if (_config) { +		strCaption = _config->getTitle(); +	} + +	scale.setCoords(range.left(), 0, range.right(), 20); +	painter.drawText(scale, Qt::AlignCenter, strCaption); + +	// +	// Draw the horizontal grid +	// +	for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) { +		drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen); +		scale.setCoords(0, i - 5, range.left() - 5, i + 5); +		painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output)); +	} + +	// +	// Draw the vertical guidelines +	// +	for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) { +		drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen); +		scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15); +		painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input))); +	} + +	scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35); +	painter.drawText(scale, Qt::AlignRight, strInputEGU); + +	// +	// Draw the EGU of the vertical axis (vertically!) +	// +	font.setPointSize(10); +	painter.translate(range.topLeft().x() - 35, range.topLeft().y()); +	painter.rotate(90); +	painter.drawText(0,0,strOutputEGU ); + +	// +	// Draw the two axis +	// +	pen.setWidth(2); +	pen.setColor( Qt::black ); +	drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); +	drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); + +	painter.restore(); +} + + +// +// Draw the Function for the graph, on a Pixmap. +// +void QFunctionConfigurator::drawFunction(const QRectF &fullRect) +{ +	if (!_config) +		return; +int i; +QPointF prevPoint; +QPointF currentPoint; + +	// +	// Use the background picture to draw on. +	// ToDo: find out how to add Pixmaps, without getting it all green... +	// +	_function = QPixmap(_background); +	QPainter painter(&_function); + +	painter.save(); +    painter.setRenderHint(QPainter::Antialiasing, true); + +	// +	// Draw the handles for the Points +	// +	for (i = 0; i < _points.size(); i++) { +		currentPoint = graphicalizePoint( _points[i], "drawFunction handles" );		// Get the next point and convert it to Widget measures  +	    drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120)); +		lastPoint = currentPoint;											// Remember which point is the rightmost in the graph +//qDebug() << "QFunctionConfigurator::paintEvent, drawing handle for " << currentPoint; +	} + + +    QPen pen(colBezier, 1.5, Qt::SolidLine); + +	prevPoint = graphicalizePoint( QPointF(0,0), "drawFunction lines" );		// Start at the Axis +	double max = maxInputEGU(); +	QPointF prev = graphicalizePoint(QPointF(0, 0)); +    double step = 1 / (double) pixPerEGU_Input(); +	for (double i = 0; i < max; i += step) { +	    double val = _config->getValue(i); +	    QPointF cur = graphicalizePoint(QPointF(i, val)); +	    drawLine(&painter, prev, cur, pen); +		prev = cur; +	} +	painter.restore(); +} + +// +// The Widget paints the surface every x msecs. +// +void QFunctionConfigurator::paintEvent(QPaintEvent *e) +{ +QPointF prevPoint; +QPointF currentPoint; +QPointF actualPos; +int i; + +//	qDebug() << "QFunctionConfigurator::paintEvent."; + +	QPainter p(this); +    p.setRenderHint(QPainter::Antialiasing); +    p.setClipRect(e->rect()); + +	if (_draw_background) { +		drawBackground(e->rect());						// Draw the static parts on a Pixmap +		p.drawPixmap(0, 0, _background);				// Paint the background +		_draw_background = false; + +		btnReset->move(e->rect().left(), e->rect().bottom() - btnReset->height() - 2); +	} + +	if (_draw_function) { +		drawFunction(e->rect());						// Draw the Function on a Pixmap +		_draw_function = false; +	} +	p.drawPixmap(0, 0, _function);						// Always draw the background and the function + +	QPen pen(Qt::white, 1, Qt::SolidLine); + +	// +	// Draw the Points, that make up the Curve +	// +	if (_config) { + +		// +		// When moving, also draw a sketched version of the Function. +		// +		if (moving) { +			prevPoint = graphicalizePoint( QPointF(0,0), "paintEvent moving" );				// Start at the Axis +			for (i = 0; i < _points.size(); i++) { +				currentPoint = graphicalizePoint( _points[i], "paintEvent moving" );		// Get the next point and convert it to Widget measures  +				drawLine(&p, prevPoint, currentPoint, pen); +				prevPoint = currentPoint; +//	qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint; +			} + +			// +			// When moving, also draw a few help-lines, so positioning the point gets easier. +			// +			pen.setWidth(1); +			pen.setColor( Qt::white ); +			pen.setStyle( Qt::DashLine ); +			actualPos = graphicalizePoint(*moving, "paintEvent moving help line(s)"); +			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); +			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen); +		} + +		// +		// If the Tracker is active, the 'Last Point' it requested is recorded. +		// Show that point on the graph, with some lines to assist. +		// This new feature is very handy for tweaking the curves! +		// +		if (_config->getLastPoint( currentPoint )) { + +//	qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint; + +			actualPos = graphicalizePoint( currentPoint, "paintEvent tracking" ); +			drawPoint(&p, actualPos, QColor(255, 0, 0, 120)); + +			pen.setWidth(1); +			pen.setColor( Qt::black ); +			pen.setStyle( Qt::SolidLine ); +			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); +			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen); +		} + +	} + +	// +	// Draw the delimiters +	// +	pen.setWidth(1); +	pen.setColor( Qt::white ); +	pen.setStyle( Qt::SolidLine ); +	drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); +	drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); + +    QTimer::singleShot(50, this, SLOT(update())); +} + +// +// Draw the handle, to move the Bezier-curve. +// +void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG ) +{ +    painter->save(); +    painter->setPen(QColor(50, 100, 120, 200)); +    painter->setBrush( colBG ); +    painter->drawEllipse(QRectF(pos.x() - pointSize, +                                pos.y() - pointSize, +                                pointSize*2, pointSize*2)); +    painter->restore(); +} + +void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen) +{ +    painter->save(); +    painter->setPen(pen); +    painter->setBrush(Qt::NoBrush); +    painter->drawLine(start, end); +    painter->restore(); +} + +// +// If the mousebutton is pressed, check if it is inside one of the Points. +// If so: start moving that Point, until mouse release. +// +void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) +{ +	// +	// First: check the left mouse-button +	// +	if (e->button() == Qt::LeftButton) { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		bool bTouchingPoint = false; +		movingPoint = -1; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent markContains" ), e->pos() ) ) { +					bTouchingPoint = true; +		            moving = &_points[i]; +					movingPoint = i; +				} +			} + +			// +			// If the Left Mouse-button was clicked without touching a Point, add a new Point +			// +			if (!bTouchingPoint) { +				if (withinRect(e->pos(), range)) { +					_config->addPoint(normalizePoint(e->pos())); +					setConfig(_config, strSettingsFile); +					moving = NULL; +					emit CurveChanged( true ); +				} +			} +		} +	} + +	// +	// Then: check the right mouse-button +	// +	if (e->button() == Qt::RightButton) { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		moving = NULL; +		movingPoint = -1; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent RightButton" ), e->pos() ) ) { +					movingPoint = i; +				} +			} + +			// +			// If the Right Mouse-button was clicked while touching a Point, remove the Point +			// +			if (movingPoint >= 0) { +				_config->removePoint(movingPoint); +				setConfig(_config, strSettingsFile); +				movingPoint = -1; +				emit CurveChanged( true ); +			} +		} +	} + +} + +// +// If the mouse if moving, make sure the Bezier moves along. +// Of course, only when a Point is selected... +// +void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) +{ + +	if (moving) { + +		setCursor(Qt::ClosedHandCursor);		 + +		// +		// Change the currently moving Point. +		// +		*moving = normalizePoint(e->pos()); +		update(); +    } +	else { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		bool bTouchingPoint = false; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mouseMoveEvent" ), e->pos() ) ) { +					bTouchingPoint = true; +				} +			} +		} + +		if ( bTouchingPoint ) { +			setCursor(Qt::OpenHandCursor); +		} +		else { +			setCursor(Qt::ArrowCursor); +		} + +	} +} + +void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) +{ +    //qDebug()<<"releasing"; +	if (moving > 0) { +		emit CurveChanged( true ); + +		// +		// Update the Point in the _config +		// +		if (_config) { +			_config->movePoint(movingPoint, normalizePoint(e->pos())); +			setConfig(_config, strSettingsFile); +		} +	} +	setCursor(Qt::ArrowCursor);		 +	moving = NULL; +    movingPoint = 0; +} + +// +// Determine if the mousebutton was pressed within the range of the Point. +// +bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const +{ +    QRectF rect(pos.x() - pointSize, +                pos.y() - pointSize, +                pointSize*2, pointSize*2); +    QPainterPath path; +    path.addEllipse(rect); +    return path.contains(coord); +} + +bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect ) const +{ +    QPainterPath path; +    path.addRect(rect); +    return path.contains(coord); +} + +// +// Convert the Point in the graph, to the real-life Point. +// +QPointF QFunctionConfigurator::normalizePoint(QPointF point) const +{ +	QPointF norm; + +	norm.setX( (point.x() - range.left()) / pPerEGU_Input ); +    norm.setY( (range.bottom() - point.y()) / pPerEGU_Output ); + +	if (norm.x() > maxInputEGU()) +		norm.setX(maxInputEGU()); +	else if (norm.x() < 0) +		norm.setX(0); +	if (norm.y() > maxOutputEGU()) +		norm.setY(maxOutputEGU()); +	else if (norm.y() < 0) +		norm.setY(0); + +	return norm; +} + +// +// Convert the real-life Point into the graphical Point. +// +QPointF QFunctionConfigurator::graphicalizePoint(QPointF point, QString source) const +{ +QPointF graph; + +	graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) ); +	graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) ); + +//	qDebug() << "QFunctionConfigurator::graphicalizePoint source = " << source << ", point = " << point << ", graph = " << graph; + +	return graph; +} + +void QFunctionConfigurator::setmaxInputEGU(int value) +{ +    MaxInput = value; +	setMinimumWidth(MaxInput * pPerEGU_Input + 55); +//	resetCurve(); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} +void QFunctionConfigurator::setmaxOutputEGU(int value) +{ +    MaxOutput = value; +	setMinimumHeight(MaxOutput * pPerEGU_Output + 60); +//	resetCurve(); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. +// +void QFunctionConfigurator::setpixPerEGU_Input(int value) +{ +    pPerEGU_Input = value; +	setMinimumWidth(MaxInput * pPerEGU_Input + 55); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. +// +void QFunctionConfigurator::setpixPerEGU_Output(int value) +{ +    pPerEGU_Output = value; +	setMinimumHeight(MaxOutput * pPerEGU_Output + 60); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// Define the distance of the grid 'in EGU' points. +// +void QFunctionConfigurator::setgridDistEGU_Input(int value) +{ +    gDistEGU_Input = value; +	_draw_background = true; +	_draw_function = true; +	repaint(); +} + +// +// Define the distance of the grid 'in EGU' points. +// +void QFunctionConfigurator::setgridDistEGU_Output(int value) +{ +    gDistEGU_Output = value; +	_draw_background = true; +	_draw_function = true; +	repaint(); +} + +void QFunctionConfigurator::setColorBezier(QColor color) +{ +    colBezier = color; +    update(); +} +void QFunctionConfigurator::setColorBackground(QColor color) +{ +    colBackground = color; +    update(); +} + +void QFunctionConfigurator::setInputEGU(QString egu) +{ +    strInputEGU = egu; +    update(); +} +void QFunctionConfigurator::setOutputEGU(QString egu) +{ +    strOutputEGU = egu; +    update(); +} +void QFunctionConfigurator::setCaption(QString cap) +{ +    strCaption = cap; +    update(); +} + +void QFunctionConfigurator::resizeEvent(QResizeEvent *e) +{ +	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + +	qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range; + +	if (_config) { +		setConfig(_config, strSettingsFile); +	} +	_draw_background = true; +	_draw_function = true; +	repaint(); +} diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index c467bc92..6ad810c1 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -1,206 +1,207 @@ -/********************************************************************************
 -* FaceTrackNoIR		This program is a private project of some enthusiastic		*
 -*					gamers from Holland, who don't like to pay much for			*
 -*					head-tracking.												*
 -*																				*
 -* Copyright (C) 2012	Wim Vriend (Developing)									*
 -*						Ron Hendriks (Researching and Testing)					*
 -*																				*
 -* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				*
 -*																				*
 -* 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 <http://www.gnu.org/licenses/>.				*
 -*																				*
 -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          *
 -* FaceTrackNoIR.																*
 -*																				*
 -* All credits for this nice piece of code should go to Stanislaw.				*
 -*																				*
 -* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					*
 -* Permission to use, copy, modify, and/or distribute this						*
 -* software for any purpose with or without fee is hereby granted,				*
 -* provided that the above copyright notice and this permission					*
 -* notice appear in all copies.													*
 -********************************************************************************/
 -#ifndef QFUNCTIONCONFIGURATOR_H
 -#define QFUNCTIONCONFIGURATOR_H
 -
 -#include <QtGui>
 -#include <QtDesigner/QDesignerExportWidget>
 -#include <QPointF>
 -#include "FunctionConfig.h"
 -
 -//
 -// The FunctionConfigurator Widget is used to display and configure a function (curve).
 -// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function.
 -//
 -// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the
 -// Widget and the Widget used to change the Function.
 -//
 -class QDESIGNER_WIDGET_EXPORT QFunctionConfigurator : public QWidget
 -{
 -	Q_OBJECT
 -    Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU);
 -    Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU);
 -    Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input);
 -    Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output);
 -    Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input);
 -    Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output);
 -
 -	Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier);
 -    Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground);
 -    Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU);
 -    Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU);
 -    Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption);
 -
 -	// Return the current value to Designer
 -	int maxInputEGU() const
 -    {
 -        return MaxInput;
 -    }
 -	int maxOutputEGU() const
 -    {
 -        return MaxOutput;
 -    }
 -	int pixPerEGU_Input() const
 -    {
 -        return pPerEGU_Input;
 -    }
 -	int pixPerEGU_Output() const
 -    {
 -        return pPerEGU_Output;
 -    }
 -	int gridDistEGU_Input() const
 -    {
 -        return gDistEGU_Input;
 -    }
 -	int gridDistEGU_Output() const
 -    {
 -        return gDistEGU_Output;
 -    }
 -
 -	// Return the current color to Designer
 -	QColor colorBezier() const
 -    {
 -        return colBezier;
 -    }
 -	// Return the current color to Designer
 -	QColor colorBackground() const
 -    {
 -        return colBackground;
 -    }
 -	// Return the current string to Designer
 -	QString stringInputEGU() const
 -    {
 -        return strInputEGU;
 -    }
 -	// Return the current string to Designer
 -	QString stringOutputEGU() const
 -    {
 -        return strOutputEGU;
 -    }
 -	// Return the current string to Designer
 -	QString stringCaption() const
 -    {
 -        return strCaption;
 -    }
 -
 -public:
 -	QFunctionConfigurator(QWidget *parent = 0);
 -	~QFunctionConfigurator();
 -	FunctionConfig* config();
 -
 -	void setConfig(FunctionConfig* config, QString settingsFile);		// Connect the FunctionConfig to the Widget.
 -	void loadSettings(QString settingsFile);							// Load the FunctionConfig (points) from the INI-file
 -	void saveSettings(QString settingsFile);							// Save the FunctionConfig (points) to the INI-file
 -
 -signals:
 -    void CurveChanged(bool);
 -
 -public slots:
 -    void setmaxInputEGU(int);
 -    void setmaxOutputEGU(int);
 -    void setpixPerEGU_Input(int);
 -    void setpixPerEGU_Output(int);
 -    void setgridDistEGU_Input(int);
 -    void setgridDistEGU_Output(int);
 -
 -    void setColorBezier(QColor);
 -    void setColorBackground(QColor);
 -    void setInputEGU(QString);
 -    void setOutputEGU(QString);
 -    void setCaption(QString);
 -
 -	void resetCurve() {
 -		qDebug() << "QFunctionConfigurator::resetCurve = " << strSettingsFile;
 -		loadSettings( strSettingsFile );
 -	}
 -
 -protected slots:
 -	void paintEvent(QPaintEvent *e);
 -	void mousePressEvent(QMouseEvent *e);
 -	void mouseMoveEvent(QMouseEvent *e);
 -	void mouseReleaseEvent(QMouseEvent *e);
 -      
 -protected:
 -	void drawBackground(const QRectF &rect);
 -	void drawFunction(const QRectF &rect);
 -	void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG );
 -	void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen);
 -	bool markContains(const QPointF &pt, const QPointF &coord) const;
 -//	bool withinRange( const QPointF &coord ) const;
 -	bool withinRect( const QPointF &coord, const QRectF &rect ) const;
 -
 -protected:
 -	virtual void resizeEvent(QResizeEvent *);
 -
 -private:
 -	QRectF  range;														// The actual rectangle for the Bezier-curve
 -	QPointF lastPoint;													// The right-most point of the Function
 -	QPointF normalizePoint (QPointF point) const;						// Convert the graphical Point to a real-life Point
 -	QPointF graphicalizePoint (QPointF point, QString source = "") const;	// Convert the Point to a graphical Point
 -
 -	QPointF *moving;
 -	int     movingPoint;
 -
 -	int MaxInput;					// Maximum input limit
 -	int MaxOutput;					// Maximum output limit
 -	int pPerEGU_Input;				// Number of pixels, per EGU of Input
 -	int pPerEGU_Output;				// Number of pixels, per EGU of Output
 -	int gDistEGU_Input;				// Distance of the grid, in EGU of Input
 -	int gDistEGU_Output;			// Distance of the grid, in EGU of Output
 -
 -	QColor colBezier;				// Color of Bezier curve
 -	QColor colBackground;			// Color of widget background
 -	QString strInputEGU;			// Engineering Units input (vertical axis)
 -	QString strOutputEGU;			// Engineering Units output (horizontal axis)
 -	QString strCaption;				// Caption of the graph
 -	QString strSettingsFile;		// Name of last read INI-file
 -	QPushButton *btnReset;			// Reset Curve
 -
 -	bool _draw_background;			// Flag to determine if the background should be (re-)drawn on the QPixmap
 -	QPixmap _background;			// Image of the static parts (axis, lines, etc.)
 -	bool _draw_function;			// Flag to determine if the function should be (re-)drawn on the QPixmap
 -	QPixmap _function;				// Image of the function (static unless edited by the user)
 -
 -	//
 -	// Properties of the CurveConfigurator Widget
 -	//
 -	QString _title;								// Title do display in Widget and to load Settings
 -	FunctionConfig* _config;
 -	QList<QPointF> _points;			// Function-points
 -	QList<QPointF> _draw_points;	// Curve-points needed for drawing
 -	HANDLE _mutex;
 -};
 -
 -#endif // QFUNCTIONCONFIGURATOR_H
 +/******************************************************************************** +* FaceTrackNoIR		This program is a private project of some enthusiastic		* +*					gamers from Holland, who don't like to pay much for			* +*					head-tracking.												* +*																				* +* Copyright (C) 2012	Wim Vriend (Developing)									* +*						Ron Hendriks (Researching and Testing)					* +*																				* +* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				* +*																				* +* 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 <http://www.gnu.org/licenses/>.				* +*																				* +* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          * +* FaceTrackNoIR.																* +*																				* +* All credits for this nice piece of code should go to Stanislaw.				* +*																				* +* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					* +* Permission to use, copy, modify, and/or distribute this						* +* software for any purpose with or without fee is hereby granted,				* +* provided that the above copyright notice and this permission					* +* notice appear in all copies.													* +********************************************************************************/ +#ifndef QFUNCTIONCONFIGURATOR_H +#define QFUNCTIONCONFIGURATOR_H + +#include <QWidget> +#include <QtGui> +#include <QtDesigner/QDesignerExportWidget> +#include <QPointF> +#include "qfunctionconfigurator/functionconfig.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" + +// +// The FunctionConfigurator Widget is used to display and configure a function (curve). +// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function. +// +// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the +// Widget and the Widget used to change the Function. +// +class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget +{ +	Q_OBJECT +    Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU); +    Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU); +    Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input); +    Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output); +    Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input); +    Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output); + +	Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier); +    Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground); +    Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU); +    Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU); +    Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption); + +	// Return the current value to Designer +	int maxInputEGU() const +    { +        return MaxInput; +    } +	int maxOutputEGU() const +    { +        return MaxOutput; +    } +	int pixPerEGU_Input() const +    { +        return pPerEGU_Input; +    } +	int pixPerEGU_Output() const +    { +        return pPerEGU_Output; +    } +	int gridDistEGU_Input() const +    { +        return gDistEGU_Input; +    } +	int gridDistEGU_Output() const +    { +        return gDistEGU_Output; +    } + +	// Return the current color to Designer +	QColor colorBezier() const +    { +        return colBezier; +    } +	// Return the current color to Designer +	QColor colorBackground() const +    { +        return colBackground; +    } +	// Return the current string to Designer +	QString stringInputEGU() const +    { +        return strInputEGU; +    } +	// Return the current string to Designer +	QString stringOutputEGU() const +    { +        return strOutputEGU; +    } +	// Return the current string to Designer +	QString stringCaption() const +    { +        return strCaption; +    } + +public: +	QFunctionConfigurator(QWidget *parent = 0); +	~QFunctionConfigurator(); +	FunctionConfig* config(); + +	void setConfig(FunctionConfig* config, QString settingsFile);		// Connect the FunctionConfig to the Widget. +	void loadSettings(QString settingsFile);							// Load the FunctionConfig (points) from the INI-file +	void saveSettings(QString settingsFile);							// Save the FunctionConfig (points) to the INI-file + +signals: +    void CurveChanged(bool); + +public slots: +    void setmaxInputEGU(int); +    void setmaxOutputEGU(int); +    void setpixPerEGU_Input(int); +    void setpixPerEGU_Output(int); +    void setgridDistEGU_Input(int); +    void setgridDistEGU_Output(int); + +    void setColorBezier(QColor); +    void setColorBackground(QColor); +    void setInputEGU(QString); +    void setOutputEGU(QString); +    void setCaption(QString); + +	void resetCurve() { +		qDebug() << "QFunctionConfigurator::resetCurve = " << strSettingsFile; +		loadSettings( strSettingsFile ); +	} + +protected slots: +	void paintEvent(QPaintEvent *e); +	void mousePressEvent(QMouseEvent *e); +	void mouseMoveEvent(QMouseEvent *e); +	void mouseReleaseEvent(QMouseEvent *e); +       +protected: +	void drawBackground(const QRectF &rect); +	void drawFunction(const QRectF &rect); +	void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); +	void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); +	bool markContains(const QPointF &pt, const QPointF &coord) const; +//	bool withinRange( const QPointF &coord ) const; +	bool withinRect( const QPointF &coord, const QRectF &rect ) const; + +protected: +	virtual void resizeEvent(QResizeEvent *); + +private: +	QRectF  range;														// The actual rectangle for the Bezier-curve +	QPointF lastPoint;													// The right-most point of the Function +	QPointF normalizePoint (QPointF point) const;						// Convert the graphical Point to a real-life Point +	QPointF graphicalizePoint (QPointF point, QString source = "") const;	// Convert the Point to a graphical Point + +	QPointF *moving; +	int     movingPoint; + +	int MaxInput;					// Maximum input limit +	int MaxOutput;					// Maximum output limit +	int pPerEGU_Input;				// Number of pixels, per EGU of Input +	int pPerEGU_Output;				// Number of pixels, per EGU of Output +	int gDistEGU_Input;				// Distance of the grid, in EGU of Input +	int gDistEGU_Output;			// Distance of the grid, in EGU of Output + +	QColor colBezier;				// Color of Bezier curve +	QColor colBackground;			// Color of widget background +	QString strInputEGU;			// Engineering Units input (vertical axis) +	QString strOutputEGU;			// Engineering Units output (horizontal axis) +	QString strCaption;				// Caption of the graph +	QString strSettingsFile;		// Name of last read INI-file +	QPushButton *btnReset;			// Reset Curve + +	bool _draw_background;			// Flag to determine if the background should be (re-)drawn on the QPixmap +	QPixmap _background;			// Image of the static parts (axis, lines, etc.) +	bool _draw_function;			// Flag to determine if the function should be (re-)drawn on the QPixmap +	QPixmap _function;				// Image of the function (static unless edited by the user) + +	// +	// Properties of the CurveConfigurator Widget +	// +	QString _title;								// Title do display in Widget and to load Settings +	FunctionConfig* _config; +	QList<QPointF> _points;			// Function-points +	QList<QPointF> _draw_points;	// Curve-points needed for drawing +}; + +#endif // QFUNCTIONCONFIGURATOR_H diff --git a/x-plane-plugin/plugin.c b/x-plane-plugin/plugin.c new file mode 100644 index 00000000..fc1a5186 --- /dev/null +++ b/x-plane-plugin/plugin.c @@ -0,0 +1,185 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/file.h> +#include <sys/mman.h> +#include <limits.h> +#include <unistd.h> + +#include <XPLMPlugin.h> +#include <XPLMDisplay.h> +#include <XPLMDataAccess.h> +#include <XPLMCamera.h> +#include <XPLMProcessing.h> + +// using Wine name to ease things +#define WINE_SHM_NAME "facetracknoir-wine-shm" +#define WINE_MTX_NAME "facetracknoir-wine-mtx" + +typedef struct PortableLockedShm { +    void* mem; +    int fd, size; +} PortableLockedShm; + +typedef struct WineSHM { +    float rx, ry, rz, tx, ty, tz; +    char stop; +} WineSHM; + +static PortableLockedShm* lck_posix = NULL; +static WineSHM* shm_posix = NULL; +static void *view_x, *view_y, *view_z, *view_heading, *view_pitch; +static float offset_x, offset_y, offset_z; + +PortableLockedShm* PortableLockedShm_init(const char *shmName, const char *mutexName, int mapSize) +{ +    PortableLockedShm* self = malloc(sizeof(PortableLockedShm)); +    char shm_filename[NAME_MAX]; +    shm_filename[0] = '/'; +    strncpy(shm_filename+1, shmName, NAME_MAX-2); +    shm_filename[NAME_MAX-1] = '\0'; +    sprintf(shm_filename + strlen(shm_filename), "%ld\n", (long) getuid()); +    //(void) shm_unlink(shm_filename); +     +    self->fd = shm_open(shm_filename, O_RDWR | O_CREAT, 0600); +    if (ftruncate(self->fd, mapSize) == 0) +        self->mem = mmap(NULL, mapSize, PROT_READ|PROT_WRITE, MAP_SHARED, self->fd, (off_t)0); +    else +        self->mem = (void*) -1; +    return self; +} + +void PortableLockedShm_free(PortableLockedShm* self) +{ +    //(void) shm_unlink(shm_filename); +    (void) munmap(self->mem, self->size); +    (void) close(self->fd); +    free(self); +} + +void PortableLockedShm_lock(PortableLockedShm* self) +{ +    flock(self->fd, LOCK_SH); +} + +void PortableLockedShm_unlock(PortableLockedShm* self) +{ +    flock(self->fd, LOCK_UN); +} + +static void reinit_offset() { +    offset_x = XPLMGetDataf(view_x); +    offset_y = XPLMGetDataf(view_y); +    offset_z = XPLMGetDataf(view_z); +} + +int write_head_position( +    XPLMDrawingPhase     inPhase,     +    int                  inIsBefore,     +    void *               inRefcon) +{ +    if (lck_posix != NULL && shm_posix != NULL) { +        PortableLockedShm_lock(lck_posix); +        XPLMSetDataf(view_x, shm_posix->tx * 1e-2 + offset_x); +        XPLMSetDataf(view_y, shm_posix->ty * 1e-2 + offset_y); +        XPLMSetDataf(view_z, shm_posix->tz * 1e-2 + offset_z); +        XPLMSetDataf(view_heading, shm_posix->rx * 57.295781); +        XPLMSetDataf(view_pitch, shm_posix->ry * 57.295781); +        PortableLockedShm_unlock(lck_posix); +    } +    return 1; +} + +PLUGIN_API int XPluginStart ( char * outName, char * outSignature, char * outDescription ) { +    view_x = XPLMFindDataRef("sim/aircraft/view/acf_peX"); +    view_y = XPLMFindDataRef("sim/aircraft/view/acf_peY"); +    view_z = XPLMFindDataRef("sim/aircraft/view/acf_peZ"); +    view_heading = XPLMFindDataRef("sim/graphics/view/pilots_head_psi"); +    view_pitch = XPLMFindDataRef("sim/graphics/view/pilots_head_the"); +    if (view_x && view_y && view_z && view_heading && view_pitch) { +        lck_posix = PortableLockedShm_init(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); +        if (lck_posix->mem == (void*)-1) { +            fprintf(stderr, "FTNOIR failed to init SHM #1!\n"); +            return 0; +        } +        if (lck_posix->mem == NULL) { +            fprintf(stderr, "FTNOIR failed to init SHM #2!\n"); +            return 0; +        } +        shm_posix = (WineSHM*) lck_posix->mem; +        memset(shm_posix, 0, sizeof(WineSHM)); +        strcpy(outName, "FaceTrackNoIR"); +        strcpy(outSignature, "FaceTrackNoIR - FreeTrack lives!"); +        strcpy(outDescription, "Face tracking view control"); +        fprintf(stderr, "FTNOIR init complete\n"); +        return 1; +    } +    return 0; +} + +#if 0 +static int camera_callback(XPLMCameraPosition_t* outCameraPosition, int inIsLosingControl, void* inRefCon) { +    if (!inIsLosingControl && XPLMGetCycleNumber() > 0) { +        //XPLMReadCameraPosition(outCameraPosition); +        PortableLockedShm_lock(lck_posix); +        outCameraPosition->heading = shm_posix->rx * 57.295781; +        outCameraPosition->pitch = shm_posix->ry * 57.295781; +        outCameraPosition->roll = shm_posix->rz * 57.295781; +        outCameraPosition->x = XPLMGetDataf(view_x); +        outCameraPosition->y = XPLMGetDataf(view_y); +        outCameraPosition->z = XPLMGetDataf(view_z); +        PortableLockedShm_unlock(lck_posix); +        return 1; +    } +    return 0; +} +static float flight_loop ( +    float                inElapsedSinceLastCall,     +    float                inElapsedTimeSinceLastFlightLoop,     +    int                  inCounter,     +    void *               inRefcon) +{ +    XPLMControlCamera(xplm_ControlCameraForever, camera_callback, NULL); +    // don't want it called anymore +    return 0; +} +#endif + +PLUGIN_API void XPluginStop ( void ) { +#if 0 +    // crashes due to race +    if (lck_posix) +        PortableLockedShm_free(lck_posix); +    lck_posix = NULL; +    shm_posix = NULL; +#endif +} + +PLUGIN_API void XPluginEnable ( void ) { +    reinit_offset(); +    XPLMRegisterDrawCallback(write_head_position, xplm_Phase_LastScene, 1, NULL); +#if 0 +    XPLMRegisterFlightLoopCallback(flight_loop, -1, NULL); +#endif +} + +PLUGIN_API void XPluginDisable ( void ) { +    XPLMUnregisterDrawCallback(write_head_position, xplm_Phase_LastScene, 1, NULL); +    XPLMSetDataf(view_x, offset_x); +    XPLMSetDataf(view_y, offset_y); +    XPLMSetDataf(view_z, offset_z); +#if 0 +    XPLMUnregisterFlightLoopCallback(flight_loop, NULL); +    if (XPLMIsCameraBeingControlled(NULL)) +        XPLMDontControlCamera(); +#endif +} + +PLUGIN_API void XPluginReceiveMessage( +    XPLMPluginID    inFromWho, +    int             inMessage, +    void *          inParam) +{ +    if (inMessage == XPLM_MSG_AIRPORT_LOADED) +        reinit_offset(); +} diff --git a/x-plane-plugin/version-script.txt b/x-plane-plugin/version-script.txt new file mode 100644 index 00000000..cfb84ec8 --- /dev/null +++ b/x-plane-plugin/version-script.txt @@ -0,0 +1,10 @@ +{ + global: +  XPluginStart; +  XPluginStop; +  XPluginEnable; +  XPluginDisable; +  XPluginReceiveMessage; + local: +   *; +}; | 
