diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2015-09-30 16:21:41 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2015-09-30 16:22:00 +0200 |
commit | ac4dc94acc5d1e1d8fd4867730b835e2aa1fcc89 (patch) | |
tree | 8ca3dc84958e572e3f890ac3f56dfda670c63f60 /opentrack | |
parent | 03a164ed74d616e8d5203142ec7e9738c8aae547 (diff) | |
parent | eb7703b4ecea5540a4c4a65faa1ff4c53fe97631 (diff) |
Merge branch 'unstable' into trackhat-ui
Sponsored-by: TrackHat
* unstable: (112 commits)
Revert "accela: try more complex deadzone algorithm"
pt: add wiki link for calibration instructions
qfc: more gray colors when graph is disabled
qfc, mapping: disallow editing and change color when checkbox disabled
qfc: don't allow editing when disabled
plugin-support: workaround multiple copies of modules
accela: change translation gain
accela: change rotation gain
pt: change extraction code
freepie-udp: add license
freepie-udp: update
accela: try more complex deadzone algorithm
accela: add helpful comment
accela: revert to more quadratic spline at start
also save if save pending when start tracking
ui: force saving if saving timer is pending
accela: slightly more linear function
pose-widget: simplify
freepie-udp: nix harmless warning
pose-widget: add comment
simple-mat: add __restrict for GNU
ui: save settings on a timer
ui: show a warning if configuration directory can't be used
aruco: tune min/max marker size
win32-joystick: fix duplicate device name selection logic
ui: no need to reset settings on tracking start
ui: save profile when combobox text changes, not merely index
ui: save current tracker/filter/proto, not last
win32-joystick: fix COM failure path
win32-joystick: nix unused variable
win32-joystick: allow for unique selection of joysticks
qfc: also draw line from function start while moving
no need to save on tracking start anymore
save axis opts, not just spline control points
tracker: change centering order again
fix typo
cmake: don't say "opentrack" twice for osx build
ui: really don't switch profiles while refreshing combobox
pt: fix type mismatch
ui: save prior to switching configs
tracker_rs: adjusted tracker's name
ui: don't reload settings if config wasn't changed
ui: save everything before switching profiles
options: return .ini basename easier
tracker_rs: more readable icon
tracker_rs: prevent potential thread starvation
ui: switch to newly-created config
ui: decruft
ui: also bail on new config if its name is ".ini"
ui: auto-refresh config list
ui: display up to 20 profiles w/o scrolling
ui: create an empty config properly in another code branch
udp-tracker: silence harmless warning
plugin-support: fix typo
plugin-support: set more sane RTLD flags
plugin-support: free modules from address space when needed
ui: rename symbol to reflect current usage
ui: move some slots to private
ui, shortcuts: these are slots, actually
ui: no need to write anything to new empty config
ui: avoid potential memory leak
ft: new game support
game-data: chomp newlines in extractor
ui: append extension in the right place
simple-mat: fix arglist SFINAE
simple-mat: can use static_cast here
nix default empty config. it gets created on its own.
ui: these aren't qt slots
ui: nix wrong headers
ui: remove GNU GPL
ui: simplify condition
props changed only
main, ui: store config files in a predefined directory
pt: show extracted points' areas and success count
close dialogs on switch to new module
...
Diffstat (limited to 'opentrack')
-rw-r--r-- | opentrack/main-settings.hpp | 2 | ||||
-rw-r--r-- | opentrack/mappings.hpp | 3 | ||||
-rw-r--r-- | opentrack/options.hpp | 59 | ||||
-rw-r--r-- | opentrack/plugin-api.hpp | 2 | ||||
-rw-r--r-- | opentrack/plugin-support.hpp | 10 | ||||
-rw-r--r-- | opentrack/simple-mat.hpp | 103 | ||||
-rw-r--r-- | opentrack/tracker.cpp | 52 | ||||
-rw-r--r--[-rwxr-xr-x] | opentrack/win32-shortcuts.cpp | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | opentrack/win32-shortcuts.h | 0 |
9 files changed, 144 insertions, 87 deletions
diff --git a/opentrack/main-settings.hpp b/opentrack/main-settings.hpp index 96520fe9..dd61143e 100644 --- a/opentrack/main-settings.hpp +++ b/opentrack/main-settings.hpp @@ -15,9 +15,11 @@ using namespace options; struct axis_opts { + pbundle b; value<bool> invert, altp; value<int> src; axis_opts(pbundle b, QString pfx, int idx) : + b(b), invert(b, n(pfx, "invert-sign"), false), altp(b, n(pfx, "alt-axis-sign"), false), src(b, n(pfx, "source-index"), idx) diff --git a/opentrack/mappings.hpp b/opentrack/mappings.hpp index 85d9900c..2391efd1 100644 --- a/opentrack/mappings.hpp +++ b/opentrack/mappings.hpp @@ -62,6 +62,7 @@ public: { axes[i].curve.loadSettings(*iniFile, axes[i].name1); axes[i].curveAlt.loadSettings(*iniFile, axes[i].name2); + axes[i].opts.b->reload(); } } void save_mappings() @@ -72,6 +73,7 @@ public: { axes[i].curve.saveSettings(*iniFile, axes[i].name1); axes[i].curveAlt.saveSettings(*iniFile, axes[i].name2); + axes[i].opts.b->save(); } } @@ -81,6 +83,7 @@ public: { axes[i].curve.invalidate_unsaved_settings(); axes[i].curveAlt.invalidate_unsaved_settings(); + axes[i].opts.b->reload(); } } }; diff --git a/opentrack/options.hpp b/opentrack/options.hpp index 9768bc43..f2c09479 100644 --- a/opentrack/options.hpp +++ b/opentrack/options.hpp @@ -30,6 +30,7 @@ #include <QCoreApplication> #include <QFileInfo> #include <QDir> +#include <QStandardPaths> #include <cinttypes> @@ -38,8 +39,8 @@ #include <memory> template<typename t> using mem = std::shared_ptr<t>; -#define OPENTRACK_CONFIG_FILENAME_KEY "settings-file" -#define OPENTRACK_DEFAULT_CONFIG_PATH "/settings/default.ini" +#define OPENTRACK_CONFIG_FILENAME_KEY "settings-filename" +#define OPENTRACK_DEFAULT_CONFIG "default.ini" #define OPENTRACK_ORG "TrackHat opentrack-2.3" namespace options { @@ -90,30 +91,30 @@ namespace options { public: group(const string& name) : name(name) { - QSettings conf(ini_pathname(), QSettings::IniFormat); + auto conf = ini_file(); auto q_name = QString::fromStdString(name); - conf.beginGroup(q_name); - for (auto& k_ : conf.childKeys()) + conf->beginGroup(q_name); + for (auto& k_ : conf->childKeys()) { auto tmp = k_.toUtf8(); string k(tmp); - kvs[k] = conf.value(k_); + kvs[k] = conf->value(k_); } - conf.endGroup(); + conf->endGroup(); } void save() { - QSettings s(ini_pathname(), QSettings::IniFormat); + auto s = ini_file(); auto q_name = QString::fromStdString(name); - s.beginGroup(q_name); + s->beginGroup(q_name); for (auto& i : kvs) { auto k = QString::fromStdString(i.first); - s.setValue(k, i.second); + s->setValue(k, i.second); } - s.endGroup(); - s.sync(); + s->endGroup(); + s->sync(); } template<typename t> @@ -132,22 +133,46 @@ namespace options { return kvs.count(s) != 0; } - static const QString ini_pathname() + static QString ini_directory() { + const auto dirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); + if (dirs.size() == 0) + return ""; + if (QDir(dirs[0]).mkpath(OPENTRACK_ORG)) + return dirs[0] + "/" OPENTRACK_ORG; + return ""; + } + + static QString ini_filename() + { + QSettings settings(OPENTRACK_ORG); + return settings.value(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG).toString(); + } + + static QString ini_pathname() + { + const auto dir = ini_directory(); + if (dir == "") + return ""; QSettings settings(OPENTRACK_ORG); - return settings.value(OPENTRACK_CONFIG_FILENAME_KEY, QCoreApplication::applicationDirPath() + OPENTRACK_DEFAULT_CONFIG_PATH).toString(); + return dir + "/" + settings.value(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG).toString(); } static const QStringList ini_list() { - QFileInfo info(group::ini_pathname()); - QDir settings_dir(info.dir()); + const auto dirname = ini_directory(); + if (dirname == "") + return QStringList(); + QDir settings_dir(dirname); return settings_dir.entryList( QStringList { "*.ini" } , QDir::Files, QDir::Name ); } static const mem<QSettings> ini_file() { - return std::make_shared<QSettings>(ini_pathname(), QSettings::IniFormat); + const auto pathname = ini_pathname(); + if (pathname != "") + return std::make_shared<QSettings>(ini_pathname(), QSettings::IniFormat); + return std::make_shared<QSettings>(); } }; diff --git a/opentrack/plugin-api.hpp b/opentrack/plugin-api.hpp index 572b7f31..732dbb3d 100644 --- a/opentrack/plugin-api.hpp +++ b/opentrack/plugin-api.hpp @@ -42,7 +42,7 @@ signals: } // implement this in all plugins -// also you must link against "opentrack-api" in CMakeList.txt to avoid vtable link errors +// also you must link against "opentrack-api" in CMakeLists.txt to avoid vtable link errors struct Metadata { // plugin name to be displayed in the interface diff --git a/opentrack/plugin-support.hpp b/opentrack/plugin-support.hpp index 78443cae..cd7eb528 100644 --- a/opentrack/plugin-support.hpp +++ b/opentrack/plugin-support.hpp @@ -103,7 +103,7 @@ struct dylib { # if defined(__APPLE__) RTLD_LOCAL|RTLD_FIRST|RTLD_NOW # else - RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE + RTLD_LOCAL|RTLD_NOW // XXX RTLD_DEEPBIND on Linux? # endif ); @@ -184,6 +184,14 @@ struct dylib { std::cout.flush(); if (!get_metadata(lib, longName, icon)) continue; + using d = const mem<dylib>&; + if (std::any_of(ret.cbegin(), + ret.cend(), + [&](d a) {return a->type == lib->type && a->name == lib->name;})) + { + qDebug() << "Duplicate lib" << lib->filename; + continue; + } ret.push_back(lib); } } diff --git a/opentrack/simple-mat.hpp b/opentrack/simple-mat.hpp index 7432e665..e462812b 100644 --- a/opentrack/simple-mat.hpp +++ b/opentrack/simple-mat.hpp @@ -41,66 +41,84 @@ namespace { enum { P = a == 1 ? 1 : 3 }; enum { Q = a == 1 ? 3 : 1 }; }; + + template<typename num, int h, int w, typename...ts> + struct is_arglist_correct + { + enum { value = h * w == sizeof...(ts) }; + }; } template<typename num, int h_, int w_> -struct Mat +class Mat { +#ifdef __GNUC__ + __restrict +#endif num data[h_][w_]; + + static_assert(h_ > 0 && w_ > 0, "must have positive mat dimensions"); + + Mat(std::initializer_list<num>&& xs) = delete; + +public: + + // parameters w_ and h_ are rebound so that SFINAE occurs + // removing them causes a compile-time error -sh 20150811 template<int Q = w_> typename std::enable_if<equals<Q, 1, 0>::value, num>::type - __inline operator()(int i) const { return data[i][0]; } + inline operator()(int i) const { return data[i][0]; } template<int P = h_> typename std::enable_if<equals<P, 1, 1>::value, num>::type - __inline operator()(int i) const { return data[0][i]; } + inline operator()(int i) const { return data[0][i]; } template<int Q = w_> typename std::enable_if<equals<Q, 1, 2>::value, num&>::type - __inline operator()(int i) { return data[i][0]; } + inline operator()(int i) { return data[i][0]; } template<int P = h_> typename std::enable_if<equals<P, 1, 3>::value, num&>::type - __inline operator()(int i) { return data[0][i]; } + inline operator()(int i) { return data[0][i]; } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 1>::value, num>::type - __inline x() const { return operator()(0); } + inline x() const { return operator()(0); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 2>::value, num>::type - __inline y() const { return operator()(1); } + inline y() const { return operator()(1); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 3>::value, num>::type - __inline z() const { return operator()(2); } + inline z() const { return operator()(2); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 4>::value, num>::type - __inline w() const { return operator()(3); } + inline w() const { return operator()(3); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 1>::value, num&>::type - __inline x() { return operator()(0); } + inline x() { return operator()(0); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 2>::value, num&>::type - __inline y() { return operator()(1); } + inline y() { return operator()(1); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 3>::value, num&>::type - __inline z() { return operator()(2); } + inline z() { return operator()(2); } template<int P = h_, int Q = w_> typename std::enable_if<maybe_add_swizzle<P, Q, 4>::value, num&>::type - __inline w() { return operator()(3); } + inline w() { return operator()(3); } template<int R, int S, int P = h_, int Q = w_> typename std::enable_if<is_vector_pair<R, S, P, Q>::value, num>::type - __inline dot(const Mat<num, R, S>& p2) const { + dot(const Mat<num, R, S>& p2) const { num ret = 0; constexpr int len = vector_len<R, S>::value; for (int i = 0; i < len; i++) - ret += operator()(i) * p2.operator ()(i); + ret += operator()(i) * p2(i); return ret; } template<int R, int S, int P = h_, int Q = w_> typename std::enable_if<is_dim3<P, Q, R, S>::value, Mat<num, is_dim3<P, Q, R, S>::P, is_dim3<P, Q, R, S>::Q>>::type - __inline cross(const Mat<num, R, S>& p2) const + cross(const Mat<num, R, S>& p2) const { - return Mat<num, R, S>({y() * p2.z() - p2.y() * z(), - p2.x() * z() - x() * p2.z(), - x() * p2.y() - y() * p2.x()}); + return Mat<num, R, S>(y() * p2.z() - p2.y() * z(), + p2.x() * z() - x() * p2.z(), + x() * p2.y() - y() * p2.x()); } Mat<num, h_, w_> operator+(const Mat<num, h_, w_>& other) const @@ -108,7 +126,7 @@ struct Mat Mat<num, h_, w_> ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - ret(j, i) = this->operator ()(j, i) + other(j, i); + ret(j, i) = data[j][i] + other.data[j][i]; return ret; } @@ -117,7 +135,7 @@ struct Mat Mat<num, h_, w_> ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - ret(j, i) = this->operator ()(j, i) - other(j, i); + ret(j, i) = data[j][i] - other.data[j][i]; return ret; } @@ -126,7 +144,7 @@ struct Mat Mat<num, h_, w_> ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - ret(j, i) = this->operator ()(j, i) + other; + ret(j, i) = data[j][i] + other; return ret; } @@ -135,7 +153,7 @@ struct Mat Mat<num, h_, w_> ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - ret(j, i) = this->operator ()(j, i) - other; + ret(j, i) = data[j][i] - other; return ret; } @@ -144,7 +162,7 @@ struct Mat Mat<num, h_, w_> ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - ret(j, i) = operator()(j, i) * other; + ret(j, i) = data[j][i] * other; return ret; } @@ -158,30 +176,41 @@ struct Mat num sum = num(0); for (int k = 0; k < h_; k++) - sum += data[j][k]*other.data[k][i]; + sum += data[j][k]*other(k, i); - ret.data[j][i] = sum; + ret(j, i) = sum; } return ret; } - __inline num operator()(int j, int i) const { return data[j][i]; } - __inline num& operator()(int j, int i) { return data[j][i]; } + inline num operator()(int j, int i) const { return data[j][i]; } + inline num& operator()(int j, int i) { return data[j][i]; } - Mat(std::initializer_list<num>&& list) + template<typename... ts, int h__ = h_, int w__ = w_, + typename = typename std::enable_if<is_arglist_correct<num, h__, w__, ts...>::value>::type> + Mat(ts const&... xs) { - auto iter = list.begin(); - for (int i = 0; i < h_; i++) - for (int j = 0; j < w_; j++) - data[i][j] = *iter++; + const std::initializer_list<num> init = { static_cast<num>(xs)... }; + auto iter = init.begin(); + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + data[j][i] = *iter++; + } + + template<typename t> + Mat(const t* xs) + { + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + data[j][i] = num(*xs++); } Mat() { for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) - data[j][i] = 0; + data[j][i] = num(0); } Mat(const num* mem) @@ -191,6 +220,8 @@ struct Mat data[j][i] = mem[i*h_+j]; } + Mat(num* mem) : Mat(const_cast<const num*>(mem)) {} + // XXX add more operators as needed, third-party dependencies mostly // not needed merely for matrix algebra -sh 20141030 @@ -234,10 +265,10 @@ struct Mat if (std::abs(pitch_1) + std::abs(roll_1) + std::abs(yaw_1) > std::abs(pitch_2) + std::abs(roll_2) + std::abs(yaw_2)) { bool fix_neg_pitch = pitch_1 < 0; - return dmat<3, 1>({yaw_2, std::fmod(fix_neg_pitch ? -pi - pitch_1 : pitch_2, pi), roll_2}); + return dmat<3, 1>(yaw_2, std::fmod(fix_neg_pitch ? -pi - pitch_1 : pitch_2, pi), roll_2); } else - return dmat<3, 1>({yaw_1, pitch_1, roll_1}); + return dmat<3, 1>(yaw_1, pitch_1, roll_1); } // tait-bryan angles, not euler diff --git a/opentrack/tracker.cpp b/opentrack/tracker.cpp index e9d85f5d..58e911bf 100644 --- a/opentrack/tracker.cpp +++ b/opentrack/tracker.cpp @@ -52,14 +52,14 @@ double Tracker::map(double pos, Mapping& axis) void Tracker::t_compensate(const rmat& rmat, const double* xyz, double* output, bool rz) { // TY is really yaw axis. need swapping accordingly. - dmat<3, 1> tvec({ xyz[2], -xyz[0], -xyz[1] }); + dmat<3, 1> tvec( xyz[2], -xyz[0], -xyz[1] ); const dmat<3, 1> ret = rmat * tvec; if (!rz) - output[2] = ret(0, 0); + output[2] = ret(0); else output[2] = xyz[2]; - output[1] = -ret(2, 0); - output[0] = -ret(1, 0); + output[1] = -ret(2); + output[0] = -ret(1); } void Tracker::logic() @@ -81,7 +81,12 @@ void Tracker::logic() if (!zero_) for (int i = 0; i < 6; i++) { - value(i) = newpose[i]; + auto& axis = m(i); + int k = axis.opts.src; + if (k < 0 || k >= 6) + value(i) = 0; + else + value(i) = newpose[k]; raw(i) = newpose[i]; } else @@ -90,7 +95,7 @@ void Tracker::logic() for (int i = 0; i < 3; i++) { - raw(i+3) = value(i+3) = mat(i, 0) * r2d; + raw(i+3) = value(i+3) = mat(i) * r2d; raw(i) = value(i) = t_b[i]; } } @@ -102,7 +107,7 @@ void Tracker::logic() }; const rmat cam = rmat::euler_to_rmat(off); rmat r = rmat::euler_to_rmat(&value[Yaw]); - dmat<3, 1> t { value(0), value(1), value(2) }; + dmat<3, 1> t(value(0), value(1), value(2)); r = cam * r; @@ -122,19 +127,19 @@ void Tracker::logic() { centerp = false; for (int i = 0; i < 3; i++) - t_b[i] = t(i, 0); + t_b[i] = t(i); r_b = r; } { - double tmp[3] = { t(0, 0) - t_b[0], t(1, 0) - t_b[1], t(2, 0) - t_b[2] }; + double tmp[3] = { t(0) - t_b[0], t(1) - t_b[1], t(2) - t_b[2] }; t_compensate(cam, tmp, tmp, false); - const rmat m_ = r_b.t() * r; + const rmat m_ = r * r_b.t(); const dmat<3, 1> euler = rmat::rmat_to_euler(m_); for (int i = 0; i < 3; i++) { value(i) = tmp[i]; - value(i+3) = euler(i, 0) * r2d; + value(i+3) = euler(i) * r2d; } } @@ -144,7 +149,7 @@ void Tracker::logic() if (libs.pFilter) libs.pFilter->filter(tmp, value); } - + for (int i = 0; i < 6; i++) value(i) = map(value(i), m(i)); @@ -153,27 +158,14 @@ void Tracker::logic() value, value, s.tcomp_tz); - - for (int i = 0; i < 6; i++) - value[i] *= inverts[i] ? -1. : 1.; - - Pose output_pose_; for (int i = 0; i < 6; i++) - { - auto& axis = m(i); - int k = axis.opts.src; - if (k < 0 || k >= 6) - output_pose_(i) = 0; - else - output_pose_(i) = value(k); - } - + value[i] *= inverts[i] ? -1. : 1.; - libs.pProtocol->pose(output_pose_); + libs.pProtocol->pose(value); QMutexLocker foo(&mtx); - output_pose = output_pose_; + output_pose = value; raw_6dof = raw; } @@ -202,10 +194,6 @@ void Tracker::run() { } { - // do one last pass with origin pose - for (int i = 0; i < 6; i++) - newpose[i] = 0; - logic(); // filter may inhibit exact origin Pose p; libs.pProtocol->pose(p); diff --git a/opentrack/win32-shortcuts.cpp b/opentrack/win32-shortcuts.cpp index d4107949..d4107949 100755..100644 --- a/opentrack/win32-shortcuts.cpp +++ b/opentrack/win32-shortcuts.cpp diff --git a/opentrack/win32-shortcuts.h b/opentrack/win32-shortcuts.h index 3e824b89..3e824b89 100755..100644 --- a/opentrack/win32-shortcuts.h +++ b/opentrack/win32-shortcuts.h |