summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy1
-rw-r--r--.github/workflows/cmake.yml15
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md4
-rw-r--r--cmake/msvc.cmake6
-rw-r--r--cmake/opentrack-pkg-config.cmake14
-rw-r--r--compat/process-list.hpp41
-rw-r--r--filter-hamilton/ftnoir_filter_hamilton.cpp29
-rw-r--r--filter-hamilton/ftnoir_filter_hamilton.h2
-rw-r--r--filter-hamilton/ftnoir_hamilton_filtercontrols.ui1509
-rw-r--r--filter-hamilton/lang/nl_NL.ts26
-rw-r--r--filter-hamilton/lang/ru_RU.ts26
-rw-r--r--filter-hamilton/lang/stub.ts26
-rw-r--r--filter-hamilton/lang/zh_CN.ts26
-rw-r--r--gui/CMakeLists.txt7
-rw-r--r--gui/init.cpp78
-rw-r--r--proto-osc/CMakeLists.txt15
-rw-r--r--proto-osc/dialog.cpp38
-rw-r--r--proto-osc/dialog.hpp29
-rw-r--r--proto-osc/dialog.ui131
-rw-r--r--proto-osc/images/osc-icon.pngbin0 -> 868 bytes
-rw-r--r--proto-osc/lang/nl_NL.ts45
-rw-r--r--proto-osc/lang/ru_RU.ts45
-rw-r--r--proto-osc/lang/stub.ts45
-rw-r--r--proto-osc/lang/zh_CN.ts45
-rw-r--r--proto-osc/metadata.cpp8
-rw-r--r--proto-osc/metadata.hpp10
-rw-r--r--proto-osc/osc-res.qrc5
-rw-r--r--proto-osc/proto.cpp54
-rw-r--r--proto-osc/proto.hpp29
-rw-r--r--proto-osc/settings.hpp14
-rw-r--r--proto-simconnect/ftnoir_protocol_sc.cpp32
-rw-r--r--proto-simconnect/ftnoir_protocol_sc.h2
-rw-r--r--sdk-paths-sthalik@MSVC-windows.cmake9
-rw-r--r--tracker-aruco/aruco-trackercontrols.ui5
-rw-r--r--tracker-aruco/ftnoir_tracker_aruco.cpp1
-rw-r--r--tracker-aruco/lang/nl_NL.ts4
-rw-r--r--tracker-aruco/lang/ru_RU.ts4
-rw-r--r--tracker-aruco/lang/stub.ts4
-rw-r--r--tracker-aruco/lang/zh_CN.ts4
-rw-r--r--tracker-eyeware-beam/CMakeLists.txt10
-rw-r--r--tracker-neuralnet/CMakeLists.txt9
-rw-r--r--tracker-neuralnet/model_adapters.cpp41
-rw-r--r--tracker-neuralnet/model_adapters.h13
-rw-r--r--tracker-pt/FTNoIR_PT_Controls.ui441
-rw-r--r--tracker-pt/ftnoir_tracker_pt_dialog.cpp24
-rw-r--r--tracker-pt/ftnoir_tracker_pt_dialog.h2
-rw-r--r--tracker-pt/lang/nl_NL.ts8
-rw-r--r--tracker-pt/lang/ru_RU.ts8
-rw-r--r--tracker-pt/lang/stub.ts8
-rw-r--r--tracker-pt/lang/zh_CN.ts8
-rw-r--r--tracker-pt/module/point_extractor.cpp38
-rw-r--r--tracker-pt/module/point_extractor.h2
-rw-r--r--tracker-pt/pt-settings.hpp2
54 files changed, 1838 insertions, 1166 deletions
diff --git a/.clang-tidy b/.clang-tidy
index a29d0ffd..8898ca05 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -39,7 +39,6 @@ clang-analyzer-deadcode.DeadStores,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-special-member-functions,
--hicpp-special-member-functions,
-google-readability-braces-around-statements,
-google-readability-casting,
-hicpp-avoid-c-arrays,
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
index c24e9c99..92bda418 100644
--- a/.github/workflows/cmake.yml
+++ b/.github/workflows/cmake.yml
@@ -36,20 +36,17 @@ jobs:
- uses: seanmiddleditch/gha-setup-ninja@master
- name: Install Linux Dependencies
- run: sudo apt update && sudo apt install libprocps-dev libopencv-dev libopencv-dev wine64-tools
+ run: |
+ sudo apt-get update
+ sudo apt-get install libprocps-dev libopencv-dev libopencv-dev wine64-tools
+ sudo apt-get install qttools5-dev qtbase5-dev libqt5serialport5-dev qtbase5-private-dev
if: matrix.os == 'ubuntu-latest'
- - name: Cache Qt
- id: cache-qt
- uses: actions/cache@v3
- with:
- path: ../Qt
- key: ${{ runner.os }}-QtCache
-
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
- cached: ${{ steps.cache-qt.outputs.cache-hit }}
+ archives: qtbase qtimageformats qtgamepad qttools qtserialport qtmultimedia
+ if: matrix.os != 'ubuntu-latest'
- name: Configure
run: ${{matrix.cmake}} -GNinja -S ${{github.workspace}}/ -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DQt5_DIR=${{env.Qt5_DIR}} -DQt5Gui_DIR=${{env.Qt5_DIR}}/lib/cmake/Qt5Gui
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bb1cfff2..4e2ddd1d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -109,6 +109,8 @@ otr_merge_translations()
include(opentrack-install)
+message("Install directory:")
+message(" ${CMAKE_INSTALL_PREFIX}")
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
message("Compile flags:")
#foreach(j C CXX)
diff --git a/README.md b/README.md
index 1e485459..0ed51166 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
## Intro
-[<img src="https://ci.appveyor.com/api/projects/status/n0j9h38jnif5qbe9/branch/unstable?svg=true"/>](https://ci.appveyor.com/project/sthalik/opentrack/branch/unstable)
+[<img src="https://github.com/opentrack/opentrack/actions/workflows/cmake.yml/badge.svg">](https://github.com/opentrack/opentrack/actions/workflows/cmake.yml)
opentrack project home is located at <<http://github.com/opentrack/opentrack>>.
@@ -40,6 +40,7 @@ Don't be afraid to submit an **issue/feature request** if you have any problems!
- BBC micro:bit, LEGO, sensortag support via Smalltalk<sup>[(1)](https://en.wikipedia.org/wiki/Smalltalk)[(2)](https://en.wikipedia.org/wiki/Alan_Kay)</sup>
[S2Bot](http://www.picaxe.com/Teaching/Other-Software/Scratch-Helper-Apps/)
- Wiimote (Windows)
+- Eyeware Beam<sup>[[1](https://beam.eyeware.tech/)]</sup>
## Output protocols
@@ -69,6 +70,7 @@ Don't be afraid to submit an **issue/feature request** if you have any problems!
- Wei Shuai (Wiimote tracker)
- Stéphane Lenclud (Kinect Face Tracker, Easy Tracker)
- GO63-samara (Hamilton Filter, Pose-widget improvement)
+- Davide Mameli (Eyeware Beam tracker)
## Thanks
diff --git a/cmake/msvc.cmake b/cmake/msvc.cmake
index e7e3c329..cf3bb0cb 100644
--- a/cmake/msvc.cmake
+++ b/cmake/msvc.cmake
@@ -37,7 +37,7 @@ add_definitions(-D_HAS_EXCEPTIONS=0)
if(DEFINED CMAKE_TOOLCHAIN_FILE)
# ignore cmake warning: Manually-specified variable not used by the project
- set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}}")
+ set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/opentrack-policy.cmake" NO_POLICY_SCOPE)
@@ -106,6 +106,10 @@ if(CMAKE_PROJECT_NAME STREQUAL "OpenCV")
set(BUILD_opencv_gapi OFF)
endif()
+if(CMAKE_PROJECT_NAME STREQUAL "TestOscpack")
+ add_compile_definitions(OSC_HOST_LITTLE_ENDIAN)
+endif()
+
set(opentrack-simd "SSE2")
if(CMAKE_PROJECT_NAME STREQUAL "onnxruntime")
diff --git a/cmake/opentrack-pkg-config.cmake b/cmake/opentrack-pkg-config.cmake
index 5b84cf40..0f13defc 100644
--- a/cmake/opentrack-pkg-config.cmake
+++ b/cmake/opentrack-pkg-config.cmake
@@ -1,7 +1,8 @@
include_guard(GLOBAL)
include(FindPkgConfig)
-function(otr_pkgconfig target)
+function(otr_pkgconfig_ ret target)
+ set(${ret} 1 PARENT_SCOPE)
foreach(i ${ARGN})
set(k pkg-config_${i})
pkg_check_modules(${k} QUIET ${i})
@@ -11,6 +12,17 @@ function(otr_pkgconfig target)
target_include_directories(${target} SYSTEM PRIVATE ${${k}_INCLUDE_DIRS} ${${k}_INCLUDEDIR})
target_link_libraries(${target} ${${k}_LIBRARIES})
else()
+ set(${ret} 0 PARENT_SCOPE)
+ endif()
+ endforeach()
+endfunction()
+
+function(otr_pkgconfig target)
+ set(ret "")
+ otr_pkgconfig_(ret "${target}" ${ARGN})
+ foreach(i ${ARGN})
+ set(k pkg-config_${i})
+ if(NOT ${${k}_FOUND})
message(FATAL_ERROR "Can't find '${i}'. Please install development files for this package.")
endif()
endforeach()
diff --git a/compat/process-list.hpp b/compat/process-list.hpp
index 782dc0a4..6d960610 100644
--- a/compat/process-list.hpp
+++ b/compat/process-list.hpp
@@ -131,6 +131,46 @@ static QStringList get_all_executable_names()
#elif defined __linux__
+#include <cerrno>
+
+#ifdef OTR_HAS_LIBPROC2
+#include <libproc2/pids.h>
+template<typename = void>
+QStringList get_all_executable_names()
+{
+ QStringList ret;
+ enum pids_item items[] = { PIDS_ID_PID, PIDS_CMD, PIDS_CMDLINE_V };
+
+ enum rel_items { rel_pid, rel_cmd, rel_cmdline };
+ struct pids_info *info = NULL;
+ struct pids_stack *stack;
+ QString tmp; tmp.reserve(64);
+
+ procps_pids_new(&info, items, 3);
+
+ while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY)))
+ {
+ char **p_cmdline = PIDS_VAL(rel_cmdline, strv, stack, info);
+
+ // note, wine sets argv[0] so no parsing like in OSX case
+ if (p_cmdline && p_cmdline[0] && p_cmdline[0][0] &&
+ !(p_cmdline[0][0] == '-' && !p_cmdline[0][1]))
+ {
+ tmp = QString{p_cmdline[0]};
+ const int idx = std::max(tmp.lastIndexOf('\\'), tmp.lastIndexOf('/'));
+ if (idx != -1)
+ tmp = tmp.mid(idx+1);
+ //qDebug() << "procps" << tmp;
+ ret.append(tmp);
+ }
+ }
+ //qDebug() << "-- procps end";
+
+ procps_pids_unref(&info);
+
+ return ret;
+}
+#else
#include <proc/readproc.h>
#include <cerrno>
@@ -160,6 +200,7 @@ QStringList get_all_executable_names()
free(procs);
return ret;
}
+#endif
#else
template<typename = void>
diff --git a/filter-hamilton/ftnoir_filter_hamilton.cpp b/filter-hamilton/ftnoir_filter_hamilton.cpp
index be3faa7f..7bbc91de 100644
--- a/filter-hamilton/ftnoir_filter_hamilton.cpp
+++ b/filter-hamilton/ftnoir_filter_hamilton.cpp
@@ -34,11 +34,15 @@ void hamilton::filter(const double *input, double *output)
double dist = VectorDistance( &input[TX], pos_last);
double alpha = (dist - pos_deadzone) / (pos_max + pos_deadzone + EPSILON);
- alpha = fmin(alpha, 1.0);
- alpha = fmax(alpha, 0.0);
- alpha = pow (alpha, pos_pow);
- alpha = alpha * (dist - pos_deadzone) / (dist + EPSILON);
-
+ alpha = std::min(1.0, std::max(0.0, alpha));
+ if (alpha > 0.0)
+ alpha = pow(alpha, pos_pow);
+ // Scale alpha so that alpha * dist <= dist - pos_deadzone. This ensures that
+ // the center of the deadzone will never move closer to the input position than
+ // distance dist. And this ensures that the view never jumps ahead of head
+ // movements.
+ alpha *= (dist - pos_deadzone) / (dist + EPSILON);
+
pos_last = Lerp(pos_last, input, alpha);
output[TX] = pos_last.v[0];
@@ -48,11 +52,11 @@ void hamilton::filter(const double *input, double *output)
// zoom smoothing:
const double pow_zoom {s.kPowZoom};
const double max_z {s.kMaxZ};
- double rot_zoom = pow_zoom;
+ double rot_zoom = pow_zoom;
if (output[TZ] > 0) rot_zoom = 0;
- else rot_zoom *= -output[TZ] / (max_z + EPSILON);
- rot_zoom = fmin( rot_zoom, pow_zoom );
+ else rot_zoom *= -output[TZ] / (max_z + EPSILON);
+ rot_zoom = fmin( rot_zoom, pow_zoom );
// rotations:
const double rot_max {s.kMaxRot};
@@ -62,10 +66,11 @@ void hamilton::filter(const double *input, double *output)
double angle = AngleBetween(quat_input, quat_last);
alpha = (angle - rot_deadzone) / (rot_max + rot_deadzone + EPSILON);
- alpha = fmin(alpha, 1.0);
- alpha = fmax(alpha, 0.0);
- alpha = pow (alpha, rot_pow + rot_zoom);
- alpha = alpha * (angle - rot_deadzone) / (angle + EPSILON);
+ alpha = std::min(1.0, std::max(0.0, alpha));
+ if (alpha > 0.0)
+ alpha = pow(alpha, rot_pow + rot_zoom);
+ // see comment in earlier alpha calculation above
+ alpha *= (angle - rot_deadzone) / (angle + EPSILON);
quat_last = Slerp(quat_last, quat_input, alpha);
diff --git a/filter-hamilton/ftnoir_filter_hamilton.h b/filter-hamilton/ftnoir_filter_hamilton.h
index 0756c216..b724d973 100644
--- a/filter-hamilton/ftnoir_filter_hamilton.h
+++ b/filter-hamilton/ftnoir_filter_hamilton.h
@@ -43,7 +43,7 @@ public:
module_status initialize() override { return status_ok(); }
private:
tQuat quat_last;
- tVector pos_last;
+ tVector pos_last;
settings s;
bool first_run = true;
};
diff --git a/filter-hamilton/ftnoir_hamilton_filtercontrols.ui b/filter-hamilton/ftnoir_hamilton_filtercontrols.ui
index 71cdb6da..4c8b1536 100644
--- a/filter-hamilton/ftnoir_hamilton_filtercontrols.ui
+++ b/filter-hamilton/ftnoir_hamilton_filtercontrols.ui
@@ -13,7 +13,7 @@
<x>0</x>
<y>0</y>
<width>514</width>
- <height>491</height>
+ <height>563</height>
</rect>
</property>
<property name="sizePolicy">
@@ -50,8 +50,8 @@
<property name="styleSheet">
<string notr="true"/>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -65,322 +65,286 @@
<height>150</height>
</size>
</property>
- <property name="font">
- <font>
- <pointsize>8</pointsize>
- <weight>50</weight>
- <bold>false</bold>
- </font>
- </property>
<property name="title">
<string>Rotations: </string>
</property>
<property name="flat">
<bool>false</bool>
</property>
- <widget class="QSlider" name="maxRot">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>30</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>250</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>50</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbRmax">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>30</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Max distance:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbMaxRot">
- <property name="geometry">
- <rect>
- <x>424</x>
- <y>30</y>
- <width>61</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>10,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbRdz">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>110</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Dead Zone:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="dzRot">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>110</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>50</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>5</number>
- </property>
- <property name="value">
- <number>1</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>10</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbDZRot">
- <property name="geometry">
- <rect>
- <x>424</x>
- <y>110</y>
- <width>61</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>0,01</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="powRot">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>70</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>400</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>200</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>100</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbPowRot">
- <property name="geometry">
- <rect>
- <x>430</x>
- <y>70</y>
- <width>45</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>2,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbRpow">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>70</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Smoothing:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="8" column="2">
+ <widget class="QSlider" name="powRot">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="3">
+ <widget class="QLabel" name="lbPowRot">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>2,00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QSlider" name="dzRot">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>50</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>5</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="lbRpow">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Smoothing power:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="lbRdz">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Dead Zone:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="3">
+ <widget class="QLabel" name="lbDZRot">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>0,01</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="lbRmax">
+ <property name="text">
+ <string>Max distance:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2">
+ <widget class="QSlider" name="maxRot">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>250</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3">
+ <widget class="QLabel" name="lbMaxRot">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>10,00</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="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>true</bool>
+ </property>
</widget>
</item>
- <item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>For both rotations and positions: No movement occurs within the dead zone. Smoothing scales down to minimum at max distance + 2 x dead zone.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -397,300 +361,248 @@
<property name="title">
<string>Positions: </string>
</property>
- <widget class="QSlider" name="maxDist">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>30</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>200</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>50</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbRpow_3">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>70</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Smoothing:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="powDist">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>70</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>400</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>100</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbRdz_3">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>110</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Dead Zone:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbPowDist">
- <property name="geometry">
- <rect>
- <x>430</x>
- <y>70</y>
- <width>51</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>40</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>1,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbDmax">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>30</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Max distance:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="dzDist">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>110</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>50</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>10</number>
- </property>
- <property name="value">
- <number>2</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>10</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbMaxDist">
- <property name="geometry">
- <rect>
- <x>420</x>
- <y>30</y>
- <width>71</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>10,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbDZDist">
- <property name="geometry">
- <rect>
- <x>420</x>
- <y>110</y>
- <width>71</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>0,02</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="2">
+ <widget class="QLabel" name="lbMaxDist">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>10,00</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="lbRpow_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Smoothing power:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lbDmax">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Max distance:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSlider" name="maxDist">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>200</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSlider" name="powDist">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="lbPowDist">
+ <property name="minimumSize">
+ <size>
+ <width>40</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>1,00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="lbRdz_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Dead Zone:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSlider" name="dzDist">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>50</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="lbDZDist">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0,02</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item>
+ <item row="5" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
@@ -707,227 +619,194 @@
<property name="title">
<string>Zoom smoothing: </string>
</property>
- <widget class="QLabel" name="lbPowZoom">
- <property name="geometry">
- <rect>
- <x>434</x>
- <y>30</y>
- <width>45</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>2,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="powZoom">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>30</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>400</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>200</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>100</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbZpow">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>30</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string> Smoothing :</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QSlider" name="maxZ">
- <property name="geometry">
- <rect>
- <x>103</x>
- <y>60</y>
- <width>311</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>1000</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="pageStep">
- <number>50</number>
- </property>
- <property name="value">
- <number>150</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBothSides</enum>
- </property>
- <property name="tickInterval">
- <number>100</number>
- </property>
- </widget>
- <widget class="QLabel" name="lbZpow_2">
- <property name="geometry">
- <rect>
- <x>7</x>
- <y>60</y>
- <width>91</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Max Z:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="lbMaxZ">
- <property name="geometry">
- <rect>
- <x>434</x>
- <y>60</y>
- <width>45</width>
- <height>20</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>45</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>15,00</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="2" column="0">
+ <widget class="QLabel" name="lbZpow">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Smoothing power:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="lbPowZoom">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>2,00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSlider" name="powZoom">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>400</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>200</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lbZpow_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Max Z:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSlider" name="maxZ">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="pageStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>150</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="lbMaxZ">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>15,00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>When you lean forward, zoom smoothing increases the smoothing power for rotations. Maximum additonal smoothing power occurs when you lean forward by a distance of Max Z.</string>
</property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- <property name="centerButtons">
+ <property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>dzRot</tabstop>
+ <tabstop>maxRot</tabstop>
+ <tabstop>powRot</tabstop>
+ <tabstop>dzDist</tabstop>
+ <tabstop>maxDist</tabstop>
+ <tabstop>powDist</tabstop>
+ <tabstop>maxZ</tabstop>
+ <tabstop>powZoom</tabstop>
+ </tabstops>
<resources>
<include location="../gui/opentrack-res.qrc"/>
</resources>
diff --git a/filter-hamilton/lang/nl_NL.ts b/filter-hamilton/lang/nl_NL.ts
index b03e4c0b..1c720540 100644
--- a/filter-hamilton/lang/nl_NL.ts
+++ b/filter-hamilton/lang/nl_NL.ts
@@ -8,18 +8,10 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing :</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Positions: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Max distance:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Zoom smoothing: </source>
<translation type="unfinished"></translation>
</message>
@@ -52,15 +44,27 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Dead Zone:</source>
+ <source>15,00</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing:</source>
+ <source>Smoothing power:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>15,00</source>
+ <source>Dead Zone:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Max distance:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>For both rotations and positions: No movement occurs within the dead zone. Smoothing scales down to minimum at max distance + 2 x dead zone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When you lean forward, zoom smoothing increases the smoothing power for rotations. Maximum additonal smoothing power occurs when you lean forward by a distance of Max Z.</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/filter-hamilton/lang/ru_RU.ts b/filter-hamilton/lang/ru_RU.ts
index dfbb2268..f0681b21 100644
--- a/filter-hamilton/lang/ru_RU.ts
+++ b/filter-hamilton/lang/ru_RU.ts
@@ -8,18 +8,10 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing :</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Positions: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Max distance:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Zoom smoothing: </source>
<translation type="unfinished"></translation>
</message>
@@ -52,15 +44,27 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Dead Zone:</source>
+ <source>15,00</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing:</source>
+ <source>Smoothing power:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>15,00</source>
+ <source>Dead Zone:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Max distance:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>For both rotations and positions: No movement occurs within the dead zone. Smoothing scales down to minimum at max distance + 2 x dead zone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When you lean forward, zoom smoothing increases the smoothing power for rotations. Maximum additonal smoothing power occurs when you lean forward by a distance of Max Z.</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/filter-hamilton/lang/stub.ts b/filter-hamilton/lang/stub.ts
index a8af9f98..2b767312 100644
--- a/filter-hamilton/lang/stub.ts
+++ b/filter-hamilton/lang/stub.ts
@@ -8,18 +8,10 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing :</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Positions: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Max distance:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Zoom smoothing: </source>
<translation type="unfinished"></translation>
</message>
@@ -52,15 +44,27 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Dead Zone:</source>
+ <source>15,00</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing:</source>
+ <source>Smoothing power:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>15,00</source>
+ <source>Dead Zone:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Max distance:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>For both rotations and positions: No movement occurs within the dead zone. Smoothing scales down to minimum at max distance + 2 x dead zone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When you lean forward, zoom smoothing increases the smoothing power for rotations. Maximum additonal smoothing power occurs when you lean forward by a distance of Max Z.</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/filter-hamilton/lang/zh_CN.ts b/filter-hamilton/lang/zh_CN.ts
index 4fc4d812..222569e4 100644
--- a/filter-hamilton/lang/zh_CN.ts
+++ b/filter-hamilton/lang/zh_CN.ts
@@ -8,18 +8,10 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing :</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Positions: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Max distance:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Zoom smoothing: </source>
<translation type="unfinished"></translation>
</message>
@@ -52,15 +44,27 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source> Dead Zone:</source>
+ <source>15,00</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source> Smoothing:</source>
+ <source>Smoothing power:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>15,00</source>
+ <source>Dead Zone:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Max distance:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>For both rotations and positions: No movement occurs within the dead zone. Smoothing scales down to minimum at max distance + 2 x dead zone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>When you lean forward, zoom smoothing increases the smoothing power for rotations. Maximum additonal smoothing power occurs when you lean forward by a distance of Max Z.</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
index db2f0b9e..8c57221a 100644
--- a/gui/CMakeLists.txt
+++ b/gui/CMakeLists.txt
@@ -11,7 +11,12 @@ target_link_libraries(${self}
if(APPLE)
target_link_libraries(${self} proc)
elseif(LINUX)
- otr_pkgconfig(${self} libprocps)
+ otr_pkgconfig_(has-libproc2 ${self} libproc2)
+ if(has-libproc2)
+ target_compile_definitions(${self} PRIVATE -DOTR_HAS_LIBPROC2)
+ else()
+ otr_pkgconfig(${self} libprocps)
+ endif()
endif()
if(NOT APPLE AND NOT WIN32)
diff --git a/gui/init.cpp b/gui/init.cpp
index b54a085e..5984269c 100644
--- a/gui/init.cpp
+++ b/gui/init.cpp
@@ -193,51 +193,56 @@ static void apply_dark_windows_theme_if_needed()
static void add_win32_path()
{
- // see https://software.intel.com/en-us/articles/limitation-to-the-length-of-the-system-path-variable
- static char env_path[4096] { '\0', };
+ // see https://web.archive.org/web/20180924055536/https://software.intel.com/en-us/articles/limitation-to-the-length-of-the-system-path-variable
{
QString lib_path = OPENTRACK_BASE_PATH;
lib_path.replace("/", "\\");
- const QByteArray lib_path_ = QFile::encodeName(lib_path);
-
QString mod_path = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH;
mod_path.replace("/", "\\");
- const QByteArray mod_path_ = QFile::encodeName(mod_path);
-
- const char* contents[] {
- "PATH=",
- lib_path_.constData(),
- ";",
- mod_path_.constData(),
- ";",
- getenv("PATH"),
- };
- bool ok = true;
+ const QString orig_path = qgetenv("PATH");
- for (const char* ptr : contents)
- {
- if (ptr)
- strcat_s(env_path, sizeof(env_path), ptr);
+ QString env_path; env_path.reserve(4096);
- if (!ptr || ptr[0] == '\0' || env_path[0] == '\0')
- {
- qDebug() << "bad path element"
- << (ptr == nullptr ? "<null>" : ptr);
- ok = false;
- break;
- }
- }
+#if 0
+ qDebug() << "orig" << orig_path;
+ qDebug() << "libpath" << lib_path;
+ qDebug() << "modpath" << mod_path;
+#endif
- if (ok)
+ if (lib_path.isEmpty())
+ qDebug() << "env: empty lib_path!";
+ else
{
- const int error = _putenv(env_path);
-
- if (error)
- qDebug() << "can't _putenv win32 path";
+ if (!QFile(lib_path).exists())
+ qDebug() << "env: lib_path doesn't exist, this shouldn't happen!";
+ env_path += lib_path;
+ env_path += ';';
}
+ if (mod_path.isEmpty())
+ qDebug() << "env: can't add mod_path to env PATH";
else
- qDebug() << "can't set win32 path";
+ {
+ if (!QFile(mod_path).exists())
+ qDebug() << "env: mod_path doesn't exist, did you install it correctly?";
+ env_path += mod_path;
+ env_path += ';';
+ }
+
+ if (orig_path.isEmpty())
+ qDebug() << "env: empty PATH";
+ else
+ env_path += orig_path;
+
+#if 0
+ qDebug() << "data" << env_path.constData();
+#endif
+
+ // better length limit than putenv() and SetEnvironmentVariableA
+ bool ret = SetEnvironmentVariableW(L"PATH", (const wchar_t*)env_path.constData());
+
+ if (!ret)
+ qDebug() << "_putenv() failed with" << (void*)GetLastError();
}
}
@@ -300,11 +305,13 @@ int otr_main(int argc, char** argv, std::function<std::unique_ptr<QWidget>()> co
QApplication app(argc, argv);
#ifdef _WIN32
- apply_dark_windows_theme_if_needed();
- add_win32_path();
attach_parent_console();
#endif
(void)qInstallMessageHandler(qdebug_to_console);
+#ifdef _WIN32
+ apply_dark_windows_theme_if_needed();
+ add_win32_path();
+#endif
QDir::setCurrent(OPENTRACK_BASE_PATH);
@@ -345,4 +352,3 @@ int otr_main(int argc, char** argv, std::function<std::unique_ptr<QWidget>()> co
return ret;
}
-
diff --git a/proto-osc/CMakeLists.txt b/proto-osc/CMakeLists.txt
new file mode 100644
index 00000000..eeaf206c
--- /dev/null
+++ b/proto-osc/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(SDK_OSCPACK "" CACHE PATH "oscpack build directory")
+if(SDK_OSCPACK)
+ if(WIN32)
+ if(NOT EXISTS "${SDK_OSCPACK}/include/.")
+ message(FATAL_ERROR "SDK_OSCPACK should have 'include' subdirectory (or symlink) to src dir")
+ endif()
+ link_directories("${SDK_OSCPACK}")
+ include_directories("${SDK_OSCPACK}/include" "${SDK_OSCPACK}/include/oscpack")
+ else()
+ link_directories("${SDK_OSCPACK}/lib" "${SDK_OSCPACK}/lib32")
+ include_directories("${SDK_OSCPACK}/include/oscpack")
+ endif()
+ link_libraries(oscpack)
+ otr_module(proto-osc)
+endif()
diff --git a/proto-osc/dialog.cpp b/proto-osc/dialog.cpp
new file mode 100644
index 00000000..54bf6885
--- /dev/null
+++ b/proto-osc/dialog.cpp
@@ -0,0 +1,38 @@
+#include "dialog.hpp"
+#include <QHostAddress>
+#include <QPalette>
+
+void osc_dialog::host_address_edited(const QString& str)
+{
+ bool bad = QHostAddress{str}.isNull();
+ auto pal = pal_;
+ for (auto role : { QPalette::Highlight, QPalette::Window })
+ if (bad)
+ pal.setColor(role, Qt::red);
+ ui.address->setPalette(pal);
+}
+
+osc_dialog::osc_dialog() :
+ pal_{palette()}
+{
+ ui.setupUi( this );
+
+ tie_setting(s.address, ui.address);
+ tie_setting(s.port, ui.port);
+ connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &osc_dialog::doOK);
+ connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &osc_dialog::doCancel);
+ connect(ui.address, &QLineEdit::textChanged, this, &osc_dialog::host_address_edited);
+ host_address_edited(ui.address->text());
+}
+
+void osc_dialog::save() { s.b->save(); }
+void osc_dialog::reload() { s.b->reload(); }
+
+void osc_dialog::doOK() { s.b->save(); close(); }
+void osc_dialog::doCancel() { close(); }
+
+void osc_dialog::register_protocol(IProtocol*) {}
+void osc_dialog::unregister_protocol() {}
+
+bool osc_dialog::embeddable() noexcept { return true; }
+void osc_dialog::set_buttons_visible(bool x) noexcept { ui.buttonBox->setVisible(x); }
diff --git a/proto-osc/dialog.hpp b/proto-osc/dialog.hpp
new file mode 100644
index 00000000..29682843
--- /dev/null
+++ b/proto-osc/dialog.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "settings.hpp"
+#include "ui_dialog.h"
+#include "api/plugin-api.hpp"
+
+class osc_dialog: public IProtocolDialog
+{
+ Q_OBJECT
+
+public:
+ osc_dialog();
+ void register_protocol(IProtocol*) override;
+ void unregister_protocol() override;
+private:
+ void set_buttons_visible(bool x) noexcept override;
+ bool embeddable() noexcept override;
+ void save() override;
+ void reload() override;
+
+ Ui_OSC_Dialog ui;
+ osc_settings s;
+ const QPalette pal_;
+
+private slots:
+ void doOK();
+ void doCancel();
+ void host_address_edited(const QString& str);
+};
diff --git a/proto-osc/dialog.ui b/proto-osc/dialog.ui
new file mode 100644
index 00000000..5a078bbd
--- /dev/null
+++ b/proto-osc/dialog.ui
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OSC_Dialog</class>
+ <widget class="QWidget" name="OSC_Dialog">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>284</width>
+ <height>102</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>284</width>
+ <height>102</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>OSC protocol settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="osc-res.qrc">
+ <normaloff>:/images/osc-icon.png</normaloff>:/images/osc-icon.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Destination address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="address">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="maxLength">
+ <number>256</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="port">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../gui/opentrack-res.qrc"/>
+ <include location="osc-res.qrc"/>
+ </resources>
+ <connections/>
+ <designerdata>
+ <property name="gridDeltaX">
+ <number>5</number>
+ </property>
+ <property name="gridDeltaY">
+ <number>5</number>
+ </property>
+ <property name="gridSnapX">
+ <bool>true</bool>
+ </property>
+ <property name="gridSnapY">
+ <bool>true</bool>
+ </property>
+ <property name="gridVisible">
+ <bool>false</bool>
+ </property>
+ </designerdata>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/proto-osc/images/osc-icon.png b/proto-osc/images/osc-icon.png
new file mode 100644
index 00000000..3ef546e9
--- /dev/null
+++ b/proto-osc/images/osc-icon.png
Binary files differ
diff --git a/proto-osc/lang/nl_NL.ts b/proto-osc/lang/nl_NL.ts
new file mode 100644
index 00000000..260b7adc
--- /dev/null
+++ b/proto-osc/lang/nl_NL.ts
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="nl_NL">
+<context>
+ <name>OSC_Dialog</name>
+ <message>
+ <source>OSC protocol settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Destination address</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_metadata</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_proto</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error binding socket to INADDR_ANY</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invalid destination address &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/proto-osc/lang/ru_RU.ts b/proto-osc/lang/ru_RU.ts
new file mode 100644
index 00000000..498d68d6
--- /dev/null
+++ b/proto-osc/lang/ru_RU.ts
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru_RU">
+<context>
+ <name>OSC_Dialog</name>
+ <message>
+ <source>OSC protocol settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Destination address</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_metadata</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_proto</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error binding socket to INADDR_ANY</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invalid destination address &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/proto-osc/lang/stub.ts b/proto-osc/lang/stub.ts
new file mode 100644
index 00000000..20828cbd
--- /dev/null
+++ b/proto-osc/lang/stub.ts
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>OSC_Dialog</name>
+ <message>
+ <source>OSC protocol settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Destination address</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_metadata</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_proto</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error binding socket to INADDR_ANY</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invalid destination address &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/proto-osc/lang/zh_CN.ts b/proto-osc/lang/zh_CN.ts
new file mode 100644
index 00000000..e0d49844
--- /dev/null
+++ b/proto-osc/lang/zh_CN.ts
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN">
+<context>
+ <name>OSC_Dialog</name>
+ <message>
+ <source>OSC protocol settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Destination address</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_metadata</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>osc_proto</name>
+ <message>
+ <source>Open Sound Control</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error binding socket to INADDR_ANY</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invalid destination address &apos;%1&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/proto-osc/metadata.cpp b/proto-osc/metadata.cpp
new file mode 100644
index 00000000..9d69347d
--- /dev/null
+++ b/proto-osc/metadata.cpp
@@ -0,0 +1,8 @@
+#include "metadata.hpp"
+#include "proto.hpp"
+#include "dialog.hpp"
+
+QString osc_metadata::name() { return tr("Open Sound Control"); }
+QIcon osc_metadata::icon() { return QIcon(":/images/osc-icon.png"); }
+
+OPENTRACK_DECLARE_PROTOCOL(osc_proto, osc_dialog, osc_metadata)
diff --git a/proto-osc/metadata.hpp b/proto-osc/metadata.hpp
new file mode 100644
index 00000000..c0a947aa
--- /dev/null
+++ b/proto-osc/metadata.hpp
@@ -0,0 +1,10 @@
+#pragma once
+#include "api/plugin-api.hpp"
+
+class osc_metadata : public Metadata
+{
+ Q_OBJECT
+
+ QString name() override;
+ QIcon icon() override;
+};
diff --git a/proto-osc/osc-res.qrc b/proto-osc/osc-res.qrc
new file mode 100644
index 00000000..ade4c629
--- /dev/null
+++ b/proto-osc/osc-res.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/osc-icon.png</file>
+ </qresource>
+</RCC>
diff --git a/proto-osc/proto.cpp b/proto-osc/proto.cpp
new file mode 100644
index 00000000..2f90957c
--- /dev/null
+++ b/proto-osc/proto.cpp
@@ -0,0 +1,54 @@
+#include "proto.hpp"
+#include "ui_dialog.h"
+#include "api/plugin-api.hpp"
+#include <QQuaternion>
+#include <QHostAddress>
+#include "osc/OscOutboundPacketStream.h"
+
+osc_proto::osc_proto()
+{
+ auto reload_fn = [this] {
+ dest = QHostAddress{s.address };
+ port = (unsigned short)s.port;
+ };
+ connect(&*s.b, &bundle_::changed, this, reload_fn);
+ connect(&*s.b, &bundle_::reloading, this, reload_fn);
+}
+
+void osc_proto::pose(const double* data, const double*)
+{
+ if (dest.isNull())
+ return;
+
+ static constexpr unsigned buffer_size = 1024;
+ char buffer[buffer_size] = {};
+ osc::OutboundPacketStream p{buffer, buffer_size};
+ auto q = QQuaternion::fromEulerAngles((float)data[Pitch], (float)data[Yaw], (float)-data[Roll]).normalized();
+ p << osc::BeginMessage("/bridge/quat") << q.scalar() << q.x() << q.y() << q.z() << osc::EndMessage;
+ sock.writeDatagram(p.Data(), (int)p.Size(), dest, port);
+}
+
+module_status osc_proto::initialize()
+{
+ QString error;
+
+ dest = QHostAddress{s.address };
+ port = (unsigned short)s.port;
+
+ if (dest.isNull())
+ {
+ error = tr("Invalid destination address '%1'").arg(s.address);
+ goto fail;
+ }
+
+ if (!sock.bind())
+ {
+ error = tr("Error binding socket to INADDR_ANY");
+ goto fail;
+ }
+
+ return status_ok();
+
+fail:
+ return { tr("%1: %2").arg(error, sock.errorString()) };
+}
diff --git a/proto-osc/proto.hpp b/proto-osc/proto.hpp
new file mode 100644
index 00000000..53a5dee4
--- /dev/null
+++ b/proto-osc/proto.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+/* Copyright (c) 2023 Stanislaw Halik <sthalik@misaki.pl>
+ *
+ * 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 "settings.hpp"
+#include "api/plugin-api.hpp"
+#include <QUdpSocket>
+#include <QHostAddress>
+
+class osc_proto : public QObject, public IProtocol
+{
+ Q_OBJECT
+
+ osc_settings s;
+ QUdpSocket sock;
+ QHostAddress dest;
+ unsigned short port = 0;
+
+public:
+ osc_proto();
+ module_status initialize() override;
+ void pose(const double *headpose, const double*) override;
+ QString game_name() override { return tr("Open Sound Control"); }
+};
diff --git a/proto-osc/settings.hpp b/proto-osc/settings.hpp
new file mode 100644
index 00000000..edeb45c6
--- /dev/null
+++ b/proto-osc/settings.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include <QString>
+#include "options/options.hpp"
+
+using namespace options;
+
+struct osc_settings : opts
+{
+ value<QString> address;
+ value<int> port;
+ osc_settings() : opts("proto-osc"), address{b, "address", "127.0.0.1"},
+ port(b, "port", 53101)
+ {}
+};
diff --git a/proto-simconnect/ftnoir_protocol_sc.cpp b/proto-simconnect/ftnoir_protocol_sc.cpp
index 226a427b..ca76e0ce 100644
--- a/proto-simconnect/ftnoir_protocol_sc.cpp
+++ b/proto-simconnect/ftnoir_protocol_sc.cpp
@@ -43,20 +43,15 @@ void simconnect::run()
qDebug() << "fsx: connect failed, retry in" << sleep_time << "seconds...";
else
{
- Timer tm;
-
- if (!SUCCEEDED(hr = simconnect_subscribe(handle, 0, "Frame")))
+ if (!SUCCEEDED(hr = simconnect_subscribe(handle, 0, "1sec")))
qDebug() << "fsx: can't subscribe to frame event:" << (void*)hr;
else
{
while (!isInterruptionRequested())
{
- constexpr int max_idle_seconds = 2;
-
- if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
- tm.start();
+ constexpr int max_idle_ms = 2000;
- if ((int)tm.elapsed_seconds() > max_idle_seconds)
+ if (WaitForSingleObject(event, max_idle_ms) != WAIT_OBJECT_0)
{
qDebug() << "fsx: timeout reached, reconnecting";
break;
@@ -73,7 +68,9 @@ void simconnect::run()
}
}
+ QMutexLocker l(&mtx);
(void)simconnect_close(handle);
+ handle = nullptr;
}
for (unsigned k = 0; k < sleep_time * 25; k++)
@@ -91,8 +88,6 @@ void simconnect::run()
void simconnect::pose(const double* pose, const double*)
{
- QMutexLocker l(&mtx);
-
data[Pitch] = (float)-pose[Pitch];
data[Yaw] = (float)pose[Yaw];
data[Roll] = (float)pose[Roll];
@@ -101,6 +96,12 @@ void simconnect::pose(const double* pose, const double*)
data[TX] = (float)-pose[TX] * to_meters;
data[TY] = (float)pose[TY] * to_meters;
data[TZ] = (float)-pose[TZ] * to_meters;
+
+ QMutexLocker l(&mtx);
+ if (handle)
+ (void)simconnect_set6DOF(handle,
+ data[TX], data[TY], data[TZ],
+ data[Pitch], data[Roll], data[Yaw]);
}
module_status simconnect::initialize()
@@ -148,14 +149,6 @@ module_status simconnect::initialize()
return {};
}
-void simconnect::handler()
-{
- QMutexLocker l(&mtx);
- (void)simconnect_set6DOF(handle,
- data[TX], data[TY], data[TZ],
- data[Pitch], data[Roll], data[Yaw]);
-}
-
void simconnect::event_handler(SIMCONNECT_RECV* pData, DWORD, void* self_)
{
simconnect& self = *reinterpret_cast<simconnect*>(self_);
@@ -172,9 +165,6 @@ void simconnect::event_handler(SIMCONNECT_RECV* pData, DWORD, void* self_)
qDebug() << "fsx: got quit event";
self.reconnect = true;
break;
- case SIMCONNECT_RECV_ID_EVENT_FRAME:
- self.handler();
- break;
}
}
diff --git a/proto-simconnect/ftnoir_protocol_sc.h b/proto-simconnect/ftnoir_protocol_sc.h
index 28b9b1d8..df3a538d 100644
--- a/proto-simconnect/ftnoir_protocol_sc.h
+++ b/proto-simconnect/ftnoir_protocol_sc.h
@@ -47,8 +47,6 @@ public:
void run() override;
private:
- void handler();
-
enum {
SIMCONNECT_RECV_ID_EXCEPTION = 2,
SIMCONNECT_RECV_ID_QUIT = 3,
diff --git a/sdk-paths-sthalik@MSVC-windows.cmake b/sdk-paths-sthalik@MSVC-windows.cmake
index 8f185695..340b78ad 100644
--- a/sdk-paths-sthalik@MSVC-windows.cmake
+++ b/sdk-paths-sthalik@MSVC-windows.cmake
@@ -28,22 +28,23 @@ setq(SDK_REALSENSE "RSSDK-R2")
setq(SDK_VALVE_STEAMVR "steamvr")
setq(SDK_FSUIPC "fsuipc")
setq(SDK_HYDRA "SixenseSDK")
+setq(SDK_EYEWARE_BEAM "eyeware-beam-sdk")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
setq(Qt5_DIR "../qt-5.15-kde-amd64/lib/cmake/Qt5")
setq(OpenCV_DIR "opencv/build-amd64/install")
setq(SDK_ARUCO_LIBPATH "aruco/build-amd64/src/aruco.lib")
setq(SDK_LIBUSB "libusb-msvc-amd64")
-setq(ONNXRuntime_DIR "onnxruntime-1.12.1-amd64")
+setq(ONNXRuntime_DIR "onnxruntime-1.14.1-amd64")
setq(SDK_TRACKHAT_SENSOR "trackhat-c-library-driver/build-amd64/install")
-setq(SDK_EYEWARE_BEAM "BeamSDK-Windows64-1.1.0")
+setq(SDK_OSCPACK "oscpack/build-amd64")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
setq(Qt5_DIR "../qt-5.15-kde/lib/cmake/Qt5")
setq(OpenCV_DIR "opencv/build/install")
setq(SDK_ARUCO_LIBPATH "aruco/build/src/aruco.lib")
setq(SDK_LIBUSB "libusb-msvc-x86")
-setq(ONNXRuntime_DIR "onnxruntime-1.12.1")
+setq(ONNXRuntime_DIR "onnxruntime-1.14.1")
setq(SDK_TRACKHAT_SENSOR "trackhat-c-library-driver/build/install")
-set(SDK_EYEWARE_BEAM "" CACHE PATH "" FORCE)
+setq(SDK_OSCPACK "oscpack/build")
else()
message(FATAL_ERROR "unknown word size ${CMAKE_SIZEOF_VOID_P}b")
endif()
diff --git a/tracker-aruco/aruco-trackercontrols.ui b/tracker-aruco/aruco-trackercontrols.ui
index 0cd76b89..729d4b48 100644
--- a/tracker-aruco/aruco-trackercontrols.ui
+++ b/tracker-aruco/aruco-trackercontrols.ui
@@ -139,6 +139,11 @@
</item>
<item>
<property name="text">
+ <string>1920x1080</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string>Default (not recommended!)</string>
</property>
</item>
diff --git a/tracker-aruco/ftnoir_tracker_aruco.cpp b/tracker-aruco/ftnoir_tracker_aruco.cpp
index 1f39db32..5130a889 100644
--- a/tracker-aruco/ftnoir_tracker_aruco.cpp
+++ b/tracker-aruco/ftnoir_tracker_aruco.cpp
@@ -57,6 +57,7 @@ static const resolution_tuple resolution_choices[] =
{ 640, 480 },
{ 320, 240 },
{ 1280, 720 },
+ { 1920, 1080 },
{ 0, 0 }
};
diff --git a/tracker-aruco/lang/nl_NL.ts b/tracker-aruco/lang/nl_NL.ts
index 1a510ac1..e5a94f3b 100644
--- a/tracker-aruco/lang/nl_NL.ts
+++ b/tracker-aruco/lang/nl_NL.ts
@@ -67,6 +67,10 @@
<source>MJPEG</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>1920x1080</source>
+ <translation type="unfinished">1280x1080 {1920x?}</translation>
+ </message>
</context>
<context>
<name>aruco_dialog</name>
diff --git a/tracker-aruco/lang/ru_RU.ts b/tracker-aruco/lang/ru_RU.ts
index 3e0aa86a..639b59ce 100644
--- a/tracker-aruco/lang/ru_RU.ts
+++ b/tracker-aruco/lang/ru_RU.ts
@@ -67,6 +67,10 @@
<source>MJPEG</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>1920x1080</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>aruco_dialog</name>
diff --git a/tracker-aruco/lang/stub.ts b/tracker-aruco/lang/stub.ts
index bbd78995..f213eb41 100644
--- a/tracker-aruco/lang/stub.ts
+++ b/tracker-aruco/lang/stub.ts
@@ -67,6 +67,10 @@
<source>MJPEG</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>1920x1080</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>aruco_dialog</name>
diff --git a/tracker-aruco/lang/zh_CN.ts b/tracker-aruco/lang/zh_CN.ts
index 71fa163c..8c4e5511 100644
--- a/tracker-aruco/lang/zh_CN.ts
+++ b/tracker-aruco/lang/zh_CN.ts
@@ -67,6 +67,10 @@
<source>MJPEG</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>1920x1080</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>aruco_dialog</name>
diff --git a/tracker-eyeware-beam/CMakeLists.txt b/tracker-eyeware-beam/CMakeLists.txt
index 73ea231a..e041c131 100644
--- a/tracker-eyeware-beam/CMakeLists.txt
+++ b/tracker-eyeware-beam/CMakeLists.txt
@@ -7,9 +7,15 @@ if(WIN32 AND SDK_EYEWARE_BEAM)
endif()
otr_module(tracker-eyeware-beam)
+ if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
+ set(arch "x86")
+ else()
+ set(arch "x64")
+ endif()
+
target_include_directories(${self} SYSTEM PRIVATE "${SDK_EYEWARE_BEAM}/API/cpp/include")
- target_link_directories(${self} PRIVATE "${SDK_EYEWARE_BEAM}/API/cpp/lib")
- set(dll "${SDK_EYEWARE_BEAM}/API/cpp/lib/tracker_client.dll" "${SDK_EYEWARE_BEAM}/API/cpp/lib/libsodium.dll")
+ target_link_directories(${self} PRIVATE "${SDK_EYEWARE_BEAM}/API/cpp/lib/${arch}")
+ set(dll "${SDK_EYEWARE_BEAM}/API/cpp/lib/${arch}/tracker_client.dll")
set(lib tracker_client.lib)
#message(${self})
diff --git a/tracker-neuralnet/CMakeLists.txt b/tracker-neuralnet/CMakeLists.txt
index 4689dba1..db568fae 100644
--- a/tracker-neuralnet/CMakeLists.txt
+++ b/tracker-neuralnet/CMakeLists.txt
@@ -16,16 +16,21 @@ if(OpenCV_FOUND AND ONNXRuntime_FOUND AND OpenMP_FOUND)
otr_module(tracker-neuralnet)
- target_link_libraries(${self}
+ target_link_libraries(${self}
opentrack-cv
onnxruntime::onnxruntime
opencv_calib3d
opencv_imgproc
opencv_imgcodecs
opencv_core
- OpenMP::OpenMP_C
+ OpenMP::OpenMP_CXX
)
+ # OpenMP::OpenMP_CXX doesn't set up the -fopenmp linking option, so set it up ourselves.
+ if(NOT MSVC)
+ target_link_options(${self} PUBLIC ${OpenMP_CXX_FLAGS})
+ endif()
+
install(
FILES "models/head-localizer.onnx"
"models/head-pose.onnx"
diff --git a/tracker-neuralnet/model_adapters.cpp b/tracker-neuralnet/model_adapters.cpp
index af599321..a8580a89 100644
--- a/tracker-neuralnet/model_adapters.cpp
+++ b/tracker-neuralnet/model_adapters.cpp
@@ -8,7 +8,6 @@
#include <QDebug>
-
namespace neuralnet_tracker_ns
{
@@ -165,6 +164,24 @@ double Localizer::last_inference_time_millis() const
}
+std::string PoseEstimator::get_network_input_name(size_t i) const
+{
+#if ORT_API_VERSION >= 12
+ return std::string(&*session_.GetInputNameAllocated(i, allocator_));
+#else
+ return std::string(session_.GetInputName(i, allocator_));
+#endif
+}
+
+std::string PoseEstimator::get_network_output_name(size_t i) const
+{
+#if ORT_API_VERSION >= 12
+ return std::string(&*session_.GetOutputNameAllocated(i, allocator_));
+#else
+ return std::string(session_.GetOutputName(i, allocator_));
+#endif
+}
+
PoseEstimator::PoseEstimator(Ort::MemoryInfo &allocator_info, Ort::Session &&session)
: model_version_{session.GetModelMetadata().GetVersion()}
, session_{std::move(session)}
@@ -215,14 +232,16 @@ PoseEstimator::PoseEstimator(Ort::MemoryInfo &allocator_info, Ort::Session &&ses
qDebug() << "Pose model inputs (" << session_.GetInputCount() << ")";
qDebug() << "Pose model outputs (" << session_.GetOutputCount() << "):";
+ output_names_.resize(session_.GetOutputCount());
+ output_c_names_.resize(session_.GetOutputCount());
for (size_t i=0; i<session_.GetOutputCount(); ++i)
{
- const char* name = session_.GetOutputName(i, allocator_);
+ std::string name = get_network_output_name(i);
const auto& output_info = session_.GetOutputTypeInfo(i);
const auto& onnx_tensor_spec = output_info.GetTensorTypeAndShapeInfo();
auto my_tensor_spec = understood_outputs.find(name);
- qDebug() << "\t" << name << " (" << onnx_tensor_spec.GetShape() << ") dtype: " << onnx_tensor_spec.GetElementType() << " " <<
+ qDebug() << "\t" << name.c_str() << " (" << onnx_tensor_spec.GetShape() << ") dtype: " << onnx_tensor_spec.GetElementType() << " " <<
(my_tensor_spec != understood_outputs.end() ? "ok" : "unknown");
if (my_tensor_spec != understood_outputs.end())
@@ -240,7 +259,8 @@ PoseEstimator::PoseEstimator(Ort::MemoryInfo &allocator_info, Ort::Session &&ses
// Create tensor regardless and ignore output
output_val_.push_back(create_tensor(output_info, allocator_));
}
- output_names_.push_back(name);
+ output_names_[i] = name;
+ output_c_names_[i] = output_names_[i].c_str();
}
has_uncertainty_ = understood_outputs.at("rotaxis_scales_tril").available ||
@@ -270,9 +290,12 @@ PoseEstimator::PoseEstimator(Ort::MemoryInfo &allocator_info, Ort::Session &&ses
// output_val_.push_back(create_tensor(output_info, allocator_));
// }
+ input_names_.resize(session_.GetInputCount());
+ input_c_names_.resize(session_.GetInputCount());
for (size_t i = 0; i < session_.GetInputCount(); ++i)
{
- input_names_.push_back(session_.GetInputName(i, allocator_));
+ input_names_[i] = get_network_input_name(i);
+ input_c_names_[i] = input_names_[i].c_str();
}
assert (input_names_.size() == input_val_.size());
@@ -312,11 +335,11 @@ std::optional<PoseEstimator::Face> PoseEstimator::run(
{
session_.Run(
Ort::RunOptions{ nullptr },
- input_names_.data(),
+ input_c_names_.data(),
input_val_.data(),
input_val_.size(),
- output_names_.data(),
- output_val_.data(),
+ output_c_names_.data(),
+ output_val_.data(),
output_val_.size());
}
catch (const Ort::Exception &e)
@@ -430,4 +453,4 @@ double PoseEstimator::last_inference_time_millis() const
-} // namespace neuralnet_tracker_ns \ No newline at end of file
+} // namespace neuralnet_tracker_ns
diff --git a/tracker-neuralnet/model_adapters.h b/tracker-neuralnet/model_adapters.h
index 3fbfb861..820330cf 100644
--- a/tracker-neuralnet/model_adapters.h
+++ b/tracker-neuralnet/model_adapters.h
@@ -3,6 +3,7 @@
#include <optional>
#include <array>
#include <vector>
+#include <string>
#include <onnxruntime_cxx_api.h>
#include <opencv2/core.hpp>
@@ -21,7 +22,7 @@ class Localizer
public:
Localizer(Ort::MemoryInfo &allocator_info,
Ort::Session &&session);
-
+
// Returns bounding wrt image coordinate of the input image
// The preceeding float is the score for being a face normalized to [0,1].
std::pair<float, cv::Rect2f> run(
@@ -68,13 +69,16 @@ class PoseEstimator
bool has_uncertainty() const { return has_uncertainty_; }
private:
+ std::string get_network_input_name(size_t i) const;
+ std::string get_network_output_name(size_t i) const;
int64_t model_version_ = 0; // Queried meta data from the ONNX file
Ort::Session session_{nullptr}; // ONNX's runtime context for running the model
Ort::Allocator allocator_; // Memory allocator for tensors
// Inputs
cv::Mat scaled_frame_{}, input_mat_{}; // Input. One is the original crop, the other is rescaled (?)
std::vector<Ort::Value> input_val_; // Tensors to put into the model
- std::vector<const char*> input_names_; // Refers to the names in the onnx model.
+ std::vector<std::string> input_names_; // Refers to the names in the onnx model.
+ std::vector<const char *> input_c_names_; // Refers to the C names in the onnx model.
// Outputs
cv::Vec<float, 3> output_coord_{}; // 2d Coordinate and head size output.
cv::Vec<float, 4> output_quat_{}; // Quaternion output
@@ -83,7 +87,8 @@ class PoseEstimator
cv::Vec<float, 2> output_eyes_{};
cv::Vec<float, 3> output_coord_scales_{};
std::vector<Ort::Value> output_val_; // Tensors to put the model outputs in.
- std::vector<const char*> output_names_; // Refers to the names in the onnx model.
+ std::vector<std::string> output_names_; // Refers to the names in the onnx model.
+ std::vector<const char *> output_c_names_; // Refers to the C names in the onnx model.
// More bookkeeping
size_t num_recurrent_states_ = 0;
double last_inference_time_ = 0;
@@ -99,4 +104,4 @@ int find_input_intensity_quantile(const cv::Mat& frame, float percentage);
void normalize_brightness(const cv::Mat& frame, cv::Mat& out);
-} // namespace neuralnet_tracker_ns \ No newline at end of file
+} // namespace neuralnet_tracker_ns
diff --git a/tracker-pt/FTNoIR_PT_Controls.ui b/tracker-pt/FTNoIR_PT_Controls.ui
index 4cf4344c..53a29c1a 100644
--- a/tracker-pt/FTNoIR_PT_Controls.ui
+++ b/tracker-pt/FTNoIR_PT_Controls.ui
@@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>413</width>
- <height>575</height>
+ <height>630</height>
</rect>
</property>
<property name="sizePolicy">
@@ -79,21 +79,47 @@
<string>Camera settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="8" column="1">
- <widget class="QPushButton" name="camera_settings">
+ <item row="11" column="1">
+ <widget class="QCheckBox" name="chroma_key_overexposed">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_4">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="cursor">
+ <cursorShape>WhatsThisCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>This should be 56° or 76° for the PS3 Eye, dependent upon the physical lens setting. It's only neccessary to get position correspond to real-world values.</string>
+ </property>
<property name="text">
- <string>Open</string>
+ <string>Diagonal field of view</string>
</property>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_4">
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Dynamic pose (for caps only, never clips)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
@@ -104,23 +130,49 @@
<cursorShape>WhatsThisCursor</cursorShape>
</property>
<property name="toolTip">
- <string>This should be 56° or 76° for the PS3 Eye, dependent upon the physical lens setting. It's only neccessary to get position correspond to real-world values.</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For LEDs, 'Natural' is the fastest grayscale mode thanks to optimized SIMD code. Color key allows to track regular pieces of colored paper.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
- <string>Diagonal field of view</string>
+ <string>Color channels used</string>
</property>
</widget>
</item>
- <item row="8" column="0">
- <widget class="QLabel" name="label_9">
+ <item row="8" column="1">
+ <widget class="QPushButton" name="camera_settings">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Open</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QCheckBox" name="use_mjpeg">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="cursor">
+ <cursorShape>WhatsThisCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Enable MJPEG compression for high-speed cameras other than the PS3 Eye. Windows only.</string>
+ </property>
<property name="text">
- <string>Camera settings (when available)</string>
+ <string>MJPEG compression</string>
</property>
</widget>
</item>
@@ -153,73 +205,15 @@
</property>
</widget>
</item>
- <item row="9" column="1">
- <widget class="QComboBox" name="blob_color">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Chroma key includes overexposed pixels</string>
</property>
- <item>
- <property name="text">
- <string>Grayscale BT.709</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Grayscale (from hardware)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Red only</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Green only</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Blue only</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Red chroma key</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Green chroma key</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Blue chroma key</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Cyan chroma key</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Yellow chroma key</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Magenta chroma key</string>
- </property>
- </item>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_41">
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
@@ -227,20 +221,26 @@
</sizepolicy>
</property>
<property name="text">
- <string>Height</string>
+ <string>Camera settings (when available)</string>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_5">
+ <item row="7" column="1">
+ <widget class="QSpinBox" name="init_phase_timeout">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text">
- <string>Dynamic pose (for caps only, never clips)</string>
+ <property name="suffix">
+ <string> ms</string>
+ </property>
+ <property name="minimum">
+ <number>50</number>
+ </property>
+ <property name="maximum">
+ <number>5000</number>
</property>
</widget>
</item>
@@ -257,8 +257,8 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="res_y_spin">
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="res_x_spin">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
@@ -266,7 +266,7 @@
</sizepolicy>
</property>
<property name="toolTip">
- <string>Desired capture height</string>
+ <string>Desired capture width</string>
</property>
<property name="suffix">
<string> px</string>
@@ -279,22 +279,16 @@
</property>
</widget>
</item>
- <item row="9" column="0">
- <widget class="QLabel" name="label_12">
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="cursor">
- <cursorShape>WhatsThisCursor</cursorShape>
- </property>
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For LEDs, 'Natural' is the fastest grayscale mode thanks to optimized SIMD code. Color key allows to track regular pieces of colored paper.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
<property name="text">
- <string>Color channels used</string>
+ <string>Dynamic pose timeout</string>
</property>
</widget>
</item>
@@ -311,25 +305,32 @@
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="res_x_spin">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="toolTip">
- <string>Desired capture width</string>
+ <property name="text">
+ <string>Device</string>
</property>
- <property name="suffix">
- <string> px</string>
+ <property name="buddy">
+ <cstring>camdevice_combo</cstring>
</property>
- <property name="maximum">
- <number>2000</number>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_41">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="singleStep">
- <number>10</number>
+ <property name="text">
+ <string>Height</string>
</property>
</widget>
</item>
@@ -352,23 +353,69 @@
</property>
</widget>
</item>
- <item row="7" column="1">
- <widget class="QSpinBox" name="init_phase_timeout">
+ <item row="9" column="1">
+ <widget class="QComboBox" name="blob_color">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="suffix">
- <string> ms</string>
- </property>
- <property name="minimum">
- <number>50</number>
- </property>
- <property name="maximum">
- <number>5000</number>
- </property>
+ <item>
+ <property name="text">
+ <string>Grayscale BT.709</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Grayscale (from hardware)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Red only</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Green only</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Blue only</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Red chroma key</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Green chroma key</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Blue chroma key</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Cyan chroma key</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yellow chroma key</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Magenta chroma key</string>
+ </property>
+ </item>
</widget>
</item>
<item row="5" column="1">
@@ -393,60 +440,70 @@
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_2">
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="res_y_spin">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text">
- <string>Device</string>
+ <property name="toolTip">
+ <string>Desired capture height</string>
</property>
- <property name="buddy">
- <cstring>camdevice_combo</cstring>
+ <property name="suffix">
+ <string> px</string>
</property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <property name="maximum">
+ <number>2000</number>
</property>
- <property name="text">
- <string>Dynamic pose timeout</string>
+ <property name="singleStep">
+ <number>10</number>
</property>
</widget>
</item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_13">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="cursor">
- <cursorShape>WhatsThisCursor</cursorShape>
- </property>
- <property name="toolTip">
- <string>Enable MJPEG compression for high-speed cameras other than the PS3 Eye. Windows only.</string>
- </property>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_17">
<property name="text">
- <string>MJPEG compression</string>
+ <string>Chroma key strength</string>
</property>
</widget>
</item>
- <item row="4" column="1">
- <widget class="QCheckBox" name="use_mjpeg">
- <property name="text">
- <string/>
- </property>
- </widget>
+ <item row="10" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSlider" name="chroma_key_strength_slider">
+ <property name="minimum">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="chroma_key_strength_label">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ <property name="minimum">
+ <double>0.500000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>4.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
@@ -602,6 +659,26 @@
</property>
</widget>
</item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="threshold_value_display">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="mindiam_spin">
<property name="sizePolicy">
@@ -624,26 +701,6 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QLabel" name="threshold_value_display">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Value</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
@@ -1635,55 +1692,55 @@ Don't roll or change position.</string>
<string>Status</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
- <item row="1" column="0">
- <widget class="QLabel" name="label_3">
+ <item row="1" column="1">
+ <widget class="QLabel" name="pointinfo_label">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string>Extracted Points:</string>
+ <string/>
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_38">
+ <item row="0" column="1">
+ <widget class="QLabel" name="caminfo_label">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string>Camera Info:</string>
+ <string/>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QLabel" name="pointinfo_label">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string/>
+ <string>Extracted Points:</string>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QLabel" name="caminfo_label">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_38">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string/>
+ <string>Camera Info:</string>
</property>
</widget>
</item>
@@ -1717,6 +1774,8 @@ Don't roll or change position.</string>
<tabstop>init_phase_timeout</tabstop>
<tabstop>camera_settings</tabstop>
<tabstop>blob_color</tabstop>
+ <tabstop>chroma_key_strength_slider</tabstop>
+ <tabstop>chroma_key_overexposed</tabstop>
<tabstop>auto_threshold</tabstop>
<tabstop>threshold_slider</tabstop>
<tabstop>mindiam_spin</tabstop>
diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.cpp b/tracker-pt/ftnoir_tracker_pt_dialog.cpp
index 160eb831..d67f79a7 100644
--- a/tracker-pt/ftnoir_tracker_pt_dialog.cpp
+++ b/tracker-pt/ftnoir_tracker_pt_dialog.cpp
@@ -110,6 +110,16 @@ TrackerDialog_PT::TrackerDialog_PT(const QString& module_name) :
tie_setting(s.blob_color, ui.blob_color);
+ tie_setting(s.chroma_key_strength, ui.chroma_key_strength_slider);
+ connect(&s.chroma_key_strength, value_::value_changed<slider_value>(), ui.chroma_key_strength_label,
+ [this] { ui.chroma_key_strength_label->setValue(*s.chroma_key_strength); });
+ ui.chroma_key_strength_label->setValue(*s.chroma_key_strength);
+
+ tie_setting(s.chroma_key_overexposed, ui.chroma_key_overexposed);
+ connect(ui.blob_color, &QComboBox::currentTextChanged, this, &TrackerDialog_PT::chroma_key_controls_enable);
+
+ chroma_key_controls_enable("");
+
tie_setting(s.threshold_slider, ui.threshold_value_display, [this](const slider_value& val) {
return threshold_display_text(int(val));
});
@@ -248,6 +258,20 @@ void TrackerDialog_PT::show_camera_settings()
(void)video::show_dialog(s.camera_name);
}
+void TrackerDialog_PT::chroma_key_controls_enable(const QString&)
+{
+ bool enabled = false;
+ QVariant data = ui.blob_color->currentData();
+ if (data.isValid())
+ {
+ pt_color_type blob_color = pt_color_type(data.toInt());
+ enabled = blob_color >= pt_color_red_chromakey && blob_color <= pt_color_magenta_chromakey;
+ }
+ ui.chroma_key_strength_slider->setEnabled(enabled);
+ ui.chroma_key_strength_label->setEnabled(enabled);
+ ui.chroma_key_overexposed->setEnabled(enabled);
+}
+
void TrackerDialog_PT::trans_calib_step()
{
QMutexLocker l(&calibrator_mutex);
diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.h b/tracker-pt/ftnoir_tracker_pt_dialog.h
index f4b0ff8c..79cd91bd 100644
--- a/tracker-pt/ftnoir_tracker_pt_dialog.h
+++ b/tracker-pt/ftnoir_tracker_pt_dialog.h
@@ -39,6 +39,8 @@ public slots:
void poll_tracker_info_impl();
void set_camera_settings_available(const QString& camera_name);
void show_camera_settings();
+ void chroma_key_controls_enable(const QString&);
+
protected:
QString threshold_display_text(int threshold_value);
diff --git a/tracker-pt/lang/nl_NL.ts b/tracker-pt/lang/nl_NL.ts
index 90383b97..fc44b0f1 100644
--- a/tracker-pt/lang/nl_NL.ts
+++ b/tracker-pt/lang/nl_NL.ts
@@ -304,6 +304,14 @@ Don&apos;t roll or change position.</source>
<source>Filter</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Chroma key includes overexposed pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Chroma key strength</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/ru_RU.ts b/tracker-pt/lang/ru_RU.ts
index b7146449..7ff4657e 100644
--- a/tracker-pt/lang/ru_RU.ts
+++ b/tracker-pt/lang/ru_RU.ts
@@ -309,6 +309,14 @@ ROLL или X/Y-смещения.</translation>
<source>Filter</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Chroma key includes overexposed pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Chroma key strength</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/stub.ts b/tracker-pt/lang/stub.ts
index 3d5e9ae7..3dbe208d 100644
--- a/tracker-pt/lang/stub.ts
+++ b/tracker-pt/lang/stub.ts
@@ -304,6 +304,14 @@ Don&apos;t roll or change position.</source>
<source>Filter</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Chroma key includes overexposed pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Chroma key strength</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/zh_CN.ts b/tracker-pt/lang/zh_CN.ts
index d8aff4b5..3519d719 100644
--- a/tracker-pt/lang/zh_CN.ts
+++ b/tracker-pt/lang/zh_CN.ts
@@ -304,6 +304,14 @@ Don&apos;t roll or change position.</source>
<source>Filter</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Chroma key includes overexposed pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Chroma key strength</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/module/point_extractor.cpp b/tracker-pt/module/point_extractor.cpp
index 17819d78..3329fafc 100644
--- a/tracker-pt/module/point_extractor.cpp
+++ b/tracker-pt/module/point_extractor.cpp
@@ -11,6 +11,7 @@
#include "frame.hpp"
#include "cv/numeric.hpp"
#include "compat/math.hpp"
+#include "compat/math-imports.hpp"
#include <opencv2/imgproc.hpp>
@@ -111,11 +112,31 @@ void PointExtractor::extract_single_channel(const cv::Mat& orig_frame, int idx,
cv::mixChannels(&orig_frame, 1, &dest, 1, from_to, 1);
}
-void PointExtractor::filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, cv::Mat1b& dest)
+void PointExtractor::filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, bool overexp, cv::Mat1b& dest)
{
ensure_channel_buffers(orig_frame);
- cv::transform(orig_frame, dest, cv::Mat(cv::Matx13f(b, g, r)));
+ // just filter for colour or also include overexposed regions?
+ if (!overexp)
+ cv::transform(orig_frame, dest, cv::Mat(cv::Matx13f(b, g, r)));
+ else
+ {
+ for (int i = 0; i < orig_frame.rows; i++)
+ {
+ cv::Vec3b const* const __restrict orig_ptr = orig_frame.ptr<cv::Vec3b>(i);
+ uint8_t* const __restrict dest_ptr = dest.ptr(i);
+ for (int j = 0; j < orig_frame.cols; j++)
+ {
+ // get the intensity of the key color (i.e. +ve coefficients)
+ uchar blue = orig_ptr[j][0], green = orig_ptr[j][1], red = orig_ptr[j][2];
+ float key = std::max(b, 0.0f) * blue + std::max(g, 0.0f) * green + std::max(r, 0.0f) * red;
+ // get the intensity of the non-key color (i.e. -ve coefficients)
+ float nonkey = std::max(-b, 0.0f) * blue + std::max(-g, 0.0f) * green + std::max(-r, 0.0f) * red;
+ // the result is key color minus non-key color inversely weighted by key colour intensity
+ dest_ptr[j] = std::max(0.0f, std::min(255.0f, key - (255.0f - key) / 255.0f * nonkey));
+ }
+ }
+ }
}
void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
@@ -127,6 +148,7 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
return;
}
+ const float half_chr_key_str = *s.chroma_key_strength * 0.5;
switch (s.blob_color)
{
case pt_color_green_only:
@@ -146,32 +168,32 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
}
case pt_color_red_chromakey:
{
- filter_single_channel(frame, 1, -0.5, -0.5, output);
+ filter_single_channel(frame, 1, -half_chr_key_str, -half_chr_key_str, s.chroma_key_overexposed, output);
break;
}
case pt_color_green_chromakey:
{
- filter_single_channel(frame, -0.5, 1, -0.5, output);
+ filter_single_channel(frame, -half_chr_key_str, 1, -half_chr_key_str, s.chroma_key_overexposed, output);
break;
}
case pt_color_blue_chromakey:
{
- filter_single_channel(frame, -0.5, -0.5, 1, output);
+ filter_single_channel(frame, -half_chr_key_str, -half_chr_key_str, 1, s.chroma_key_overexposed, output);
break;
}
case pt_color_cyan_chromakey:
{
- filter_single_channel(frame, -1, 0.5, 0.5, output);
+ filter_single_channel(frame, -*s.chroma_key_strength, 0.5, 0.5, s.chroma_key_overexposed, output);
break;
}
case pt_color_yellow_chromakey:
{
- filter_single_channel(frame, 0.5, 0.5, -1, output);
+ filter_single_channel(frame, 0.5, 0.5, -*s.chroma_key_strength, s.chroma_key_overexposed, output);
break;
}
case pt_color_magenta_chromakey:
{
- filter_single_channel(frame, 0.5, -1, 0.5, output);
+ filter_single_channel(frame, 0.5, -*s.chroma_key_strength, 0.5, s.chroma_key_overexposed, output);
break;
}
case pt_color_hardware:
diff --git a/tracker-pt/module/point_extractor.h b/tracker-pt/module/point_extractor.h
index 3f7fb4ee..fbfdbb0b 100644
--- a/tracker-pt/module/point_extractor.h
+++ b/tracker-pt/module/point_extractor.h
@@ -51,7 +51,7 @@ private:
void ensure_buffers(const cv::Mat& frame);
void extract_single_channel(const cv::Mat& orig_frame, int idx, cv::Mat1b& dest);
- void filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, cv::Mat1b& dest);
+ void filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, bool overexp, cv::Mat1b& dest);
void color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output);
void threshold_image(const cv::Mat& frame_gray, cv::Mat1b& output);
diff --git a/tracker-pt/pt-settings.hpp b/tracker-pt/pt-settings.hpp
index 6f7a18d5..5d16d973 100644
--- a/tracker-pt/pt-settings.hpp
+++ b/tracker-pt/pt-settings.hpp
@@ -65,6 +65,8 @@ struct pt_settings final : options::opts
value<bool> auto_threshold { b, "automatic-threshold", true };
value<pt_color_type> blob_color { b, "blob-color", pt_color_bt709 };
value<bool> use_mjpeg { b, "use-mjpeg", false };
+ value<slider_value> chroma_key_strength{ b, "chroma-key-strength", { 1.0, 0.5, 4. } };
+ value<bool> chroma_key_overexposed{ b, "chroma-key-overexposed", false };
value<slider_value> threshold_slider { b, "threshold-slider", { 128, 0, 255 } };