diff options
-rw-r--r-- | facetracknoir/tracker.cpp | 432 | ||||
-rw-r--r-- | ftnoir_filter_accela/ftnoir_filter_accela.cpp | 174 | ||||
-rw-r--r-- | ftnoir_filter_accela/ftnoir_filter_accela.h | 216 | ||||
-rw-r--r-- | ftnoir_filter_base/ftnoir_filter_base.h | 82 | ||||
-rw-r--r-- | ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp | 342 | ||||
-rw-r--r-- | ftnoir_filter_ewma2/ftnoir_filter_ewma2.h | 230 |
6 files changed, 738 insertions, 738 deletions
diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp index 5acf7dea..981be4b7 100644 --- a/facetracknoir/tracker.cpp +++ b/facetracknoir/tracker.cpp @@ -1,217 +1,217 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of the some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 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/>. * -*********************************************************************************/ -#include "tracker.h" -#include "facetracknoir.h" - -/** constructor **/ -Tracker::Tracker( FaceTrackNoIR *parent ) : - should_quit(false), - do_center(false) -{ - // Retieve the pointer to the parent - mainApp = parent; - // Load the settings from the INI-file - loadSettings(); -} - -Tracker::~Tracker() -{ -} - -static void get_curve(double pos, double& out, THeadPoseDOF& axis) { - bool altp = (pos < 0) && axis.altp; - if (altp) { - out = axis.invert * axis.curveAlt.getValue(pos); - axis.curve.setTrackingActive( false ); - axis.curveAlt.setTrackingActive( true ); - } - else { - out = axis.invert * axis.curve.getValue(pos); - axis.curve.setTrackingActive( true ); - axis.curveAlt.setTrackingActive( false ); - } - out += axis.zero; -} - -/** QThread run method @override **/ -void Tracker::run() { - T6DOF target_camera; - T6DOF new_camera; - - /** Direct Input variables **/ - T6DOF offset_camera; - T6DOF gameoutput_camera; - - bool bTracker1Confid = false; - bool bTracker2Confid = false; - - double newpose[6]; - double last_post_filter[6]; - - forever - { - if (should_quit) - break; - - for (int i = 0; i < 6; i++) - newpose[i] = 0; - - // - // 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); - } - - { - QMutexLocker foo(&mtx); - const bool confid = bTracker1Confid || bTracker2Confid; - - if ( confid ) { - for (int i = 0; i < 6; i++) - mainApp->axis(i).headPos = newpose[i]; - } - - // - // If Center is pressed, copy the current values to the offsets. - // - if (do_center) { - // - // Only copy valid values - // - for (int i = 0; i < 6; i++) - offset_camera.axes[i] = mainApp->axis(i).headPos; - - Tracker::do_center = false; - - if (Libraries->pTracker) - Libraries->pTracker->NotifyCenter(); - - if (Libraries->pSecondTracker) - Libraries->pSecondTracker->NotifyCenter(); - - if (Libraries->pFilter) - Libraries->pFilter->Initialize(); - } - - if (confid) { - // get values - for (int i = 0; i < 6; i++) - target_camera.axes[i] = mainApp->axis(i).headPos; - - // do the centering - target_camera = target_camera - offset_camera; - - // - // Use advanced filtering, when a filter was selected. - // - if (Libraries->pFilter) { - for (int i = 0; i < 6; i++) - last_post_filter[i] = gameoutput_camera.axes[i]; - Libraries->pFilter->FilterHeadPoseData(target_camera.axes, new_camera.axes, last_post_filter); - } - else { - new_camera = target_camera; - } - - for (int i = 0; i < 6; i++) { - get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i)); - } - - // - // Send the headpose to the game - // - if (Libraries->pProtocol) { - gameoutput_camera = output_camera; - Libraries->pProtocol->sendHeadposeToGame( gameoutput_camera.axes, newpose ); // degrees & centimeters - } - } - } - - //for lower cpu load - msleep(8); - } - - for (int i = 0; i < 6; i++) - { - mainApp->axis(i).curve.setTrackingActive(false); - mainApp->axis(i).curveAlt.setTrackingActive(false); - } -} - -// -// Get the raw headpose, so it can be displayed. -// -void Tracker::getHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - { - data[i] = mainApp->axis(i).headPos; - } -} - -// -// Get the output-headpose, so it can be displayed. -// -void Tracker::getOutputHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - data[i] = output_camera.axes[i]; -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void Tracker::loadSettings() { - qDebug() << "Tracker::loadSettings says: Starting "; - QSettings settings("opentrack"); // Registry settings (in HK_USER) - +/********************************************************************************
+* FaceTrackNoIR This program is a private project of the some enthusiastic *
+* gamers from Holland, who don't like to pay much for *
+* head-tracking. *
+* *
+* Copyright (C) 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/>. *
+*********************************************************************************/
+#include "tracker.h"
+#include "facetracknoir.h"
+
+/** constructor **/
+Tracker::Tracker( FaceTrackNoIR *parent ) :
+ should_quit(false),
+ do_center(false)
+{
+ // Retieve the pointer to the parent
+ mainApp = parent;
+ // Load the settings from the INI-file
+ loadSettings();
+}
+
+Tracker::~Tracker()
+{
+}
+
+static void get_curve(double pos, double& out, THeadPoseDOF& axis) {
+ bool altp = (pos < 0) && axis.altp;
+ if (altp) {
+ out = axis.invert * axis.curveAlt.getValue(pos);
+ axis.curve.setTrackingActive( false );
+ axis.curveAlt.setTrackingActive( true );
+ }
+ else {
+ out = axis.invert * axis.curve.getValue(pos);
+ axis.curve.setTrackingActive( true );
+ axis.curveAlt.setTrackingActive( false );
+ }
+ out += axis.zero;
+}
+
+/** QThread run method @override **/
+void Tracker::run() {
+ T6DOF target_camera;
+ T6DOF new_camera;
+
+ /** Direct Input variables **/
+ T6DOF offset_camera;
+ T6DOF gameoutput_camera;
+
+ bool bTracker1Confid = false;
+ bool bTracker2Confid = false;
+
+ double newpose[6];
+ double last_post_filter[6];
+
+ forever
+ {
+ if (should_quit)
+ break;
+
+ for (int i = 0; i < 6; i++)
+ newpose[i] = 0;
+
+ //
+ // 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);
+ }
+
+ {
+ QMutexLocker foo(&mtx);
+ const bool confid = bTracker1Confid || bTracker2Confid;
+
+ if ( confid ) {
+ for (int i = 0; i < 6; i++)
+ mainApp->axis(i).headPos = newpose[i];
+ }
+
+ //
+ // If Center is pressed, copy the current values to the offsets.
+ //
+ if (do_center) {
+ //
+ // Only copy valid values
+ //
+ for (int i = 0; i < 6; i++)
+ offset_camera.axes[i] = mainApp->axis(i).headPos;
+
+ Tracker::do_center = false;
+
+ if (Libraries->pTracker)
+ Libraries->pTracker->NotifyCenter();
+
+ if (Libraries->pSecondTracker)
+ Libraries->pSecondTracker->NotifyCenter();
+
+ if (Libraries->pFilter)
+ Libraries->pFilter->Initialize();
+ }
+
+ if (confid) {
+ // get values
+ for (int i = 0; i < 6; i++)
+ target_camera.axes[i] = mainApp->axis(i).headPos;
+
+ // do the centering
+ target_camera = target_camera - offset_camera;
+
+ //
+ // Use advanced filtering, when a filter was selected.
+ //
+ if (Libraries->pFilter) {
+ for (int i = 0; i < 6; i++)
+ last_post_filter[i] = gameoutput_camera.axes[i];
+ Libraries->pFilter->FilterHeadPoseData(target_camera.axes, new_camera.axes, last_post_filter);
+ }
+ else {
+ new_camera = target_camera;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i));
+ }
+
+ //
+ // Send the headpose to the game
+ //
+ if (Libraries->pProtocol) {
+ gameoutput_camera = output_camera;
+ Libraries->pProtocol->sendHeadposeToGame( gameoutput_camera.axes, newpose ); // degrees & centimeters
+ }
+ }
+ }
+
+ //for lower cpu load
+ msleep(8);
+ }
+
+ for (int i = 0; i < 6; i++)
+ {
+ mainApp->axis(i).curve.setTrackingActive(false);
+ mainApp->axis(i).curveAlt.setTrackingActive(false);
+ }
+}
+
+//
+// Get the raw headpose, so it can be displayed.
+//
+void Tracker::getHeadPose( double *data ) {
+ QMutexLocker foo(&mtx);
+ for (int i = 0; i < 6; i++)
+ {
+ data[i] = mainApp->axis(i).headPos;
+ }
+}
+
+//
+// Get the output-headpose, so it can be displayed.
+//
+void Tracker::getOutputHeadPose( double *data ) {
+ QMutexLocker foo(&mtx);
+ for (int i = 0; i < 6; i++)
+ data[i] = output_camera.axes[i];
+}
+
+//
+// Load the current Settings from the currently 'active' INI-file.
+//
+void Tracker::loadSettings() {
+ qDebug() << "Tracker::loadSettings says: Starting ";
+ QSettings settings("opentrack"); // 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("Tracking"); - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - const char* names2[] = { - "zero_tx", - "zero_ty", - "zero_tz", - "zero_rx", - "zero_ry", - "zero_rz" - }; - - for (int i = 0; i < 6; i++) - mainApp->axis(i).zero = iniFile.value(names2[i], 0).toDouble(); - - iniFile.endGroup(); -} - -void Tracker::setInvertAxis(Axis axis, bool invert) { mainApp->axis(axis).invert = invert?-1.0f:1.0f; } + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+
+ iniFile.beginGroup("Tracking");
+
+ qDebug() << "loadSettings says: iniFile = " << currentFile;
+
+ const char* names2[] = {
+ "zero_tx",
+ "zero_ty",
+ "zero_tz",
+ "zero_rx",
+ "zero_ry",
+ "zero_rz"
+ };
+
+ for (int i = 0; i < 6; i++)
+ mainApp->axis(i).zero = iniFile.value(names2[i], 0).toDouble();
+
+ iniFile.endGroup();
+}
+
+void Tracker::setInvertAxis(Axis axis, bool invert) { mainApp->axis(axis).invert = invert?-1.0f:1.0f; }
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index e0b80034..4060a8eb 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -1,89 +1,89 @@ -/* Copyright (c) 2012 Stanislaw Halik - * - * 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 "ftnoir_filter_accela/ftnoir_filter_accela.h" -#include <cmath> -#include <QDebug> -#include <QMutexLocker> -#include "facetracknoir/global-settings.h" - -using namespace std; - -FTNoIR_Filter::FTNoIR_Filter() -{ - first_run = true; - loadSettings(); -} - -FTNoIR_Filter::~FTNoIR_Filter() -{ - -} - -void FTNoIR_Filter::loadSettings() { - QSettings settings("opentrack"); // Registry settings (in HK_USER) - +/* Copyright (c) 2012 Stanislaw Halik
+ *
+ * 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 "ftnoir_filter_accela/ftnoir_filter_accela.h"
+#include <cmath>
+#include <QDebug>
+#include <QMutexLocker>
+#include "facetracknoir/global-settings.h"
+
+using namespace std;
+
+FTNoIR_Filter::FTNoIR_Filter()
+{
+ first_run = true;
+ loadSettings();
+}
+
+FTNoIR_Filter::~FTNoIR_Filter()
+{
+
+}
+
+void FTNoIR_Filter::loadSettings() {
+ QSettings settings("opentrack"); // 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 ( "Accela" ); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+
+ iniFile.beginGroup ( "Accela" );
zoom_factor = iniFile.value("zoom-slowness", ACCELA_ZOOM_SLOWNESS).toDouble(); - rotation_alpha = iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble(); - translation_alpha = iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble(); - iniFile.endGroup (); -} - -void FTNoIR_Filter::receiveSettings(double rot, double trans, double zoom_fac) -{ - QMutexLocker foo(&mutex); - - rotation_alpha = rot; - translation_alpha = trans; - zoom_factor = zoom_fac; -} - -static double parabola(const double a, const double x) -{ - const double a1 = 1./a; - return a1 * x * x; -} - -void FTNoIR_Filter::FilterHeadPoseData(const double *target_camera_position, - double *new_camera_position, - const double *last_post_filter_values) -{ - if (first_run) - { - for (int i = 0; i < 6; i++) - { - new_camera_position[i] = target_camera_position[i]; - current_camera_position[i] = target_camera_position[i]; - } - - first_run = false; - return; - } - - QMutexLocker foo(&mutex); - - for (int i=0;i<6;i++) - { - const double vec = target_camera_position[i] - current_camera_position[i]; - const int sign = vec < 0 ? -1 : 1; - const double x = fabs(vec); - const double a = i >= 3 ? rotation_alpha : translation_alpha; - const double reduction = 1. / std::max(1., 1. + zoom_factor * -last_post_filter_values[TZ] / 1000); - const double velocity = parabola(a, x) * reduction; - const double result = current_camera_position[i] + velocity * sign; - const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i]; - new_camera_position[i] = current_camera_position[i] = done ? target_camera_position[i] : result; - } -} - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Filter; -} + rotation_alpha = iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble();
+ translation_alpha = iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble();
+ iniFile.endGroup ();
+}
+
+void FTNoIR_Filter::receiveSettings(double rot, double trans, double zoom_fac)
+{
+ QMutexLocker foo(&mutex);
+
+ rotation_alpha = rot;
+ translation_alpha = trans;
+ zoom_factor = zoom_fac;
+}
+
+static double parabola(const double a, const double x)
+{
+ const double a1 = 1./a;
+ return a1 * x * x;
+}
+
+void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position,
+ double *new_camera_position,
+ const double* last_post_filter_values)
+{
+ if (first_run)
+ {
+ for (int i = 0; i < 6; i++)
+ {
+ new_camera_position[i] = target_camera_position[i];
+ current_camera_position[i] = target_camera_position[i];
+ }
+
+ first_run = false;
+ return;
+ }
+
+ QMutexLocker foo(&mutex);
+
+ for (int i=0;i<6;i++)
+ {
+ const double vec = target_camera_position[i] - current_camera_position[i];
+ const int sign = vec < 0 ? -1 : 1;
+ const double x = fabs(vec);
+ const double a = i >= 3 ? rotation_alpha : translation_alpha;
+ const double reduction = 1. / std::max(1., 1. + zoom_factor * -last_post_filter_values[TZ] / 1000);
+ const double velocity = parabola(a, x) * reduction;
+ const double result = current_camera_position[i] + velocity * sign;
+ const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i];
+ new_camera_position[i] = current_camera_position[i] = done ? target_camera_position[i] : result;
+ }
+}
+
+extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
+{
+ return new FTNoIR_Filter;
+}
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h index 55e413aa..82766293 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -1,109 +1,109 @@ -/******************************************************************************** -* 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 * -* * -* 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/>. * -* * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FTN_FILTER_H -#define INCLUDED_FTN_FILTER_H - -#undef FTNOIR_TRACKER_BASE_LIB -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT - -#include "ftnoir_filter_base/ftnoir_filter_base.h" -#include "ui_ftnoir_accela_filtercontrols.h" -#include "facetracknoir/global-settings.h" -#include <QMutex> - -#define ACCELA_SMOOTHING_ROTATION 6.0 -#define ACCELA_SMOOTHING_TRANSLATION 3.0 +/********************************************************************************
+* 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 *
+* *
+* 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/>. *
+* *
+********************************************************************************/
+#pragma once
+#ifndef INCLUDED_FTN_FILTER_H
+#define INCLUDED_FTN_FILTER_H
+
+#undef FTNOIR_TRACKER_BASE_LIB
+#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT
+
+#include "ftnoir_filter_base/ftnoir_filter_base.h"
+#include "ui_ftnoir_accela_filtercontrols.h"
+#include "facetracknoir/global-settings.h"
+#include <QMutex>
+
+#define ACCELA_SMOOTHING_ROTATION 60.0
+#define ACCELA_SMOOTHING_TRANSLATION 40.0
#define ACCELA_ZOOM_SLOWNESS 35 - -//******************************************************************************************************* -// FaceTrackNoIR Filter class. -//******************************************************************************************************* -class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter -{ -public: - FTNoIR_Filter(); - ~FTNoIR_Filter(); - void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position, const double *last_post_filter_values); - void Initialize() { - first_run = true; - } - void receiveSettings(double rot, double trans, double zoom_fac); -private: - QMutex mutex; - void loadSettings(); - bool first_run; - double rotation_alpha, translation_alpha, zoom_factor; - double current_camera_position[6]; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* - -// Widget that has controls for FTNoIR protocol filter-settings. -class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog -{ - Q_OBJECT -public: - explicit FilterControls(); - virtual ~FilterControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerFilter(IFilter* filter); - void unregisterFilter(); -private: - Ui::AccelaUICFilterControls ui; - void loadSettings(); - void save(); - bool settingsDirty; - FTNoIR_Filter* accela_filter; -private slots: - void doOK(); - void doCancel(); - void settingChanged(bool) { settingsDirty = true; } - void settingChanged(int) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter -//******************************************************************************************************* -class FTNoIR_FilterDll : public Metadata -{ -public: - FTNoIR_FilterDll(); - ~FTNoIR_FilterDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk3"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk3"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk3"); } - - void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } -}; - - -#endif //INCLUDED_FTN_FILTER_H -//END - +
+//*******************************************************************************************************
+// FaceTrackNoIR Filter class.
+//*******************************************************************************************************
+class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter
+{
+public:
+ FTNoIR_Filter();
+ ~FTNoIR_Filter();
+ void FilterHeadPoseData(const double* target_camera_position, double *new_camera_position, const double* last_post_filter_values);
+ void Initialize() {
+ first_run = true;
+ }
+ void receiveSettings(double rot, double trans, double zoom_fac);
+private:
+ QMutex mutex;
+ void loadSettings();
+ bool first_run;
+ double rotation_alpha, translation_alpha, zoom_factor;
+ double current_camera_position[6];
+};
+
+//*******************************************************************************************************
+// FaceTrackNoIR Filter Settings-dialog.
+//*******************************************************************************************************
+
+// Widget that has controls for FTNoIR protocol filter-settings.
+class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog
+{
+ Q_OBJECT
+public:
+ explicit FilterControls();
+ virtual ~FilterControls();
+ void showEvent ( QShowEvent * event );
+ void Initialize(QWidget *parent);
+ void registerFilter(IFilter* filter);
+ void unregisterFilter();
+private:
+ Ui::AccelaUICFilterControls ui;
+ void loadSettings();
+ void save();
+ bool settingsDirty;
+ FTNoIR_Filter* accela_filter;
+private slots:
+ void doOK();
+ void doCancel();
+ void settingChanged(bool) { settingsDirty = true; }
+ void settingChanged(int) { settingsDirty = true; }
+};
+
+//*******************************************************************************************************
+// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter
+//*******************************************************************************************************
+class FTNoIR_FilterDll : public Metadata
+{
+public:
+ FTNoIR_FilterDll();
+ ~FTNoIR_FilterDll();
+
+ void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk3"); }
+ void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk3"); }
+ void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk3"); }
+
+ void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
+};
+
+
+#endif //INCLUDED_FTN_FILTER_H
+//END
+
diff --git a/ftnoir_filter_base/ftnoir_filter_base.h b/ftnoir_filter_base/ftnoir_filter_base.h index b8b5017d..0f73310f 100644 --- a/ftnoir_filter_base/ftnoir_filter_base.h +++ b/ftnoir_filter_base/ftnoir_filter_base.h @@ -1,41 +1,41 @@ -#ifndef FTNOIR_FILTER_BASE_H -#define FTNOIR_FILTER_BASE_H - -#include "ftnoir_filter_base_global.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include <QString> -#include <QList> -#include <QFile> -#include <QCoreApplication> -#include <QMessageBox> -#include <QSettings> - -//////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -# define EXTERN_C extern "C" -#else -# define EXTERN_C -#endif // __cplusplus - -//////////////////////////////////////////////////////////////////////////////// -// 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 IFilter -{ - virtual ~IFilter() {} - virtual void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position, const double *last_post_filter) = 0; - virtual void Initialize() = 0; -}; - -struct IFilterDialog -{ - virtual ~IFilterDialog() {} - virtual void Initialize(QWidget *parent) = 0; - virtual void registerFilter(IFilter* tracker) = 0; - virtual void unregisterFilter() = 0; -}; - -#endif // FTNOIR_FILTER_BASE_H +#ifndef FTNOIR_FILTER_BASE_H
+#define FTNOIR_FILTER_BASE_H
+
+#include "ftnoir_filter_base_global.h"
+#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
+#include <QString>
+#include <QList>
+#include <QFile>
+#include <QCoreApplication>
+#include <QMessageBox>
+#include <QSettings>
+
+////////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+#else
+# define EXTERN_C
+#endif // __cplusplus
+
+////////////////////////////////////////////////////////////////////////////////
+// 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 IFilter
+{
+ virtual ~IFilter() {}
+ virtual void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position, const double *last_post_filter) = 0;
+ virtual void Initialize() = 0;
+};
+
+struct IFilterDialog
+{
+ virtual ~IFilterDialog() {}
+ virtual void Initialize(QWidget *parent) = 0;
+ virtual void registerFilter(IFilter* tracker) = 0;
+ virtual void unregisterFilter() = 0;
+};
+
+#endif // FTNOIR_FILTER_BASE_H
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp index 6904dd92..f50c60d1 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp @@ -1,172 +1,172 @@ -/******************************************************************************** -* 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 * -* * -* 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/>. * -* * -********************************************************************************/ -#include "ftnoir_filter_ewma2.h" -#include "math.h" -#include <QDebug> -#include <QWidget> -#include "facetracknoir/global-settings.h" -#include <algorithm> -#include <QMutexLocker> -//#define LOG_OUTPUT - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -FTNoIR_Filter::FTNoIR_Filter() -{ - first_run = true; - alpha_smoothing = 0.02f; // this is a constant for now, might be a parameter later - loadSettings(); // Load the Settings -} - -FTNoIR_Filter::~FTNoIR_Filter() -{ -} - -void FTNoIR_Filter::receiveSettings(double smin, double smax, double sexpt) -{ - QMutexLocker foo(&mutex); - - kMinSmoothing = smin; - kMaxSmoothing = smax; - kSmoothingScaleCurve = sexpt; -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Filter::loadSettings() { - qDebug() << "FTNoIR_Filter::loadSettings says: Starting "; - QSettings settings("opentrack"); // Registry settings (in HK_USER) - +/********************************************************************************
+* 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 *
+* *
+* 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/>. *
+* *
+********************************************************************************/
+#include "ftnoir_filter_ewma2.h"
+#include "math.h"
+#include <QDebug>
+#include <QWidget>
+#include "facetracknoir/global-settings.h"
+#include <algorithm>
+#include <QMutexLocker>
+//#define LOG_OUTPUT
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FTNoIR_Filter::FTNoIR_Filter()
+{
+ first_run = true;
+ alpha_smoothing = 0.02f; // this is a constant for now, might be a parameter later
+ loadSettings(); // Load the Settings
+}
+
+FTNoIR_Filter::~FTNoIR_Filter()
+{
+}
+
+void FTNoIR_Filter::receiveSettings(double smin, double smax, double sexpt)
+{
+ QMutexLocker foo(&mutex);
+
+ kMinSmoothing = smin;
+ kMaxSmoothing = smax;
+ kSmoothingScaleCurve = sexpt;
+}
+
+//
+// Load the current Settings from the currently 'active' INI-file.
+//
+void FTNoIR_Filter::loadSettings() {
+ qDebug() << "FTNoIR_Filter::loadSettings says: Starting ";
+ QSettings settings("opentrack"); // Registry settings (in HK_USER)
+
QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - - qDebug() << "FTNoIR_Filter::loadSettings says: iniFile = " << currentFile; - - // - // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR - // - iniFile.beginGroup ( "Tracking" ); - kMinSmoothing = iniFile.value ( "minSmooth", 15 ).toInt(); - kMaxSmoothing = iniFile.value ( "maxSmooth", 50 ).toInt(); - kSmoothingScaleCurve = iniFile.value ( "powCurve", 10 ).toInt(); - iniFile.endGroup (); -} - -void FTNoIR_Filter::FilterHeadPoseData(const double *target_camera_position, - double *new_camera_position, - const double *last_post_filter) -{ - double delta; - double new_alpha; - double scale[]={0.025f,0.025f,0.025f,6.0f,6.0f,6.0f}; - - //On the first run, initialize to output=target and return. - if (first_run==true) { - for (int i=0;i<6;i++) { - new_camera_position[i] = target_camera_position[i]; - current_camera_position[i] = target_camera_position[i]; - alpha[i] = 0.0f; - } - first_run=false; - return; - } - - QMutexLocker foo(&mutex); - - for (int i=0;i<6;i++) { - // Calculate the delta. - delta=target_camera_position[i]-current_camera_position[i]; - // Normalise the delta. - delta=std::min<double>(std::max<double>(fabs(delta)/scale[i],0.0),1.0); - // Calculate the new alpha from the normalized delta. - new_alpha=1.0/(kMinSmoothing+((1.0-pow(delta,kSmoothingScaleCurve))*(kMaxSmoothing-kMinSmoothing))); - // Update the smoothed alpha. - alpha[i]=(alpha_smoothing*new_alpha)+((1.0f-alpha_smoothing)*alpha[i]); - } - - // Use the same (largest) smoothed alpha for each channel - //NB: larger alpha = *less* lag (opposite to what you'd expect) - float largest_alpha=0.0f; - for (int i=0;i<6;i++) { - largest_alpha=std::max<double>(largest_alpha, alpha[i]); - } - - // Calculate the new camera position. - for (int i=0;i<6;i++) { - new_camera_position[i]=(largest_alpha*target_camera_position[i])+((1.0f-largest_alpha)*current_camera_position[i]); - //new_camera_position[i]=(alpha[i]*target_camera_position[i])+((1.0f-alpha[i])*current_camera_position[i]); - } - -#ifdef LOG_OUTPUT - // Use this for some debug-output to file... - QFile data(QCoreApplication::applicationDirPath() + "\\EWMA_output.txt"); - if (data.open(QFile::WriteOnly | QFile::Append)) { - QTextStream out(&data); - out << "current:\t" << current_camera_position[0] - << "\t" << current_camera_position[1] - << "\t" << current_camera_position[2] - << "\t" << current_camera_position[3] - << "\t" << current_camera_position[4] - << "\t" << current_camera_position[5] << '\n'; - out << "target:\t" << target_camera_position[0] - << "\t" << target_camera_position[1] - << "\t" << target_camera_position[2] - << "\t" << target_camera_position[3] - << "\t" << target_camera_position[4] - << "\t" << target_camera_position[5] << '\n'; - out << "output:\t" << new_camera_position[0] - << "\t" << new_camera_position[1] - << "\t" << new_camera_position[2] - << "\t" << new_camera_position[3] - << "\t" << new_camera_position[4] - << "\t" << new_camera_position[5] << '\n'; - out << "largest_alpha:\t" << largest_alpha << '\n'; - } -#endif - - // Update the current camera position to the new position. - for (int i = 0; i < 6; i++) { - current_camera_position[i] = new_camera_position[i]; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter object. - -// Export both decorated and undecorated names. -// 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") - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Filter; -} + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+
+ qDebug() << "FTNoIR_Filter::loadSettings says: iniFile = " << currentFile;
+
+ //
+ // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR
+ //
+ iniFile.beginGroup ( "Tracking" );
+ kMinSmoothing = iniFile.value ( "minSmooth", 15 ).toInt();
+ kMaxSmoothing = iniFile.value ( "maxSmooth", 50 ).toInt();
+ kSmoothingScaleCurve = iniFile.value ( "powCurve", 10 ).toInt();
+ iniFile.endGroup ();
+}
+
+void FTNoIR_Filter::FilterHeadPoseData(const double *target_camera_position,
+ double *new_camera_position,
+ const double *last_post_filter)
+{
+ double delta;
+ double new_alpha;
+ double scale[]={0.025f,0.025f,0.025f,6.0f,6.0f,6.0f};
+
+ //On the first run, initialize to output=target and return.
+ if (first_run==true) {
+ for (int i=0;i<6;i++) {
+ new_camera_position[i] = target_camera_position[i];
+ current_camera_position[i] = target_camera_position[i];
+ alpha[i] = 0.0f;
+ }
+ first_run=false;
+ return;
+ }
+
+ QMutexLocker foo(&mutex);
+
+ for (int i=0;i<6;i++) {
+ // Calculate the delta.
+ delta=target_camera_position[i]-current_camera_position[i];
+ // Normalise the delta.
+ delta=std::min<double>(std::max<double>(fabs(delta)/scale[i],0.0),1.0);
+ // Calculate the new alpha from the normalized delta.
+ new_alpha=1.0/(kMinSmoothing+((1.0-pow(delta,kSmoothingScaleCurve))*(kMaxSmoothing-kMinSmoothing)));
+ // Update the smoothed alpha.
+ alpha[i]=(alpha_smoothing*new_alpha)+((1.0f-alpha_smoothing)*alpha[i]);
+ }
+
+ // Use the same (largest) smoothed alpha for each channel
+ //NB: larger alpha = *less* lag (opposite to what you'd expect)
+ float largest_alpha=0.0f;
+ for (int i=0;i<6;i++) {
+ largest_alpha=std::max<double>(largest_alpha, alpha[i]);
+ }
+
+ // Calculate the new camera position.
+ for (int i=0;i<6;i++) {
+ new_camera_position[i]=(largest_alpha*target_camera_position[i])+((1.0f-largest_alpha)*current_camera_position[i]);
+ //new_camera_position[i]=(alpha[i]*target_camera_position[i])+((1.0f-alpha[i])*current_camera_position[i]);
+ }
+
+#ifdef LOG_OUTPUT
+ // Use this for some debug-output to file...
+ QFile data(QCoreApplication::applicationDirPath() + "\\EWMA_output.txt");
+ if (data.open(QFile::WriteOnly | QFile::Append)) {
+ QTextStream out(&data);
+ out << "current:\t" << current_camera_position[0]
+ << "\t" << current_camera_position[1]
+ << "\t" << current_camera_position[2]
+ << "\t" << current_camera_position[3]
+ << "\t" << current_camera_position[4]
+ << "\t" << current_camera_position[5] << '\n';
+ out << "target:\t" << target_camera_position[0]
+ << "\t" << target_camera_position[1]
+ << "\t" << target_camera_position[2]
+ << "\t" << target_camera_position[3]
+ << "\t" << target_camera_position[4]
+ << "\t" << target_camera_position[5] << '\n';
+ out << "output:\t" << new_camera_position[0]
+ << "\t" << new_camera_position[1]
+ << "\t" << new_camera_position[2]
+ << "\t" << new_camera_position[3]
+ << "\t" << new_camera_position[4]
+ << "\t" << new_camera_position[5] << '\n';
+ out << "largest_alpha:\t" << largest_alpha << '\n';
+ }
+#endif
+
+ // Update the current camera position to the new position.
+ for (int i = 0; i < 6; i++) {
+ current_camera_position[i] = new_camera_position[i];
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Factory function that creates instances if the Filter object.
+
+// Export both decorated and undecorated names.
+// 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")
+
+extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
+{
+ return new FTNoIR_Filter;
+}
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h index 4f9cdba3..e3a264be 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h @@ -1,115 +1,115 @@ -/******************************************************************************** -* 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 * -* * -* 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/>. * -* * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FTN_FILTER_H -#define INCLUDED_FTN_FILTER_H - -#include "ftnoir_filter_base/ftnoir_filter_base.h" -#include "facetracknoir/global-settings.h" -#include "ui_ftnoir_ewma_filtercontrols.h" -#include <QWidget> -#include <QMutex> - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class FTNoIR_Filter : public IFilter -{ -public: - FTNoIR_Filter(); - ~FTNoIR_Filter(); - void Initialize() {} - - void FilterHeadPoseData(const double *target_camera_position, - double *new_camera_position, - const double *last_post_filter); - void receiveSettings(double smin, double smax, double sexpt); - -private: - void loadSettings(); // Load the settings from the INI-file - double newHeadPose; // Structure with new headpose - - bool first_run; - double alpha_smoothing; - double alpha[6]; - - double kMinSmoothing; - double kMaxSmoothing; - double kSmoothingScaleCurve; - double current_camera_position[6]; - QMutex mutex; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* - -// Widget that has controls for FTNoIR protocol filter-settings. -class FilterControls: public QWidget, public IFilterDialog -{ - Q_OBJECT -public: - explicit FilterControls(); - virtual ~FilterControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerFilter(IFilter* flt); - void unregisterFilter(); - -private: - Ui::UICFilterControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - - FTNoIR_Filter* pFilter; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; } - void settingChanged( int ) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter -//******************************************************************************************************* -class FTNoIR_FilterDll : public Metadata -{ -public: - FTNoIR_FilterDll(); - ~FTNoIR_FilterDll(); - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA Filter Mk2"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Exponentially Weighted Moving Average filter with dynamic smoothing parameter"); } - void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } -}; - -#endif //INCLUDED_FTN_FILTER_H -//END +/********************************************************************************
+* 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 *
+* *
+* 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/>. *
+* *
+********************************************************************************/
+#pragma once
+#ifndef INCLUDED_FTN_FILTER_H
+#define INCLUDED_FTN_FILTER_H
+
+#include "ftnoir_filter_base/ftnoir_filter_base.h"
+#include "facetracknoir/global-settings.h"
+#include "ui_ftnoir_ewma_filtercontrols.h"
+#include <QWidget>
+#include <QMutex>
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class FTNoIR_Filter : public IFilter
+{
+public:
+ FTNoIR_Filter();
+ ~FTNoIR_Filter();
+ void Initialize() {}
+
+ void FilterHeadPoseData(const double *target_camera_position,
+ double *new_camera_position,
+ const double *last_post_filter);
+ void receiveSettings(double smin, double smax, double sexpt);
+
+private:
+ void loadSettings(); // Load the settings from the INI-file
+ double newHeadPose; // Structure with new headpose
+
+ bool first_run;
+ double alpha_smoothing;
+ double alpha[6];
+
+ double kMinSmoothing;
+ double kMaxSmoothing;
+ double kSmoothingScaleCurve;
+ double current_camera_position[6];
+ QMutex mutex;
+};
+
+//*******************************************************************************************************
+// FaceTrackNoIR Filter Settings-dialog.
+//*******************************************************************************************************
+
+// Widget that has controls for FTNoIR protocol filter-settings.
+class FilterControls: public QWidget, public IFilterDialog
+{
+ Q_OBJECT
+public:
+ explicit FilterControls();
+ virtual ~FilterControls();
+ void showEvent ( QShowEvent * event );
+ void Initialize(QWidget *parent);
+ void registerFilter(IFilter* flt);
+ void unregisterFilter();
+
+private:
+ Ui::UICFilterControls ui;
+ void loadSettings();
+ void save();
+
+ /** helper **/
+ bool settingsDirty;
+
+ FTNoIR_Filter* pFilter;
+
+private slots:
+ void doOK();
+ void doCancel();
+ void settingChanged() { settingsDirty = true; }
+ void settingChanged( int ) { settingsDirty = true; }
+};
+
+//*******************************************************************************************************
+// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter
+//*******************************************************************************************************
+class FTNoIR_FilterDll : public Metadata
+{
+public:
+ FTNoIR_FilterDll();
+ ~FTNoIR_FilterDll();
+ void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA Filter Mk2"); }
+ void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA"); }
+ void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Exponentially Weighted Moving Average filter with dynamic smoothing parameter"); }
+ void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
+};
+
+#endif //INCLUDED_FTN_FILTER_H
+//END
|