From 60ac7c17eb4786949a130099a4ef26af00c2ea4f Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 19 Aug 2013 12:43:22 +0200 Subject: Simplify Accela's UI and preset equations --- .../ftnoir_accela_filtercontrols.ui | 675 ++++++--------------- ftnoir_filter_accela/ftnoir_filter_accela.cpp | 111 +--- ftnoir_filter_accela/ftnoir_filter_accela.h | 31 +- .../ftnoir_filter_accela_dialog.cpp | 91 +-- ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp | 18 - 5 files changed, 233 insertions(+), 693 deletions(-) (limited to 'ftnoir_filter_accela') diff --git a/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui b/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui index 1478254e..d66dfa80 100644 --- a/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui +++ b/ftnoir_filter_accela/ftnoir_accela_filtercontrols.ui @@ -9,8 +9,8 @@ 0 0 - 868 - 729 + 570 + 71 @@ -29,482 +29,193 @@ - - - - - true - - - - 0 - 0 - - - - - 850 - 650 - - - - - 300 - 650 - - - - 0 - - - - Preset - - - - - 10 - 10 - 111 - 16 - - - - Rotation smoothing - - - - - - 10 - 40 - 111 - 16 - - - - Translation smoothing - - - - - - 130 - 10 - 81 - 22 - - - - 0.100000000000000 - - - 10.000000000000000 - - - 3.000000000000000 - - - - - - 130 - 40 - 81 - 22 - - - - 0.100000000000000 - - - 10.000000000000000 - - - 0.750000000000000 - - - - - - 140 - 70 - 75 - 23 - - - - Set curves - - - - - - 60 - 70 - 75 - 23 - - - - Remove all - - - - - - Rotation - - - - - 20 - 10 - 819 - 571 - - - - 10 - - - 10 - - - 57 - - - 57 - - - 1 - - - 1 - - - - 255 - 170 - 0 - - - - - 192 - 192 - 192 - - - - Input - - - Output - - - Translation - - - - - - Translation - - - - - 20 - 10 - 819 - 581 - - - - 10 - - - 10 - - - 57 - - - 57 - - - 1 - - - 1 - - - - 85 - 255 - 0 - - - - - 192 - 192 - 192 - - - - Input - - - Output - - - - - - - - - - - - 25 - 0 - - - - - 150 - 16777215 - - - - color:#0; + + + + 243 + 10 + 76 + 22 + + + + + 25 + 0 + + + + + 150 + 16777215 + + + + color:#0; background:none; - - - Reduction factor: - - - - - - - - 50 - 15 - - - - 1 - - - 1000 - - - 5 - - - 100 - - - Qt::Horizontal - - - QSlider::NoTicks - - - - - - - - 35 - 22 - - - - background:none; - - - false - - - 1 - - - 1000 - - - 100 - - - - - - - - 25 - 0 - - - - - 150 - 16777215 - - - - color:#0; -background:none; - - - Zoom slowness: - - - - - - - - 50 - 15 - - - - 0 - - - 200 - - - 1 - - - 100 - - - Qt::Horizontal - - - QSlider::NoTicks - - - - - - - - 35 - 22 - - - - background:none; - - - false - - - 0 - - - 200 - - - 100 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - OK - - - - - - - Cancel - - - - - - + + + Zoom slowness: + + + + + + 130 + 40 + 81 + 22 + + + + 0.100000000000000 + + + 65535.000000000000000 + + + 1.000000000000000 + + + + + + 130 + 10 + 81 + 22 + + + + 0.100000000000000 + + + 65535.000000000000000 + + + 1.000000000000000 + + + + + + 10 + 10 + 111 + 16 + + + + Rotation smoothing + + + + + + 325 + 13 + 189 + 15 + + + + + 50 + 15 + + + + 0 + + + 200 + + + 1 + + + 100 + + + Qt::Horizontal + + + QSlider::NoTicks + + + + + + 520 + 10 + 42 + 22 + + + + + 35 + 22 + + + + background:none; + + + false + + + 0 + + + 200 + + + 100 + + + + + + 10 + 40 + 111 + 16 + + + + Translation smoothing + + + + + + 409 + 40 + 75 + 23 + + + + OK + + + + + + 490 + 40 + 75 + 23 + + + + Cancel + + - - - QFunctionConfigurator - QWidget -
qfunctionconfigurator.h
-
-
- - slideReduction - valueChanged(int) - spinReduction - setValue(int) - - - 219 - 620 - - - 310 - 622 - - - - - spinReduction - valueChanged(int) - slideReduction - setValue(int) - - - 315 - 613 - - - 170 - 621 - - - slideZoom valueChanged(int) @@ -512,12 +223,12 @@ background:none; setValue(int) - 547 - 602 + 463 + 19 - 667 - 602 + 537 + 20 @@ -528,12 +239,12 @@ background:none; setValue(int) - 663 - 602 + 533 + 20 - 537 - 602 + 426 + 20 diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index 0aea2f78..66744c2f 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -4,29 +4,16 @@ * 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): - 20120807 - WVR: FunctionConfig is now also used for the Filter. The extrapolation was adapted from Stanislaw. - 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/ftnoir_filter_accela.h" #include "math.h" #include #include #include "facetracknoir/global-settings.h" -#if !defined(_WIN32) && !defined(__WIN32) -# define _isnan isnan -#endif - -FTNoIR_Filter::FTNoIR_Filter() : - functionConfig("Accela-Scaling-Rotation", 10, 10), - translationFunctionConfig("Accela-Scaling-Translation", 10, 10) +FTNoIR_Filter::FTNoIR_Filter() { first_run = true; - kMagicNumber = 1000; - loadSettings(); // Load the Settings + loadSettings(); } FTNoIR_Filter::~FTNoIR_Filter() @@ -40,102 +27,50 @@ void FTNoIR_Filter::loadSettings() { QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - functionConfig.loadSettings(iniFile); - translationFunctionConfig.loadSettings(iniFile); - iniFile.beginGroup ( "Accela" ); - kMagicNumber = iniFile.value ( "Reduction", 1000 ).toFloat(); - kZoomSlowness = iniFile.value("zoom-slowness", 0).toFloat(); + zoom_factor = iniFile.value("zoom-slowness", 0).toDouble(); + rotation_alpha = iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble(); + translation_alpha = iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble(); iniFile.endGroup (); } +static double parabola(const double a, const double x) +{ + const double a1 = 1./a; + return a1 * a1 * x * x; +} + void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, double *target_camera_position, double *new_camera_position, double *last_post_filter_values) { - double target[6]; - double prev_output[6]; - float output[6]; - - for (int i = 0; i < 6; i++) - { - prev_output[i] = current_camera_position[i]; - target[i] = target_camera_position[i]; - } - if (first_run) { for (int i = 0; i < 6; i++) { - new_camera_position[i] = target[i]; - current_camera_position[i] = target[i]; + new_camera_position[i] = target_camera_position[i]; + current_camera_position[i] = target_camera_position[i]; } - first_run=false; + first_run = false; return; } for (int i=0;i<6;i++) { - if (_isnan(target[i])) - return; - - if (_isnan(prev_output[i])) - return; - - double e2 = target[i]; - double start = prev_output[i]; - double vec = e2 - start; - int sign = vec < 0 ? -1 : 1; - double x = fabs(vec); - QList points = (i >= 3 ? functionConfig : translationFunctionConfig).getPoints(); - int extrapolatep = 0; - double ratio; - double maxx; - double add; - // linear extrapolation of a spline - if (points.size() > 1) { - QPointF last = points[points.size() - 1]; - QPointF penultimate = points[points.size() - 2]; - ratio = (last.y() - penultimate.y()) / (last.x() - penultimate.x()); - extrapolatep = 1; - add = last.y(); - maxx = last.x(); - } - double foo = extrapolatep && x > maxx ? add + ratio * (x - maxx) : (i >= 3 ? functionConfig : translationFunctionConfig).getValue(x); - // the idea is that "empty" updates without new head pose data are still - // 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 / kMagicNumber * (1 / std::max(1.0, 1 + kZoomSlowness * -last_post_filter_values[TZ] / 100)); - double sum = start + velocity * sign; - bool done = (sign > 0 ? sum >= e2 : sum <= e2); - if (done) { - output[i] = e2; - } else { - output[i] = sum; - } - - if (_isnan(output[i])) - return; + 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; } - - for (int i = 0; i < 6; i++) - { - new_camera_position[i] = output[i]; - current_camera_position[i] = output[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. - 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 6e98c797..a0b7f3ef 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -31,13 +31,10 @@ #include "ftnoir_filter_base/ftnoir_filter_base.h" #include "ui_ftnoir_accela_filtercontrols.h" -#include #include "facetracknoir/global-settings.h" -// -// Macro to determine array-size -// -#define NUM_OF(x) (sizeof (x) / sizeof *(x)) +#define ACCELA_SMOOTHING_ROTATION 6.0 +#define ACCELA_SMOOTHING_TRANSLATION 3.0 //******************************************************************************************************* // FaceTrackNoIR Filter class. @@ -54,13 +51,8 @@ public: private: void loadSettings(); // Load the settings from the INI-file - double newHeadPose[6]; // Structure with new headpose - - bool first_run; - double kMagicNumber, kZoomSlowness; // Stanislaws' magic number (should be 100 according to him...) - - FunctionConfig functionConfig; - FunctionConfig translationFunctionConfig; + bool first_run; + double rotation_alpha, translation_alpha, zoom_factor; }; //******************************************************************************************************* @@ -82,21 +74,12 @@ private: Ui::AccelaUICFilterControls ui; void loadSettings(); void save(); - - /** helper **/ bool settingsDirty; - - 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; - private slots: void doOK(); void doCancel(); void settingChanged(bool) { settingsDirty = true; } void settingChanged(int) { settingsDirty = true; } - void resetCircle(); - void removeAll(); }; //******************************************************************************************************* @@ -108,9 +91,9 @@ 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 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"); } }; diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp index 1de51b10..f0641ea6 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp @@ -39,9 +39,7 @@ // Constructor for server-settings-dialog // FilterControls::FilterControls() : - QWidget(), - functionConfig("Accela-Scaling-Rotation", 10, 10), - translationFunctionConfig("Accela-Scaling-Translation", 10, 10) + QWidget() { ui.setupUi( this ); @@ -49,13 +47,11 @@ FilterControls::FilterControls() : loadSettings(); connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.scalingConfig, SIGNAL(CurveChanged(bool)), this, SLOT(settingChanged(bool))); - connect(ui.translationScalingConfig, SIGNAL(CurveChanged(bool)), this, SLOT(settingChanged(bool))); - connect(ui.resetCircle, SIGNAL(clicked()), this, SLOT(resetCircle())); - connect(ui.removeAllButton, SIGNAL(clicked()), this, SLOT(removeAll())); + connect(ui.rotation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); + connect(ui.translation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); - // Connect slider for reduction - //connect(ui.slideReduction, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.slideZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.spinZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); qDebug() << "FilterControls() says: started"; } @@ -71,13 +67,6 @@ FilterControls::~FilterControls() { // Initialize tracker-client-dialog // void FilterControls::Initialize(QWidget *parent, IFilter* ptr) { - - // - // The dialog can be opened, while the Tracker is running. - // In that case, ptr will point to the active Filter-instance. - // 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); @@ -145,74 +134,16 @@ void FilterControls::loadSettings() { //qDebug() << "FTNoIR_Filter::loadSettings2 says: size = " << NUM_OF(defScaleRotation); - ui.translationScalingConfig->setConfig(&translationFunctionConfig, currentFile); - ui.scalingConfig->setConfig(&functionConfig, currentFile); - iniFile.beginGroup ( "Accela" ); - ui.slideReduction->setValue (iniFile.value ( "Reduction", 1000 ).toInt()); ui.slideZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); - ui.rotationCircle->setValue(iniFile.value("preset-rotation", 3).toDouble()); - ui.translationCircle->setValue(iniFile.value("preset-translation", 0.75).toDouble()); + ui.spinZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); + ui.rotation_alpha->setValue(iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble()); + ui.translation_alpha->setValue(iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble()); iniFile.endGroup (); settingsDirty = false; } -void FilterControls::removeAll() { - translationFunctionConfig.removeAllPoints(); - functionConfig.removeAllPoints(); -} - -void FilterControls::resetCircle() -{ - 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" ); - iniFile.setValue("preset-rotation", ui.rotationCircle->value()); - iniFile.setValue("preset-translation", ui.translationCircle->value()); - iniFile.endGroup(); - - // essentially unit circles elongated on the X axis - double elongations[] = { - ui.rotationCircle->value(), ui.translationCircle->value() - }; - - FunctionConfig* configs[] = { - &functionConfig, &translationFunctionConfig - }; - - QFunctionConfigurator* widgets[] = { - ui.scalingConfig, ui.translationScalingConfig - }; - - for (int i = 0; i < 2; i++) - { - FunctionConfig& cfg = *configs[i]; - double sz = elongations[i]; - - cfg.removeAllPoints(); - - for (double x = 0; x <= sz+1e-2; x += 1e-1) - { - double sq = sz*sz-x*x; - double val; - if (sq <= 1e-4) - val = 0; - else - val = std::min(sqrt(sq), sz); - - cfg.addPoint(QPointF(x, 10*(sz-val)/sz)); - } - - cfg.saveSettings(iniFile); - - widgets[i]->setConfig(&cfg, currentFile); - } - - settingsDirty = false; -} - // // Save the current Settings to the currently 'active' INI-file. // @@ -225,13 +156,11 @@ void FilterControls::save() { qDebug() << "FTNoIR_Filter::save() says: iniFile = " << currentFile; iniFile.beginGroup ( "Accela" ); - iniFile.setValue ( "Reduction", ui.slideReduction->value() ); iniFile.setValue("zoom-slowness", ui.slideZoom->value()); + iniFile.setValue("rotation-alpha", ui.rotation_alpha->value()); + iniFile.setValue("translation-alpha", ui.translation_alpha->value()); iniFile.endGroup (); - functionConfig.saveSettings(iniFile); - translationFunctionConfig.saveSettings(iniFile); - settingsDirty = false; } diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp index 3ae273df..0235c067 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp @@ -22,16 +22,7 @@ * with this program; if not, see . * * * ********************************************************************************/ -/* - Modifications (last one on top): - 20120830 - WVR: The Dialog class was used to get general info on the DLL. This - had a big disadvantage: the complete dialog was loaded, just to get - some data and then it was deleted again (without ever showing the dialog). - 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 #include "facetracknoir/global-settings.h" FTNoIR_FilterDll::FTNoIR_FilterDll() { @@ -42,15 +33,6 @@ FTNoIR_FilterDll::~FTNoIR_FilterDll() } -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter object. - -// Export both decorated and undecorated names. -// 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") - extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() { return new FTNoIR_FilterDll; -- cgit v1.2.3