diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-07-24 15:51:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-24 15:51:59 +0200 |
commit | cdabb9f3ad3e13e3b76b983a7b3ea6c118fc114e (patch) | |
tree | 785511a0054881447511faaaacd9cdbb8c5e13fd | |
parent | 53bc18790411d7bcd1aae9b5684aa8241666f21e (diff) | |
parent | 8da9e2945e0da7a5954de4f38263aaec8ae84955 (diff) |
Merge pull request #1666 from tombrazier/nm_filter
-rw-r--r-- | compat/hamilton-tools.cpp (renamed from filter-hamilton/hamilton-tools.cpp) | 36 | ||||
-rw-r--r-- | compat/hamilton-tools.h | 76 | ||||
-rw-r--r-- | filter-hamilton/ftnoir_filter_hamilton.cpp | 2 | ||||
-rw-r--r-- | filter-hamilton/ftnoir_filter_hamilton.h | 2 | ||||
-rw-r--r-- | filter-hamilton/hamilton-tools.h | 27 | ||||
-rw-r--r-- | filter-nm/CMakeLists.txt | 1 | ||||
-rw-r--r-- | filter-nm/ftnoir_filter_nm.cpp | 67 | ||||
-rw-r--r-- | filter-nm/ftnoir_filter_nm.h | 81 | ||||
-rw-r--r-- | filter-nm/ftnoir_filter_nm_dialog.cpp | 56 | ||||
-rw-r--r-- | filter-nm/ftnoir_nm_filtercontrols.ui | 312 | ||||
-rw-r--r-- | filter-nm/lang/nl_NL.ts | 62 | ||||
-rw-r--r-- | filter-nm/lang/ru_RU.ts | 62 | ||||
-rw-r--r-- | filter-nm/lang/stub.ts | 62 | ||||
-rw-r--r-- | filter-nm/lang/zh_CN.ts | 62 |
14 files changed, 848 insertions, 60 deletions
diff --git a/filter-hamilton/hamilton-tools.cpp b/compat/hamilton-tools.cpp index e18082a8..eb0ef984 100644 --- a/filter-hamilton/hamilton-tools.cpp +++ b/compat/hamilton-tools.cpp @@ -1,28 +1,7 @@ #include "hamilton-tools.h" #include <cmath> -double VectorLength(const tVector v) -{ - return(sqrt(v.v[0]*v.v[0] + v.v[1]*v.v[1] + v.v[2]*v.v[2])); -} - -double sqr(const double v) { return(v*v); } - -double VectorDistance(const double v1[], const tVector v2) -{ - return(sqrt(sqr(v2.v[0]-v1[0])+sqr(v2.v[1]-v1[1])+sqr(v2.v[2]-v1[2]))); -} - -tVector Lerp(const tVector s, const double d[], const double alpha) -{ - tVector V; - V.v[0] = s.v[0] + (d[0] - s.v[0]) * alpha; - V.v[1] = s.v[1] + (d[1] - s.v[1]) * alpha; - V.v[2] = s.v[2] + (d[2] - s.v[2]) * alpha; - return(V); -} - -tQuat QuatFromAngleAxe(const double angle, const tVector axe) +tQuat QuatFromAngleAxe(const double angle, const tVector& axe) { double a = TO_RAD * 0.5 * angle; double d = sin(a) / VectorLength(axe); @@ -35,7 +14,7 @@ tQuat QuatFromAngleAxe(const double angle, const tVector axe) ); } -tQuat QuatMultiply(const tQuat qL, const tQuat qR) +tQuat QuatMultiply(const tQuat& qL, const tQuat& qR) { tQuat Q; Q.x = qL.w*qR.x + qL.x*qR.w + qL.y*qR.z - qL.z*qR.y; @@ -45,11 +24,6 @@ tQuat QuatMultiply(const tQuat qL, const tQuat qR) return(Q); } -double AngleBetween(const tQuat S, const tQuat D) -{ - return( TO_DEG * 2*acos(fabs(S.x*D.x + S.y*D.y + S.z*D.z + S.w*D.w)) ); -} - tQuat QuatFromYPR(const double YPR[]) { tQuat Q, Qp, Qy; @@ -61,7 +35,7 @@ tQuat QuatFromYPR(const double YPR[]) return(QuatMultiply(Qy, Q)); } -void Normalize(tQuat Q) +void Normalize(tQuat& Q) { double m = sqrt(Q.x*Q.x + Q.y*Q.y + Q.z*Q.z + Q.w*Q.w); if (m > EPSILON) @@ -75,7 +49,7 @@ void Normalize(tQuat Q) else Q = tQuat(0, 0, 0, 1); } -tQuat Slerp(const tQuat S, const tQuat D, const double alpha) +tQuat Slerp(const tQuat& S, const tQuat& D, const double alpha) { // calc cosine of half angle double cosin = S.x*D.x + S.y*D.y + S.z*D.z + S.w*D.w; @@ -117,7 +91,7 @@ tQuat Slerp(const tQuat S, const tQuat D, const double alpha) return( Q ); } -void QuatToYPR(const tQuat Q, double YPR[]) +void QuatToYPR(const tQuat& Q, double YPR[]) { const double xx = Q.x * Q.x; const double xy = Q.x * Q.y; diff --git a/compat/hamilton-tools.h b/compat/hamilton-tools.h new file mode 100644 index 00000000..885e9f79 --- /dev/null +++ b/compat/hamilton-tools.h @@ -0,0 +1,76 @@ +#pragma once + +#include <algorithm> +#include "export.hpp" +#include "compat/math.hpp" + +constexpr double TO_RAD = (M_PI / 180); +constexpr double TO_DEG = (180 / M_PI); +constexpr double EPSILON = 1e-30; + +struct tVector +{ + double v[3]; + tVector(double X = 0, double Y = 0, double Z = 0) {v[0]=X; v[1]=Y; v[2]=Z;} + tVector(const double V[]) {v[0]=V[0]; v[1]=V[1]; v[2]=V[2];} + + void operator=(const tVector& other) + { + std::copy(other.v, other.v + 3, v); + } + inline const tVector operator+(const tVector& other) const + { + return tVector(v[0] + other.v[0], v[1] + other.v[1], v[2] + other.v[2]); + } + void operator+=(const tVector& other) + { + v[0] += other.v[0]; + v[1] += other.v[1]; + v[2] += other.v[2]; + } + const tVector operator-(const tVector& other) const + { + return tVector(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]); + } + void operator-=(const tVector& other) + { + v[0] -= other.v[0]; + v[1] -= other.v[1]; + v[2] -= other.v[2]; + } + const tVector operator*(double scalar) const + { + return tVector(v[0] * scalar, v[1] * scalar, v[2] * scalar); + } + void operator*=(double scalar) + { + v[0] *= scalar; + v[1] *= scalar; + v[2] *= scalar; + } + const tVector operator/(double scalar) const + { + return *this * (1.0 / scalar); + } + void operator/= (double scalar) + { + *this *= 1.0 / scalar; + } +}; + +struct tQuat +{ + double x, y, z, w; + tQuat(double X = 0, double Y = 0, double Z = 0, double W = 1) + {x = X; y = Y; z = Z; w = W;} +}; + +inline double VectorLength(const tVector& v) { return sqrt(v.v[0] * v.v[0] + v.v[1] * v.v[1] + v.v[2] * v.v[2]); } +inline double VectorDistance(const tVector& v1, const tVector& v2) { return VectorLength(v2 - v1); } +inline tVector Lerp(const tVector& s, const tVector& d, const double alpha) { return s + (d - s) * alpha; } +tQuat OTR_COMPAT_EXPORT QuatFromYPR(const double YPR[]); +tQuat OTR_COMPAT_EXPORT QuatMultiply(const tQuat& qL, const tQuat& qR); +inline tQuat QuatDivide(const tQuat& qL, const tQuat& qR) { return QuatMultiply(qL, tQuat(-qR.x, -qR.y, -qR.z, qR.w)); } +inline double AngleBetween(const tQuat& S, const tQuat& D) { return TO_DEG * 2 * acos(fabs(S.x * D.x + S.y * D.y + S.z * D.z + S.w * D.w)); } +tQuat OTR_COMPAT_EXPORT Slerp(const tQuat& S, const tQuat& D, const double alpha); +void OTR_COMPAT_EXPORT QuatToYPR(const tQuat& Q, double YPR[]); diff --git a/filter-hamilton/ftnoir_filter_hamilton.cpp b/filter-hamilton/ftnoir_filter_hamilton.cpp index 7bbc91de..c4429ecc 100644 --- a/filter-hamilton/ftnoir_filter_hamilton.cpp +++ b/filter-hamilton/ftnoir_filter_hamilton.cpp @@ -9,7 +9,7 @@ #include <cmath> #include <QMutexLocker> #include "api/plugin-api.hpp" -#include "hamilton-tools.h" +#include "compat/hamilton-tools.h" hamilton::hamilton() = default; diff --git a/filter-hamilton/ftnoir_filter_hamilton.h b/filter-hamilton/ftnoir_filter_hamilton.h index b724d973..199eef80 100644 --- a/filter-hamilton/ftnoir_filter_hamilton.h +++ b/filter-hamilton/ftnoir_filter_hamilton.h @@ -13,7 +13,7 @@ #include <QMutex> #include "options/options.hpp" //#include "compat/timer.hpp" -#include "hamilton-tools.h" +#include "compat/hamilton-tools.h" using namespace options; diff --git a/filter-hamilton/hamilton-tools.h b/filter-hamilton/hamilton-tools.h deleted file mode 100644 index 2e288225..00000000 --- a/filter-hamilton/hamilton-tools.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "compat/math.hpp" -constexpr double TO_RAD = (M_PI / 180); -constexpr double TO_DEG = (180 / M_PI); -constexpr double EPSILON = 1e-30; - -struct tVector -{ - double v[3]; - tVector(double X = 0, double Y = 0, double Z = 0) {v[0]=X; v[1]=Y; v[2]=Z;} - tVector(double V[]) {v[0]=V[0]; v[1]=V[1]; v[2]=V[2];} -}; - -struct tQuat -{ - double x, y, z, w; - tQuat(double X = 0, double Y = 0, double Z = 0, double W = 1) - {x = X; y = Y; z = Z; w = W;} -}; - -double VectorDistance(const double v1[], const tVector v2); -tVector Lerp (const tVector s, const double d[], const double alpha); -tQuat QuatFromYPR (const double YPR[]); -double AngleBetween (const tQuat S, const tQuat D); -tQuat Slerp (const tQuat S, const tQuat D, const double alpha); -void QuatToYPR (const tQuat Q, double YPR[]); diff --git a/filter-nm/CMakeLists.txt b/filter-nm/CMakeLists.txt new file mode 100644 index 00000000..49daaee2 --- /dev/null +++ b/filter-nm/CMakeLists.txt @@ -0,0 +1 @@ +otr_module(filter-nm) diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp new file mode 100644 index 00000000..b222184b --- /dev/null +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -0,0 +1,67 @@ +/* Copyright (c) 2023 Tom Brazier <tom_github@firstsolo.net> + * + * 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_nm.h" +#include "compat/math-imports.hpp" +#include "compat/macros.h" + +#include "api/plugin-api.hpp" +#include "opentrack/defs.hpp" + +#include <algorithm> + +filter_nm::filter_nm() +{ +} + +void filter_nm::filter(const double* input, double* output) +{ + tVector position = { input[TX], input[TY], input[TZ] }; + tQuat rotation = QuatFromYPR(input + Yaw); + + // order of axes: x, y, z, yaw, pitch, roll + if (unlikely(first_run)) + { + first_run = false; + t.start(); + + last_pos_speed = tVector(); + last_rot_speed = tQuat(); + last_pos_out = position; + last_rot_out = rotation; + } + else + { + const double dt = t.elapsed_seconds(); + t.start(); + + const tVector pos_speed = (position - last_pos_in) / dt; + const double pos_tau = 1. / *s.pos_responsiveness; + double alpha = dt / (dt + pos_tau); + last_pos_speed += (pos_speed - last_pos_speed) * alpha; + const double factor_pos = min(1.0, VectorLength(last_pos_speed) / (*s.pos_drift_speed * 3.0)); + alpha *= factor_pos * factor_pos; + last_pos_out += (position - last_pos_out) * alpha; + + const tQuat rot_delta = QuatDivide(rotation, last_rot_in); + constexpr double ms_per_s = 1000.0; // angular speed quaternions need to be small to work so use °/ms + const tQuat rot_speed = Slerp(tQuat(), rot_delta, 1.0 / ms_per_s / dt ); + const double rot_tau = 1. / *s.rot_responsiveness; + alpha = dt / (dt + rot_tau); + last_rot_speed = Slerp(last_rot_speed, rot_speed, alpha); + const double angular_speed = AngleBetween(tQuat(), last_rot_speed) * ms_per_s; + const double factor_rot = min(1.0, angular_speed / (*s.rot_drift_speed * 3.0)); + alpha *= factor_rot * factor_rot; + last_rot_out = Slerp(last_rot_out, rotation, alpha); + } + + last_pos_in = position; + last_rot_in = rotation; + std::copy(last_pos_out.v, last_pos_out.v + 3, output + TX); + QuatToYPR(last_rot_out, &output[Yaw]); +} + +OPENTRACK_DECLARE_FILTER(filter_nm, dialog_nm, nmDll) diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h new file mode 100644 index 00000000..84775207 --- /dev/null +++ b/filter-nm/ftnoir_filter_nm.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2023 Tom Brazier <tom_github@firstsolo.net> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ +#pragma once + +#include "ui_ftnoir_nm_filtercontrols.h" + +#include "api/plugin-api.hpp" +#include "compat/timer.hpp" +#include "compat/hamilton-tools.h" +#include "options/options.hpp" + +using namespace options; + +struct settings_nm : opts +{ + value<slider_value> pos_responsiveness; + value<slider_value> rot_responsiveness; + value<slider_value> pos_drift_speed; + value<slider_value> rot_drift_speed; + + settings_nm() : + opts("nm-filter"), + pos_responsiveness(value<slider_value>(b, "pos-responsiveness", { 13.0, .0, 20.0 })), + rot_responsiveness(value<slider_value>(b, "rot-responsiveness", { 16.0, .0, 20.0 })), + pos_drift_speed(value<slider_value>(b, "pos-drift-speed", { 5.0, 0.1, 50.0 })), + rot_drift_speed(value<slider_value>(b, "rot-drift-speed", { 7.0, 0.1, 50.0 })) + { + } +}; + +struct filter_nm : IFilter +{ + filter_nm(); + void filter(const double* input, double* output) override; + void center() override { first_run = true; } + module_status initialize() override { return status_ok(); } + +private: + tVector last_pos_in; + tQuat last_rot_in; + tVector last_pos_out; + tQuat last_rot_out; + tVector last_pos_speed; + tQuat last_rot_speed; + Timer t; + settings_nm s; + bool first_run = true; +}; + +class dialog_nm : public IFilterDialog +{ + Q_OBJECT +public: + dialog_nm(); + void register_filter(IFilter*) override {} + void unregister_filter() override {} + void save() override; + void reload() override; + bool embeddable() noexcept override { return true; } + void set_buttons_visible(bool x) override; + +private: + Ui::UICdialog_nm ui; + settings_nm s; + +private slots: + void doOK(); + void doCancel(); +}; + +class nmDll : public Metadata +{ + Q_OBJECT + + QString name() override { return tr("NaturalMovement"); } + QIcon icon() override { return QIcon(":/images/filter-16.png"); } +}; diff --git a/filter-nm/ftnoir_filter_nm_dialog.cpp b/filter-nm/ftnoir_filter_nm_dialog.cpp new file mode 100644 index 00000000..f3626cae --- /dev/null +++ b/filter-nm/ftnoir_filter_nm_dialog.cpp @@ -0,0 +1,56 @@ +/* Copyright (c) 2023 Tom Brazier <tom_github@firstsolo.net> + * + * 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_nm.h" + +using namespace options; + +dialog_nm::dialog_nm() +{ + ui.setupUi(this); + + tie_setting(s.pos_responsiveness, ui.pos_responsiveness_slider); + tie_setting(s.pos_responsiveness, ui.pos_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.rot_responsiveness, ui.rot_responsiveness_slider); + tie_setting(s.rot_responsiveness, ui.rot_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.pos_drift_speed, ui.pos_drift_speed_slider); + tie_setting(s.pos_drift_speed, ui.pos_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.rot_drift_speed, ui.rot_drift_speed_slider); + tie_setting(s.rot_drift_speed, ui.rot_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); +} + +void dialog_nm::doOK() +{ + save(); + close(); +} + +void dialog_nm::doCancel() +{ + close(); +} + +void dialog_nm::save() +{ + s.b->save(); +} + +void dialog_nm::reload() +{ + s.b->reload(); +} + +void dialog_nm::set_buttons_visible(bool x) +{ + ui.buttonBox->setVisible(x); +} diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui new file mode 100644 index 00000000..7e317e74 --- /dev/null +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -0,0 +1,312 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICdialog_nm</class> + <widget class="QDialog" name="UICdialog_nm"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>438</width> + <height>559</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Responsiveness</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Rotation</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="pos_responsiveness"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>10.0</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="rot_responsiveness"> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>10.0</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSlider" name="rot_responsiveness_slider"> + <property name="maximum"> + <number>40</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QSlider" name="pos_responsiveness_slider"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximum"> + <number>40</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Position</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still.</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Drift speeds</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="2"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>mm/s</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Position</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="pos_drift_speed"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>50</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="3"> + <widget class="QSlider" name="rot_drift_speed_slider"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>500</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Rotation</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="rot_drift_speed"> + <property name="minimumSize"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>100</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>°/s</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QSlider" name="pos_drift_speed_slider"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>500</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="6" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still.</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="5" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <tabstops> + <tabstop>pos_responsiveness_slider</tabstop> + <tabstop>rot_responsiveness_slider</tabstop> + <tabstop>pos_drift_speed_slider</tabstop> + <tabstop>rot_drift_speed_slider</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>UICdialog_nm</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>UICdialog_nm</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/filter-nm/lang/nl_NL.ts b/filter-nm/lang/nl_NL.ts new file mode 100644 index 00000000..540e2d51 --- /dev/null +++ b/filter-nm/lang/nl_NL.ts @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="nl_NL"> +<context> + <name>UICdialog_nm</name> + <message> + <source>Dialog</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>°/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>mm/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Responsiveness</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>10.0</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Drift speeds</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>50</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>100</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Rotation</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Position</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>nmDll</name> + <message> + <source>NaturalMovement</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/filter-nm/lang/ru_RU.ts b/filter-nm/lang/ru_RU.ts new file mode 100644 index 00000000..31e5d5cc --- /dev/null +++ b/filter-nm/lang/ru_RU.ts @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="ru_RU"> +<context> + <name>UICdialog_nm</name> + <message> + <source>Dialog</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>°/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>mm/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Responsiveness</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>10.0</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Drift speeds</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>50</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>100</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Rotation</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Position</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>nmDll</name> + <message> + <source>NaturalMovement</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/filter-nm/lang/stub.ts b/filter-nm/lang/stub.ts new file mode 100644 index 00000000..3b960804 --- /dev/null +++ b/filter-nm/lang/stub.ts @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="stub"> +<context> + <name>UICdialog_nm</name> + <message> + <source>Dialog</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>°/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>mm/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Responsiveness</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>10.0</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Drift speeds</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>50</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>100</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Rotation</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Position</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>nmDll</name> + <message> + <source>NaturalMovement</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/filter-nm/lang/zh_CN.ts b/filter-nm/lang/zh_CN.ts new file mode 100644 index 00000000..92521e0f --- /dev/null +++ b/filter-nm/lang/zh_CN.ts @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="zh_CN"> +<context> + <name>UICdialog_nm</name> + <message> + <source>Dialog</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>°/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>mm/s</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Responsiveness</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>10.0</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Drift speeds</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>50</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>100</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Rotation</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Position</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>nmDll</name> + <message> + <source>NaturalMovement</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> |