summaryrefslogtreecommitdiffhomepage
path: root/filter-nm
diff options
context:
space:
mode:
authorTom Brazier <tom_github@firstsolo.net>2023-05-30 16:20:30 +0100
committerTom Brazier <tom_github@firstsolo.net>2023-07-23 14:00:50 +0100
commit3a1f8606c5b415be00ebf21cd57f4fed6832b800 (patch)
tree7f2e4bbb667f1104d61580267be2b8020f476ffe /filter-nm
parent9d9620d2820eb9064fe7b75c509f3209f4ca3b9e (diff)
Picked a name - natural movement filter
Diffstat (limited to 'filter-nm')
-rw-r--r--filter-nm/CMakeLists.txt1
-rw-r--r--filter-nm/ftnoir_filter_nm.cpp48
-rw-r--r--filter-nm/ftnoir_filter_nm.h93
-rw-r--r--filter-nm/ftnoir_filter_nm_dialog.cpp88
-rw-r--r--filter-nm/ftnoir_nm_filtercontrols.ui610
-rw-r--r--filter-nm/lang/nl_NL.ts78
-rw-r--r--filter-nm/lang/ru_RU.ts78
-rw-r--r--filter-nm/lang/stub.ts78
-rw-r--r--filter-nm/lang/zh_CN.ts78
9 files changed, 1152 insertions, 0 deletions
diff --git a/filter-nm/CMakeLists.txt b/filter-nm/CMakeLists.txt
new file mode 100644
index 00000000..d98e90e2
--- /dev/null
+++ b/filter-nm/CMakeLists.txt
@@ -0,0 +1 @@
+otr_module(filter-tom)
diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp
new file mode 100644
index 00000000..6bcfeae0
--- /dev/null
+++ b/filter-nm/ftnoir_filter_nm.cpp
@@ -0,0 +1,48 @@
+/* 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 "filter_tom.h"
+#include "compat/math-imports.hpp"
+#include "compat/macros.h"
+
+#include "api/plugin-api.hpp"
+#include "opentrack/defs.hpp"
+
+#include <algorithm>
+
+tom::tom()
+{
+}
+
+void tom::filter(const double* input, double* output)
+{
+ // order of axes: x, y, z, yaw, pitch, roll
+ if (unlikely(first_run))
+ {
+ first_run = false;
+ t.start();
+
+ std::fill(speeds, speeds + 6, 0.0);
+ std::copy(input, input + 6, filtered_output);
+ }
+ else
+ {
+ const double dt = t.elapsed_seconds();
+ t.start();
+
+ for (int i = 0; i < 6; i++)
+ {
+ double speed = (input[i] - last_input[i]) / dt;
+ speeds[i] += dt * (double)s.responsiveness[i] * (speed - speeds[i]);
+ filtered_output[i] += dt * (double)s.responsiveness[i] * min(1.0, abs(speeds[i]) / (double)s.drift_speeds[i]) * (input[i] - filtered_output[i]);
+ }
+ }
+
+ std::copy(input, input + 6, last_input);
+ std::copy(filtered_output, filtered_output + 6, output);
+}
+
+OPENTRACK_DECLARE_FILTER(tom, dialog_tom, tomDll)
diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h
new file mode 100644
index 00000000..0f6d07c2
--- /dev/null
+++ b/filter-nm/ftnoir_filter_nm.h
@@ -0,0 +1,93 @@
+/* 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_tom_filtercontrols.h"
+
+#include "api/plugin-api.hpp"
+#include "compat/timer.hpp"
+#include "options/options.hpp"
+
+using namespace options;
+
+struct settings_tom : opts
+{
+ value<slider_value> responsiveness[6];
+ value<slider_value> drift_speeds[6];
+
+ settings_tom() :
+ opts("tom-filter"),
+ responsiveness{ value<slider_value>(b, "x-responsiveness", { 10.0, .0, 20.0 }),
+ value<slider_value>(b, "y-responsiveness", { 10.0, .0, 20.0 }),
+ value<slider_value>(b, "z-responsiveness", { 10.0, .0, 20.0 }),
+ value<slider_value>(b, "yaw-responsiveness", { 10.0, .0, 20.0 }),
+ value<slider_value>(b, "pitch-responsiveness", { 10.0, .0, 20.0 }),
+ value<slider_value>(b, "roll-responsiveness", { 10.0, .0, 20.0 }) },
+ drift_speeds{ value<slider_value>(b, "x-drift-speed", { 50.0, 1.0, 200.0 }),
+ value<slider_value>(b, "y-drift-speed", { 50.0, 1.0, 200.0 }),
+ value<slider_value>(b, "z-drift-speed", { 50.0, 1.0, 200.0 }),
+ value<slider_value>(b, "yaw-drift-speed", { 100.0, 1.0, 400.0 }),
+ value<slider_value>(b, "pitch-drift-speed", { 100.0, 1.0, 400.0 }),
+ value<slider_value>(b, "roll-drift-speed", { 100.0, 1.0, 400.0 }) }
+ {
+ }
+
+ /* value<slider_value> kMinSmoothing, kMaxSmoothing, kSmoothingScaleCurve;
+ settings()
+ : opts("ewma-filter"),
+ kMinSmoothing(b, "min-smoothing", { .02, .01, 1 }),
+ kMaxSmoothing(b, "max-smoothing", { .7, .01, 1 }),
+ kSmoothingScaleCurve(b, "smoothing-scale-curve", { .8, .1, 5 })
+ {
+ }
+*/
+};
+
+struct tom : IFilter
+{
+ tom();
+ void filter(const double* input, double* output) override;
+ void center() override { first_run = true; }
+ module_status initialize() override { return status_ok(); }
+
+private:
+ double last_input[6]{};
+ double speeds[6]{};
+ double filtered_output[6]{};
+ Timer t;
+ settings_tom s;
+ bool first_run = true;
+};
+
+class dialog_tom : public IFilterDialog
+{
+ Q_OBJECT
+public:
+ dialog_tom();
+ 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_tom ui;
+ settings_tom s;
+
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class tomDll : public Metadata
+{
+ Q_OBJECT
+
+ QString name() override { return tr("Tom"); }
+ 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..5a6ad3a4
--- /dev/null
+++ b/filter-nm/ftnoir_filter_nm_dialog.cpp
@@ -0,0 +1,88 @@
+/* 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 "filter_tom.h"
+
+using namespace options;
+
+dialog_tom::dialog_tom()
+{
+ ui.setupUi(this);
+
+ tie_setting(s.responsiveness[0], ui.x_responsiveness_slider);
+ tie_setting(s.responsiveness[0], ui.x_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.responsiveness[1], ui.y_responsiveness_slider);
+ tie_setting(s.responsiveness[1], ui.y_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.responsiveness[2], ui.z_responsiveness_slider);
+ tie_setting(s.responsiveness[2], ui.z_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.responsiveness[3], ui.yaw_responsiveness_slider);
+ tie_setting(s.responsiveness[3], ui.yaw_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.responsiveness[4], ui.pitch_responsiveness_slider);
+ tie_setting(s.responsiveness[4], ui.pitch_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.responsiveness[5], ui.roll_responsiveness_slider);
+ tie_setting(s.responsiveness[5], ui.roll_responsiveness, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[0], ui.x_drift_speed_slider);
+ tie_setting(s.drift_speeds[0], ui.x_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[1], ui.y_drift_speed_slider);
+ tie_setting(s.drift_speeds[1], ui.y_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[2], ui.z_drift_speed_slider);
+ tie_setting(s.drift_speeds[2], ui.z_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[3], ui.yaw_drift_speed_slider);
+ tie_setting(s.drift_speeds[3], ui.yaw_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[4], ui.pitch_drift_speed_slider);
+ tie_setting(s.drift_speeds[4], ui.pitch_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+
+ tie_setting(s.drift_speeds[5], ui.roll_drift_speed_slider);
+ tie_setting(s.drift_speeds[5], ui.roll_drift_speed, [](double x)
+ { return QStringLiteral("%1").arg(x, 0, 'f', 2); });
+}
+
+void dialog_tom::doOK()
+{
+ save();
+ close();
+}
+
+void dialog_tom::doCancel()
+{
+ close();
+}
+
+void dialog_tom::save()
+{
+ s.b->save();
+}
+
+void dialog_tom::reload()
+{
+ s.b->reload();
+}
+
+void dialog_tom::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..1a135c1e
--- /dev/null
+++ b/filter-nm/ftnoir_nm_filtercontrols.ui
@@ -0,0 +1,610 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICdialog_tom</class>
+ <widget class="QDialog" name="UICdialog_tom">
+ <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="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>X</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="x_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="0" column="2">
+ <widget class="QSlider" name="x_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="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="y_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="y_responsiveness_slider">
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="z_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="2" column="2">
+ <widget class="QSlider" name="z_responsiveness_slider">
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="yaw_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="3" column="2">
+ <widget class="QSlider" name="yaw_responsiveness_slider">
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="pitch_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="4" column="2">
+ <widget class="QSlider" name="pitch_responsiveness_slider">
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="roll_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="5" column="2">
+ <widget class="QSlider" name="roll_responsiveness_slider">
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </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="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QSlider" name="y_drift_speed_slider">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="y_drift_speed">
+ <property name="minimumSize">
+ <size>
+ <width>30</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="6" column="2">
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>°/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLabel" name="label_23">
+ <property name="text">
+ <string>mm/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="2">
+ <widget class="QLabel" name="label_25">
+ <property name="text">
+ <string>°/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <widget class="QSlider" name="z_drift_speed_slider">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="z_drift_speed">
+ <property name="minimumSize">
+ <size>
+ <width>30</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="11" column="1">
+ <widget class="QLabel" name="roll_drift_speed">
+ <property name="minimumSize">
+ <size>
+ <width>30</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="2" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QLabel" name="pitch_drift_speed">
+ <property name="minimumSize">
+ <size>
+ <width>30</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="9" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="3">
+ <widget class="QSlider" name="pitch_drift_speed_slider">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>X</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="yaw_drift_speed">
+ <property name="minimumSize">
+ <size>
+ <width>30</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="0" column="2">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>mm/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>mm/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QSlider" name="x_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>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="2">
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>°/s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="3">
+ <widget class="QSlider" name="yaw_drift_speed_slider">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="3">
+ <widget class="QSlider" name="roll_drift_speed_slider">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="x_drift_speed">
+ <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>50</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </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 on an axis by axis basis: 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>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>UICdialog_tom</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_tom</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..ce0aefe3
--- /dev/null
+++ b/filter-nm/lang/nl_NL.ts
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="nl_NL">
+<context>
+ <name>UICdialog_tom</name>
+ <message>
+ <source>Dialog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Yaw</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Roll</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: 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>Instructions: Set all sliders to minimum. Then on an axis by axis basis: 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>tomDll</name>
+ <message>
+ <source>Tom</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..b72d73ad
--- /dev/null
+++ b/filter-nm/lang/ru_RU.ts
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru_RU">
+<context>
+ <name>UICdialog_tom</name>
+ <message>
+ <source>Dialog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Yaw</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Roll</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: 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>Instructions: Set all sliders to minimum. Then on an axis by axis basis: 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>tomDll</name>
+ <message>
+ <source>Tom</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..f212040f
--- /dev/null
+++ b/filter-nm/lang/stub.ts
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="stub">
+<context>
+ <name>UICdialog_tom</name>
+ <message>
+ <source>Dialog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Yaw</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Roll</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: 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>Instructions: Set all sliders to minimum. Then on an axis by axis basis: 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>tomDll</name>
+ <message>
+ <source>Tom</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..5a322913
--- /dev/null
+++ b/filter-nm/lang/zh_CN.ts
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN">
+<context>
+ <name>UICdialog_tom</name>
+ <message>
+ <source>Dialog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Y</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Yaw</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Pitch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Roll</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: 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>Instructions: Set all sliders to minimum. Then on an axis by axis basis: 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>tomDll</name>
+ <message>
+ <source>Tom</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>