From b367b4c39090735ddf40df757ae381f4b4fe13cb Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 16 May 2016 13:08:20 +0200 Subject: tracker/tobii-eyex: initial revision --- tracker-tobii-eyex/tobii-eyex.hpp | 135 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tracker-tobii-eyex/tobii-eyex.hpp (limited to 'tracker-tobii-eyex/tobii-eyex.hpp') diff --git a/tracker-tobii-eyex/tobii-eyex.hpp b/tracker-tobii-eyex/tobii-eyex.hpp new file mode 100644 index 00000000..d8bb3606 --- /dev/null +++ b/tracker-tobii-eyex/tobii-eyex.hpp @@ -0,0 +1,135 @@ +#pragma once + +/* Copyright (c) 2016 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 + +#include "ui_tobii-eyex-dialog.h" +#include "opentrack/plugin-api.hpp" +#include "opentrack-compat/options.hpp" +using namespace options; +#include "opentrack-compat/timer.hpp" +#include "spline-widget/functionconfig.h" +#include "spline-widget/qfunctionconfigurator.h" + +#include +#include +#include + +enum tobii_mode +{ + tobii_relative, + tobii_absolute, +}; + +struct rel_settings : public QObject, public opts +{ + using s = slider_value; + value speed, dz_end_pt, expt_val, log_base; + rel_settings(); +private: + // linear coefficient to be the same as exponent + Map spline; +}; + +struct settings : public opts +{ + value mode; + settings() : + opts("tobii-eyex"), + mode(b, "mode", tobii_relative) + {} +}; + +class tobii_eyex_tracker : public ITracker +{ +public: + tobii_eyex_tracker(); + ~tobii_eyex_tracker() override; + void start_tracker(QFrame *) override; + void data(double *data) override; + bool center() override + { + do_center = true; + return true; + } +private: + static constexpr const char* client_id = "opentrack-tobii-eyex"; + + static void call_tx_deinit(); + + static bool register_state_snapshot(TX_CONTEXTHANDLE ctx, TX_HANDLE* state_snapshot_ptr); + static std::atomic_flag atexit_done; + static void TX_CALLCONVENTION connection_state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param); + static void TX_CALLCONVENTION event_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param); + void gaze_data_handler(TX_HANDLE gaze_data_handle); + static void TX_CALLCONVENTION snapshot_committed_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param); + static void TX_CALLCONVENTION display_state_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param); + void process_display_state(TX_HANDLE display_state_handle); + + using num = double; + + template + static num piecewise(num x, const funs_seq& funs, const bounds_seq& bounds); + + using fun_t = std::function; + + num gain(num x); + + settings s; + rel_settings rel_s; + + TX_CONTEXTHANDLE dev_ctx; + TX_TICKET conn_state_changed_ticket; + TX_TICKET event_handler_ticket; + TX_HANDLE state_snapshot; + TX_HANDLE display_state; + + QMutex global_state_mtx; + + Timer t; + + struct state + { + TX_REAL display_res_x, display_res_y; + TX_REAL px, py; + TX_REAL last_timestamp; + bool fresh; + + state() : display_res_x(-1), display_res_y(-1), px(-1), py(-1), last_timestamp(0), fresh(false) {} + bool is_valid() const { return !(display_res_x < 0 || px < 0); } + } dev_state; + + double yaw, pitch; + volatile bool do_center; +}; + +class tobii_eyex_dialog final : public ITrackerDialog +{ + Q_OBJECT +public: + tobii_eyex_dialog(); + void register_tracker(ITracker *) override {} + void unregister_tracker() override {} +private: + Ui::tobii_eyex_dialog_widgets ui; + settings s; + rel_settings rs; +private slots: + void do_ok(); + void do_cancel(); +}; + +class tobii_eyex_metadata : public Metadata +{ +public: + QString name() { return QString("Tobii EyeX"); } + QIcon icon() { return QIcon(":/images/tobii-eyex-logo.png"); } +}; + -- cgit v1.2.3 From fd86eebdd12158d80e4af190e7e7a474b410ce5a Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 7 Aug 2016 12:19:20 +0200 Subject: tracker/tobii: remove existing mapping code. maybe later revert this. It doesn't work good enough. Try use splines instead. --- tracker-tobii-eyex/CMakeLists.txt | 1 + tracker-tobii-eyex/tobii-eyex.cpp | 108 ++++++++++++++------------------------ tracker-tobii-eyex/tobii-eyex.hpp | 21 ++++---- 3 files changed, 48 insertions(+), 82 deletions(-) (limited to 'tracker-tobii-eyex/tobii-eyex.hpp') diff --git a/tracker-tobii-eyex/CMakeLists.txt b/tracker-tobii-eyex/CMakeLists.txt index a5fb3404..465801ac 100644 --- a/tracker-tobii-eyex/CMakeLists.txt +++ b/tracker-tobii-eyex/CMakeLists.txt @@ -2,6 +2,7 @@ if(WIN32) set(SDK_TOBII_EYEX "" CACHE PATH "") if(SDK_TOBII_EYEX) opentrack_boilerplate(opentrack-tracker-tobii-eyex) + target_link_libraries(opentrack-tracker-tobii-eyex opentrack-spline-widget) set(tobii-libdir ${SDK_TOBII_EYEX}/lib/x86/) set(tobii-dll ${tobii-libdir}/Tobii.EyeX.Client.dll) # we only care about the .lib for MSVC++ build anyway diff --git a/tracker-tobii-eyex/tobii-eyex.cpp b/tracker-tobii-eyex/tobii-eyex.cpp index d668a4e2..709f1b8f 100644 --- a/tracker-tobii-eyex/tobii-eyex.cpp +++ b/tracker-tobii-eyex/tobii-eyex.cpp @@ -42,13 +42,46 @@ static constexpr t clamp(t datum, t min, t max) return ((datum > max) ? max : ((datum < min) ? min : datum)); } +void rel_settings::draw_spline() +{ + Map& spline = acc_mode_spline; + + spline.removeAllPoints(); + + static constexpr float std_norm_expt = 1.f/3; + const float norm_expt = std_norm_expt * float(expt_norm.get()); + static constexpr float std_norm_lin = 2.f/3; + const float norm_lin = clamp((1-norm_expt) * lin_norm.get() * std_norm_lin, 0, 1); + +} + rel_settings::rel_settings() : opts("tobii-eyex-relative-mode"), speed(b, "speed", s(5, .1, 10)), - dz_end_pt(b, "deadzone-length", s(.05, 0, .2)), - expt_val(b, "exponent", s(1.75, 1.25, 2.25)), - log_base(b, "logarithm-base", s(1.75, 1.1, 5)) -{} + dz_end_pt(b, "deadzone-length", s(4, 0, 15)), + expt_slope(b, "exponent-slope", s(1.5, 1.25, 3)), + expt_norm(b, "exponent-norm", s(1, .25, 4)), + lin_norm(b, "linear-norm", s(1, .25, 4)), + acc_mode_spline(100, 100) +{ + QObject::connect(&dz_end_pt, + static_cast(&base_value::valueChanged), + this, + &rel_settings::draw_spline); + QObject::connect(&expt_slope, + static_cast(&base_value::valueChanged), + this, + &rel_settings::draw_spline); + QObject::connect(&expt_norm, + static_cast(&base_value::valueChanged), + this, + &rel_settings::draw_spline); + QObject::connect(&lin_norm, + static_cast(&base_value::valueChanged), + this, + &rel_settings::draw_spline); + draw_spline(); +} tobii_eyex_tracker::tobii_eyex_tracker() : dev_ctx(TX_EMPTY_HANDLE), @@ -310,74 +343,9 @@ plot_fn(lambda x: piecewise(x, [zero, f, g, h], [.05, .25, .7, 1.])) */ -template -tobii_eyex_tracker::num tobii_eyex_tracker::piecewise(num x, const funs_seq& funs, const bounds_seq& bounds) -{ - using fn = std::function; - - auto funs_it = std::begin(funs); - auto bounds_it = std::begin(bounds); - - auto funs_end = std::end(funs); - auto bounds_end = std::end(bounds); - - num norm = 0; - - for (const fn& f : funs) - { - norm += f(1); - } - - norm = std::max(num(1e-4), norm); - - num last_bound = 0, y = 0; - - for (; - bounds_it != bounds_end && funs_it != funs_end; - bounds_it++, funs_it++) - { - const fn& fun = *funs_it; - const num bound = *bounds_it; - - if (x > bound) - { - y += fun(1); - last_bound = bound; - } - else - { - const num b = bound - last_bound; - // rescale x to 0->1 - const num x_ = (x - last_bound) / b; - y += fun(x_); - break; - } - } - return clamp(y / norm, num(0), num(1)); -} - tobii_eyex_tracker::num tobii_eyex_tracker::gain(num x_) { - const num x = std::fabs(x_); - - static const fun_t funs[] = - { - [](num) -> num { return num(0); }, - [](num x) -> num { return std::pow(x, 1.1)*.08; }, - [](num x) -> num { return x*.5; }, - }; - - static constexpr num dz_l = .1, expt_l = .3; - - static constexpr num ends[] = - { - dz_l, - expt_l, - 1, - }; - - const num ret = piecewise(x, funs, ends); - return std::copysign(clamp(ret, num(0), num(1)), x_); + return 1; } void tobii_eyex_tracker::data(double* data) diff --git a/tracker-tobii-eyex/tobii-eyex.hpp b/tracker-tobii-eyex/tobii-eyex.hpp index d8bb3606..f64f2495 100644 --- a/tracker-tobii-eyex/tobii-eyex.hpp +++ b/tracker-tobii-eyex/tobii-eyex.hpp @@ -16,7 +16,7 @@ using namespace options; #include "opentrack-compat/timer.hpp" #include "spline-widget/functionconfig.h" -#include "spline-widget/qfunctionconfigurator.h" +#include "qfunctionconfigurator.h" #include #include @@ -28,17 +28,19 @@ enum tobii_mode tobii_absolute, }; -struct rel_settings : public QObject, public opts +class rel_settings final : public QObject, public opts { + Q_OBJECT +public: using s = slider_value; - value speed, dz_end_pt, expt_val, log_base; + value speed, dz_end_pt, expt_slope, expt_norm, lin_norm; + Map acc_mode_spline; rel_settings(); -private: - // linear coefficient to be the same as exponent - Map spline; +private slots: + void draw_spline(); }; -struct settings : public opts +struct settings final : public opts { value mode; settings() : @@ -75,11 +77,6 @@ private: using num = double; - template - static num piecewise(num x, const funs_seq& funs, const bounds_seq& bounds); - - using fun_t = std::function; - num gain(num x); settings s; -- cgit v1.2.3 From 9a85b814d908a28fb7444b7e1b5afae9fe629784 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 19 Sep 2016 15:05:17 +0200 Subject: tracker/tobii: fix bitrot --- tracker-tobii-eyex/tobii-eyex-dialog.ui | 49 +++++++++++++++++++-------------- tracker-tobii-eyex/tobii-eyex.cpp | 16 +++++------ tracker-tobii-eyex/tobii-eyex.hpp | 12 ++++---- 3 files changed, 42 insertions(+), 35 deletions(-) (limited to 'tracker-tobii-eyex/tobii-eyex.hpp') diff --git a/tracker-tobii-eyex/tobii-eyex-dialog.ui b/tracker-tobii-eyex/tobii-eyex-dialog.ui index 81fc13d6..1a85f417 100644 --- a/tracker-tobii-eyex/tobii-eyex-dialog.ui +++ b/tracker-tobii-eyex/tobii-eyex-dialog.ui @@ -6,7 +6,7 @@ 0 0 - 715 + 710 440 @@ -208,25 +208,6 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 25 - - - @@ -563,11 +544,30 @@ + + + + + 0 + 0 + + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 25 + + + - + 0 @@ -616,6 +616,13 @@ + + + spline_widget + QWidget +
spline-widget/spline-widget.hpp
+
+
diff --git a/tracker-tobii-eyex/tobii-eyex.cpp b/tracker-tobii-eyex/tobii-eyex.cpp index 709f1b8f..74c31240 100644 --- a/tracker-tobii-eyex/tobii-eyex.cpp +++ b/tracker-tobii-eyex/tobii-eyex.cpp @@ -44,14 +44,14 @@ static constexpr t clamp(t datum, t min, t max) void rel_settings::draw_spline() { - Map& spline = acc_mode_spline; + spline& spline = acc_mode_spline; spline.removeAllPoints(); static constexpr float std_norm_expt = 1.f/3; - const float norm_expt = std_norm_expt * float(expt_norm.get()); + const float norm_expt = std_norm_expt * float(expt_norm->cur()); static constexpr float std_norm_lin = 2.f/3; - const float norm_lin = clamp((1-norm_expt) * lin_norm.get() * std_norm_lin, 0, 1); + const float norm_lin = clamp((1-norm_expt) * lin_norm->cur() * std_norm_lin, 0., 1.); } @@ -62,22 +62,22 @@ rel_settings::rel_settings() : expt_slope(b, "exponent-slope", s(1.5, 1.25, 3)), expt_norm(b, "exponent-norm", s(1, .25, 4)), lin_norm(b, "linear-norm", s(1, .25, 4)), - acc_mode_spline(100, 100) + acc_mode_spline(100, 100, "") { QObject::connect(&dz_end_pt, - static_cast(&base_value::valueChanged), + static_cast(&base_value::valueChanged), this, &rel_settings::draw_spline); QObject::connect(&expt_slope, - static_cast(&base_value::valueChanged), + static_cast(&base_value::valueChanged), this, &rel_settings::draw_spline); QObject::connect(&expt_norm, - static_cast(&base_value::valueChanged), + static_cast(&base_value::valueChanged), this, &rel_settings::draw_spline); QObject::connect(&lin_norm, - static_cast(&base_value::valueChanged), + static_cast(&base_value::valueChanged), this, &rel_settings::draw_spline); draw_spline(); diff --git a/tracker-tobii-eyex/tobii-eyex.hpp b/tracker-tobii-eyex/tobii-eyex.hpp index f64f2495..aeac4d89 100644 --- a/tracker-tobii-eyex/tobii-eyex.hpp +++ b/tracker-tobii-eyex/tobii-eyex.hpp @@ -11,12 +11,12 @@ #include #include "ui_tobii-eyex-dialog.h" -#include "opentrack/plugin-api.hpp" -#include "opentrack-compat/options.hpp" +#include "api/plugin-api.hpp" +#include "options/options.hpp" using namespace options; -#include "opentrack-compat/timer.hpp" -#include "spline-widget/functionconfig.h" -#include "qfunctionconfigurator.h" +#include "compat/timer.hpp" +#include "spline-widget/spline.hpp" +#include "spline-widget/spline-widget.hpp" #include #include @@ -34,7 +34,7 @@ class rel_settings final : public QObject, public opts public: using s = slider_value; value speed, dz_end_pt, expt_slope, expt_norm, lin_norm; - Map acc_mode_spline; + spline acc_mode_spline; rel_settings(); private slots: void draw_spline(); -- cgit v1.2.3