summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2013-04-02 18:41:01 +0200
committerStanislaw Halik <sthalik@misaki.pl>2013-04-02 18:41:01 +0200
commit8303597a865400a363ae574ccde819302495f498 (patch)
treec83b383b3ec818f610cc6137f2b72ee7b4173b09
parent8adf6b1650af6027f28db12ca2b4de92a3fac11d (diff)
Just put everything new in. Conflict resolution will be later
-rw-r--r--compat/compat.cpp84
-rw-r--r--compat/compat.h42
-rw-r--r--faceapi/ftnoir-faceapi-wrapper.exe.manifest15
-rw-r--r--faceapi/ftnoir-faceapi-wrapper.rc2
-rw-r--r--faceapi/main.cpp11
-rw-r--r--faceapi/mutex.h4
-rw-r--r--faceapi/stdafx.h27
-rw-r--r--faceapi/utils.h5
-rw-r--r--facetracknoir/ClientFiles/FlightGear/win32/start_fg.bat1
-rw-r--r--facetracknoir/ClientFiles/Tir4Fun/readme.txt18
-rw-r--r--facetracknoir/facetracknoir.cpp1572
-rw-r--r--facetracknoir/facetracknoir.h177
-rw-r--r--facetracknoir/facetracknoir.icobin0 -> 23558 bytes
-rw-r--r--facetracknoir/facetracknoir.rc84
-rw-r--r--facetracknoir/ftnoir_curves.ui930
-rw-r--r--facetracknoir/ftnoir_fsuipccontrols.ui4
-rw-r--r--facetracknoir/ftnoir_ftnservercontrols.ui2
-rw-r--r--facetracknoir/ftnoir_keyboardshortcuts.ui316
-rw-r--r--facetracknoir/ftnoir_preferences.ui2
-rw-r--r--facetracknoir/global-settings.cpp142
-rw-r--r--facetracknoir/global-settings.h85
-rw-r--r--facetracknoir/global-shortcuts.cpp135
-rw-r--r--facetracknoir/images/facetracknoir.icobin0 -> 23558 bytes
-rw-r--r--facetracknoir/main.cpp20
-rw-r--r--facetracknoir/posix-version-script.txt8
-rw-r--r--facetracknoir/rotation.cpp2
-rw-r--r--facetracknoir/rotation.h2
-rw-r--r--facetracknoir/spot.h27
-rw-r--r--facetracknoir/tracker.cpp1186
-rw-r--r--facetracknoir/tracker.h278
-rw-r--r--facetracknoir/tracker_types.h6
-rw-r--r--facetracknoir/uielements/facetracknoir.icobin0 -> 23558 bytes
-rw-r--r--facetracknoir/uielements/setupfacetracknoir.jpgbin0 -> 21508 bytes
-rw-r--r--ftnoir_filter_accela/default-points.cpp38
-rw-r--r--ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui451
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.cpp31
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.h65
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp23
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp9
-rw-r--r--ftnoir_filter_base/ftnoir_filter_base.h51
-rw-r--r--ftnoir_filter_base/ftnoir_filter_base_global.h2
-rw-r--r--ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui587
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp19
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2.h18
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp12
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp5
-rw-r--r--ftnoir_posewidget/glwidget.cpp22
-rw-r--r--ftnoir_posewidget/glwidget.h3
-rw-r--r--ftnoir_protocol_base/ftnoir_protocol_base.h54
-rw-r--r--ftnoir_protocol_base/ftnoir_protocol_base_global.h2
-rw-r--r--ftnoir_protocol_fg/fgtypes.h5
-rw-r--r--ftnoir_protocol_fg/ftnoir_fgcontrols.ui2
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg.cpp20
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg.h20
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp14
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp7
-rw-r--r--ftnoir_protocol_fg/images/flightgear.icobin0 -> 13094 bytes
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui2
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp38
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h11
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp7
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp5
-rw-r--r--ftnoir_protocol_fsuipc/images/fs9.icobin0 -> 29926 bytes
-rw-r--r--ftnoir_protocol_ft/FreeTrackClient.c330
-rw-r--r--ftnoir_protocol_ft/ftnoir_ftcontrols.ui302
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft.cpp321
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft.h42
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp80
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp7
-rw-r--r--ftnoir_protocol_ft/fttypes.h33
-rw-r--r--ftnoir_protocol_ft/images/freetrack.icobin0 -> 17542 bytes
-rw-r--r--ftnoir_protocol_ftn/ftnoir_ftncontrols.ui2
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp80
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn.h40
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp9
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp5
-rw-r--r--ftnoir_protocol_ftn/images/facetracknoir.icobin0 -> 23558 bytes
-rw-r--r--ftnoir_protocol_mouse/ftnoir_mousecontrols.ui2
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp50
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse.h16
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp9
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp7
-rw-r--r--ftnoir_protocol_mouse/images/mouse.icobin0 -> 17542 bytes
-rw-r--r--ftnoir_protocol_sc/ftnoir-protocol-sc.rc2
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc.cpp92
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc.h20
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp7
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp3
-rw-r--r--ftnoir_protocol_sc/ftnoir_sccontrols.ui2
-rw-r--r--ftnoir_protocol_sc/images/fsx.icobin0 -> 87910 bytes
-rw-r--r--ftnoir_protocol_wine/images/wine.icobin0 -> 36451 bytes
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_base.h43
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_base_global.h2
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_sm_types.h7
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_types.h2
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht.cpp106
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht.h6
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h4
-rw-r--r--ftnoir_tracker_ht/ht-api.h56
-rw-r--r--ftnoir_tracker_ht/images/ht.icobin0 -> 15086 bytes
-rw-r--r--ftnoir_tracker_ht/trackercontrols.ui301
-rw-r--r--ftnoir_tracker_ht/video_widget.cpp69
-rw-r--r--ftnoir_tracker_ht/video_widget.h42
-rw-r--r--ftnoir_tracker_pt/Resources/icon.icobin0 -> 4286 bytes
-rw-r--r--ftnoir_tracker_pt/camera.cpp58
-rw-r--r--ftnoir_tracker_pt/camera.h20
-rw-r--r--ftnoir_tracker_pt/ftnoir_pt_controls.ui21
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.cpp82
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.h28
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp11
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h6
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp8
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h7
-rw-r--r--ftnoir_tracker_pt/point_extractor.cpp15
-rw-r--r--ftnoir_tracker_pt/point_tracker.cpp22
-rw-r--r--ftnoir_tracker_pt/point_tracker.h4
-rw-r--r--ftnoir_tracker_pt/timer.cpp3
-rw-r--r--ftnoir_tracker_pt/video_widget.cpp60
-rw-r--r--ftnoir_tracker_pt/video_widget.h17
-rw-r--r--ftnoir_tracker_sm/ftnoir_sm_controls.ui4
-rw-r--r--ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp88
-rw-r--r--ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp7
-rw-r--r--ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp7
-rw-r--r--ftnoir_tracker_sm/ftnoir_tracker_sm.h8
-rw-r--r--ftnoir_tracker_sm/images/sm.icobin0 -> 37798 bytes
-rw-r--r--ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui2
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp.cpp105
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp.h32
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp7
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp7
-rw-r--r--qfunctionconfigurator/functionconfig.cppbin17350 -> 9271 bytes
-rw-r--r--qfunctionconfigurator/functionconfig.hbin3888 -> 1964 bytes
-rw-r--r--qfunctionconfigurator/qfunctionconfigurator.cpp1421
-rw-r--r--qfunctionconfigurator/qfunctionconfigurator.h413
-rw-r--r--x-plane-plugin/plugin.c185
-rw-r--r--x-plane-plugin/version-script.txt10
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.ico
new file mode 100644
index 00000000..5115066c
--- /dev/null
+++ b/facetracknoir/facetracknoir.ico
Binary files differ
diff --git a/facetracknoir/facetracknoir.rc b/facetracknoir/facetracknoir.rc
index ed8a68c1..fcae12b3 100644
--- a/facetracknoir/facetracknoir.rc
+++ b/facetracknoir/facetracknoir.rc
@@ -1,84 +1,2 @@
-// Microsoft Visual C++ generated resource script.
-//
#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// Dutch (Neutral) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NLD)
-#ifdef _WIN32
-LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_ICON1 ICON "FaceTrackNoIR.ico"
-#endif // Dutch (Neutral) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-/////////////////////////////////////////////////////////////////////////////
-// German (Germany) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
-#ifdef _WIN32
-LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""afxres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-#endif // German (Germany) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
+IDI_ICON1 ICON "facetracknoir.ico"
diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui
index 19c68cf0..5bbe48be 100644
--- a/facetracknoir/ftnoir_curves.ui
+++ b/facetracknoir/ftnoir_curves.ui
@@ -6,8 +6,8 @@
<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.ico
new file mode 100644
index 00000000..5115066c
--- /dev/null
+++ b/facetracknoir/images/facetracknoir.ico
Binary files differ
diff --git a/facetracknoir/main.cpp b/facetracknoir/main.cpp
index 6e0549d7..d2eb84cc 100644
--- a/facetracknoir/main.cpp
+++ b/facetracknoir/main.cpp
@@ -27,28 +27,28 @@
messages from the Game.
*/
-#include "FaceApp.h"
-#include "FaceTrackNoIR.h"
+#include "facetracknoir.h"
+#include "tracker.h"
#include <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(&current_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(&current_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.ico
new file mode 100644
index 00000000..af36ec30
--- /dev/null
+++ b/facetracknoir/uielements/facetracknoir.ico
Binary files differ
diff --git a/facetracknoir/uielements/setupfacetracknoir.jpg b/facetracknoir/uielements/setupfacetracknoir.jpg
new file mode 100644
index 00000000..8778c6d5
--- /dev/null
+++ b/facetracknoir/uielements/setupfacetracknoir.jpg
Binary files differ
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>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Min. frames:&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Defines the way the filter responds to fast movements;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Higher value: slower response;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Max. frames:&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Defines the way the filter responds to slow movements;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Higher value: slower response;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Pow:&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Defines the filters 'readiness' to respond to speed changes;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Higher value = &lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;higher&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; response;&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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.ico
new file mode 100644
index 00000000..f96c0f88
--- /dev/null
+++ b/ftnoir_protocol_fg/images/flightgear.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..9afd1953
--- /dev/null
+++ b/ftnoir_protocol_fsuipc/images/fs9.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..02554c3d
--- /dev/null
+++ b/ftnoir_protocol_ft/images/freetrack.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..5115066c
--- /dev/null
+++ b/ftnoir_protocol_ftn/images/facetracknoir.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..1151ab2b
--- /dev/null
+++ b/ftnoir_protocol_mouse/images/mouse.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..1c71d409
--- /dev/null
+++ b/ftnoir_protocol_sc/images/fsx.ico
Binary files differ
diff --git a/ftnoir_protocol_wine/images/wine.ico b/ftnoir_protocol_wine/images/wine.ico
new file mode 100644
index 00000000..58edbb62
--- /dev/null
+++ b/ftnoir_protocol_wine/images/wine.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..7555ce25
--- /dev/null
+++ b/ftnoir_tracker_ht/images/ht.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..c4b2aedc
--- /dev/null
+++ b/ftnoir_tracker_pt/Resources/icon.ico
Binary files differ
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.ico
new file mode 100644
index 00000000..19b24c84
--- /dev/null
+++ b/ftnoir_tracker_sm/images/sm.ico
Binary files differ
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.cpp
index 243564d1..25d5599a 100644
--- a/qfunctionconfigurator/functionconfig.cpp
+++ b/qfunctionconfigurator/functionconfig.cpp
Binary files differ
diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h
index 8dc9cf98..281007d6 100644
--- a/qfunctionconfigurator/functionconfig.h
+++ b/qfunctionconfigurator/functionconfig.h
Binary files differ
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:
+ *;
+};