summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2021-09-25 13:52:02 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-03-29 00:04:47 +0200
commit75c76a673253b6bb780b2fe1a8719bff9e32827d (patch)
tree0655f966dad0b993e1226740358af161c6e61777
parentcefacef8befa30050a27f008ec57cb7764af1c1d (diff)
tracker/trackhat: initial revision
-rw-r--r--installer/trackhat-file-list.txt64
-rw-r--r--sdk-paths-sthalik@MSVC-windows.cmake1
-rw-r--r--tracker-trackhat/CMakeLists.txt14
-rw-r--r--tracker-trackhat/camera.cpp129
-rw-r--r--tracker-trackhat/extractor.cpp26
-rw-r--r--tracker-trackhat/frame.cpp84
-rw-r--r--tracker-trackhat/images/trackhat-64x64.pngbin0 -> 1430 bytes
-rw-r--r--tracker-trackhat/images/trackhat.icobin0 -> 3758 bytes
-rw-r--r--tracker-trackhat/images/trackhat.pngbin0 -> 14581 bytes
-rw-r--r--tracker-trackhat/lang/nl_NL.ts11
-rw-r--r--tracker-trackhat/lang/ru_RU.ts11
-rw-r--r--tracker-trackhat/lang/stub.ts11
-rw-r--r--tracker-trackhat/lang/zh_CN.ts11
-rw-r--r--tracker-trackhat/metadata.cpp41
-rw-r--r--tracker-trackhat/metadata.hpp29
-rw-r--r--tracker-trackhat/tracker_trackhat.qrc5
-rw-r--r--tracker-trackhat/trackhat.hpp89
17 files changed, 526 insertions, 0 deletions
diff --git a/installer/trackhat-file-list.txt b/installer/trackhat-file-list.txt
new file mode 100644
index 00000000..32102b78
--- /dev/null
+++ b/installer/trackhat-file-list.txt
@@ -0,0 +1,64 @@
+./cleye.config
+./doc
+./doc/3rdparty-notices
+./doc/3rdparty-notices/EIGEN-COPYING.txt
+./doc/3rdparty-notices/FACETRACKNOIR-COPYING.txt
+./doc/3rdparty-notices/NFAILCLIENT-CREDIT.txt
+./doc/3rdparty-notices/OPENCV-COPYING.txt
+./doc/3rdparty-notices/QT5-COPYING.txt
+./doc/3rdparty-notices/VJOYSTICK-COPYING.txt
+./doc/AUTHORS.md
+./doc/CONTRIBUTING.md
+./doc/OPENTRACK-LICENSING.txt
+./doc/README.md
+./doc/settings
+./doc/settings/facetracknoir supported games.csv
+./doc/WARRANTY.txt
+./i18n
+./i18n/nl_NL.qm
+./i18n/ru_RU.qm
+./i18n/stub.qm
+./i18n/zh_CN.qm
+./modules
+./modules/cleye.config
+./modules/freetrackclient.dll
+./modules/freetrackclient64.dll
+./modules/NPClient.dll
+./modules/NPClient64.dll
+./modules/opentrack-filter-accela.dll
+./modules/opentrack-filter-ewma.dll
+./modules/opentrack-filter-hamilton.dll
+./modules/opentrack-filter-kalman.dll
+./modules/opentrack-proto-fgfs.dll
+./modules/opentrack-proto-freetrack.dll
+./modules/opentrack-proto-fsuipc.dll
+./modules/opentrack-proto-simconnect.dll
+./modules/opentrack-proto-udp.dll
+./modules/opentrack-proto-vjoy.dll
+./modules/opentrack-proto-win32-mouse.dll
+./modules/opentrack-tracker-pt.dll
+./modules/opentrack-tracker-test.dll
+./modules/opentrack-tracker-trackhat.dll
+./modules/opentrack-tracker-udp.dll
+./modules/opentrack-video-opencv.dll
+./modules/opentrack-video-ps3eye.dll
+./modules/TrackIR.exe
+./modules/vJoyInterface.dll
+./opentrack-api.dll
+./opentrack-compat.dll
+./opentrack-dinput.dll
+./opentrack-logic.dll
+./opentrack-migration.dll
+./opentrack-options.dll
+./opentrack-pose-widget.dll
+./opentrack-spline.dll
+./opentrack-user-interface.dll
+./opentrack-video.dll
+./opentrack.exe
+./platforms
+./platforms/qwindows.dll
+./qt.conf
+./Qt5Core.dll
+./Qt5Gui.dll
+./Qt5Network.dll
+./Qt5Widgets.dll
diff --git a/sdk-paths-sthalik@MSVC-windows.cmake b/sdk-paths-sthalik@MSVC-windows.cmake
index db6e8b35..8e5b3fc3 100644
--- a/sdk-paths-sthalik@MSVC-windows.cmake
+++ b/sdk-paths-sthalik@MSVC-windows.cmake
@@ -36,6 +36,7 @@ setq(SDK_VJOYSTICK "vjoystick")
setq(ONNXRuntime_INCLUDE_DIR "onnxruntime-1.10.0//include")
setq(ONNXRuntime_LIBRARY "onnxruntime-1.10.0/lib/onnxruntime.lib")
setq(ONNXRuntime_RUNTIME "onnxruntime-1.10.0/lib/onnxruntime.dll")
+setq(SDK_TRACKHAT_SENSOR "../trackhat/trackhat-c-library-driver/build/install")
setq(Qt5_DIR "../qt-5.15.0kde0/lib/cmake/Qt5")
set(Qt5Core_DIR "${Qt5_DIR}Core" CACHE PATH "" FORCE)
diff --git a/tracker-trackhat/CMakeLists.txt b/tracker-trackhat/CMakeLists.txt
new file mode 100644
index 00000000..12df71fc
--- /dev/null
+++ b/tracker-trackhat/CMakeLists.txt
@@ -0,0 +1,14 @@
+if(WIN32)
+ include(opentrack-opencv)
+ find_package(OpenCV QUIET)
+ if(OpenCV_FOUND)
+ set(SDK_TRACKHAT_SENSOR CACHE PATH "")
+ if(SDK_TRACKHAT_SENSOR)
+ include_directories("${SDK_TRACKHAT_SENSOR}/include" ${OpenCV_INCLUDE_DIRS})
+ link_directories("${SDK_TRACKHAT_SENSOR}/lib")
+ link_libraries(${self} opencv_imgproc opencv_core opentrack-tracker-pt-base track-hat)
+
+ otr_module(tracker-trackhat)
+ endif()
+ endif()
+endif()
diff --git a/tracker-trackhat/camera.cpp b/tracker-trackhat/camera.cpp
new file mode 100644
index 00000000..19a8d6ca
--- /dev/null
+++ b/tracker-trackhat/camera.cpp
@@ -0,0 +1,129 @@
+#include "trackhat.hpp"
+#include <QDebug>
+
+pt_camera::result trackhat_camera::get_info() const
+{
+ return {true, get_desired() };
+}
+
+pt_camera_info trackhat_camera::get_desired() const
+{
+ pt_camera_info ret = {};
+
+ ret.fov = sensor_fov;
+ ret.fps = 250;
+ ret.res_x = sensor_size;
+ ret.res_y = sensor_size;
+
+ return ret;
+}
+
+QString trackhat_camera::get_desired_name() const
+{
+ return QStringLiteral("TrackHat sensor");
+}
+
+QString trackhat_camera::get_active_name() const
+{
+ return get_desired_name();
+}
+
+void trackhat_camera::set_fov(pt_camera::f) {}
+void trackhat_camera::show_camera_settings() {}
+
+trackhat_camera::trackhat_camera() = default;
+
+trackhat_camera::~trackhat_camera()
+{
+ stop();
+}
+
+pt_camera::result trackhat_camera::get_frame(pt_frame& frame_)
+{
+ auto& ret = *frame_.as<trackhat_frame>();
+ trackhat_frame frame;
+
+ if (status < th_running || error_code != TH_SUCCESS)
+ {
+ if (status >= th_running)
+ qDebug() << "trackhat: disconnected, status" << (void*)error_code;
+ goto error;
+ }
+
+ if (TH_ErrorCode error = trackHat_GetDetectedPoints(&device, &frame.points); error != TH_SUCCESS)
+ {
+ error_code = error;
+ goto error;
+ }
+
+ ret.points = frame.points;
+ return {true, get_desired()};
+
+error:
+ if (error_code != TH_SUCCESS)
+ qDebug() << "trackhat: error" << (void*)error_code;
+ ret.points = {};
+ stop();
+ return {false, get_desired()};
+}
+
+#define CHECK(x) \
+ do { \
+ if (TH_ErrorCode status_ = (x); status_ != TH_SUCCESS) \
+ { \
+ qDebug() << "trackhat: error" \
+ << (void*)status_ << "in" << #x; \
+ error_code = status_; \
+ goto error; \
+ } \
+ } while (false)
+
+bool trackhat_camera::start(const pt_settings&)
+{
+ stop();
+ trackHat_EnableDebugMode();
+
+ [[maybe_unused]] uint32_t uptime = 0;
+ error_code = TH_SUCCESS;
+ status = th_noinit;
+
+ CHECK(trackHat_Initialize(&device)); status = th_init;
+ CHECK(trackHat_DetectDevice(&device)); status = th_detect;
+ CHECK(trackHat_Connect(&device)); status = th_connect;
+ CHECK(trackHat_GetUptime(&device, &uptime)); status = th_running;
+
+#if 0
+ qDebug() << "trackhat start: device uptime" << uptime << "seconds";
+#endif
+
+ return true;
+error:
+ stop();
+ return false;
+}
+
+void trackhat_camera::stop()
+{
+#if 0
+ if (status >= th_connect)
+ {
+ uint32_t uptime = 0;
+ if (TH_ErrorCode status = trackHat_GetUptime(&device, &uptime); status == TH_SUCCESS)
+ qDebug() << "trackhat stop: device uptime" << uptime << "seconds";
+ }
+#endif
+
+ if (status >= th_connect)
+ (void)trackHat_Disconnect(&device);
+ if (status >= th_init)
+ (void)trackHat_Deinitialize(&device);
+
+ status = th_noinit;
+ device = {};
+}
+
+trackhat_preview::trackhat_preview(int w, int h)
+{
+ frame_bgr.create(h, w, CV_8UC3);
+ frame_bgra.create(h, w, CV_8UC4);
+}
diff --git a/tracker-trackhat/extractor.cpp b/tracker-trackhat/extractor.cpp
new file mode 100644
index 00000000..5e50b4b4
--- /dev/null
+++ b/tracker-trackhat/extractor.cpp
@@ -0,0 +1,26 @@
+#include "trackhat.hpp"
+#include <algorithm>
+#include <iterator>
+
+void trackhat_extractor::extract_points(const pt_frame& data,
+ pt_preview&, bool,
+ std::vector<vec2>& points)
+{
+ points.clear();
+ points.reserve(trackhat_camera::point_count);
+ trackHat_Points_t copy = data.as_const<trackhat_frame>()->points;
+
+ std::sort(std::begin(copy.m_point), std::end(copy.m_point),
+ [](trackHat_Point_t p1, trackHat_Point_t p2) {
+ return p1.m_brightness > p2.m_brightness;
+ });
+
+ for (const auto& pt : copy.m_point)
+ {
+ if (pt.m_brightness == 0)
+ continue;
+ constexpr int sz = trackhat_camera::sensor_size;
+ auto [ x, y ] = to_screen_pos(pt.m_x, pt.m_y, sz, sz);
+ points.push_back({x, y});
+ }
+}
diff --git a/tracker-trackhat/frame.cpp b/tracker-trackhat/frame.cpp
new file mode 100644
index 00000000..d9913776
--- /dev/null
+++ b/tracker-trackhat/frame.cpp
@@ -0,0 +1,84 @@
+#include "trackhat.hpp"
+#include <opencv2/imgproc.hpp>
+#include "compat/math.hpp"
+
+void trackhat_preview::set_last_frame(const pt_frame& frame_)
+{
+ center = {-1, -1};
+ points = frame_.as_const<trackhat_frame>()->points;
+}
+
+void trackhat_preview::draw_head_center(pt_pixel_pos_mixin::f x, pt_pixel_pos_mixin::f y)
+{
+ center = {x, y};
+}
+
+QImage trackhat_preview::get_bitmap()
+{
+ frame_bgr.setTo({0});
+
+ draw_points();
+ draw_center();
+
+ cv::cvtColor(frame_bgr, frame_bgra, cv::COLOR_BGR2BGRA);
+
+ return QImage((const unsigned char*) frame_bgra.data,
+ frame_bgra.cols, frame_bgra.rows,
+ (int)frame_bgra.step.p[0],
+ QImage::Format_ARGB32);
+}
+
+void trackhat_preview::draw_center()
+{
+ if (center == numeric_types::vec2(-1, -1))
+ return;
+
+ auto [px_, py_] = to_pixel_pos(center[0], center[1], frame_bgr.cols, frame_bgr.rows);
+ int px = iround(px_), py = iround(py_);
+
+ const f dpi = (f)frame_bgr.cols / f(320);
+ constexpr int len_ = 9;
+ int len = iround(len_ * dpi);
+
+ static const cv::Scalar color(0, 255, 255);
+ cv::line(frame_bgr,
+ cv::Point(px - len, py),
+ cv::Point(px + len, py),
+ color, 1);
+ cv::line(frame_bgr,
+ cv::Point(px, py - len),
+ cv::Point(px, py + len),
+ color, 1);
+}
+
+void trackhat_preview::draw_points()
+{
+ for (unsigned i = 0; i < std::size(points.m_point); i++)
+ {
+ const auto pt = points.m_point[i];
+
+ if (pt.m_brightness == 0)
+ continue;
+
+ constexpr f sz = trackhat_camera::sensor_size;
+ f x = std::clamp((f)pt.m_x, f(0), sz-1) * (f)frame_bgr.cols / sz,
+ y = std::clamp((f)pt.m_y, f(0), sz-1) * (f)frame_bgr.rows / sz;
+
+ const f dpi = (f)frame_bgr.cols / f(320);
+ int c = (int)pt.m_brightness;
+ constexpr int point_size = 6;
+ auto outline_color = i < 3 ? cv::Scalar{255, 255, 0} : cv::Scalar{192, 192, 192};
+
+ cv::circle(frame_bgr,
+ {iround(x*dpi), iround(y*dpi)},
+ iround(point_size * dpi),
+ outline_color,
+ iround(dpi), cv::LINE_AA);
+
+ cv::circle(frame_bgr,
+ {iround(x*dpi), iround(y*dpi)},
+ iround((point_size-2) * dpi),
+ cv::Scalar(c, c, c),
+ -1);
+ }
+}
diff --git a/tracker-trackhat/images/trackhat-64x64.png b/tracker-trackhat/images/trackhat-64x64.png
new file mode 100644
index 00000000..9e856c23
--- /dev/null
+++ b/tracker-trackhat/images/trackhat-64x64.png
Binary files differ
diff --git a/tracker-trackhat/images/trackhat.ico b/tracker-trackhat/images/trackhat.ico
new file mode 100644
index 00000000..b5f34db3
--- /dev/null
+++ b/tracker-trackhat/images/trackhat.ico
Binary files differ
diff --git a/tracker-trackhat/images/trackhat.png b/tracker-trackhat/images/trackhat.png
new file mode 100644
index 00000000..4f17de81
--- /dev/null
+++ b/tracker-trackhat/images/trackhat.png
Binary files differ
diff --git a/tracker-trackhat/lang/nl_NL.ts b/tracker-trackhat/lang/nl_NL.ts
new file mode 100644
index 00000000..6dc81cfc
--- /dev/null
+++ b/tracker-trackhat/lang/nl_NL.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>trackhat_module</name>
+ <message>
+ <source>TrackHat Point Tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tracker-trackhat/lang/ru_RU.ts b/tracker-trackhat/lang/ru_RU.ts
new file mode 100644
index 00000000..6dc81cfc
--- /dev/null
+++ b/tracker-trackhat/lang/ru_RU.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>trackhat_module</name>
+ <message>
+ <source>TrackHat Point Tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tracker-trackhat/lang/stub.ts b/tracker-trackhat/lang/stub.ts
new file mode 100644
index 00000000..6dc81cfc
--- /dev/null
+++ b/tracker-trackhat/lang/stub.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>trackhat_module</name>
+ <message>
+ <source>TrackHat Point Tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tracker-trackhat/lang/zh_CN.ts b/tracker-trackhat/lang/zh_CN.ts
new file mode 100644
index 00000000..6dc81cfc
--- /dev/null
+++ b/tracker-trackhat/lang/zh_CN.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>trackhat_module</name>
+ <message>
+ <source>TrackHat Point Tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tracker-trackhat/metadata.cpp b/tracker-trackhat/metadata.cpp
new file mode 100644
index 00000000..4145384e
--- /dev/null
+++ b/tracker-trackhat/metadata.cpp
@@ -0,0 +1,41 @@
+#include "metadata.hpp"
+#include "api/plugin-api.hpp"
+
+// XXX TODO
+static const QString bundle_name = QStringLiteral("tracker-pt");
+
+pt_runtime_traits::pointer<pt_camera> trackhat_metadata::make_camera() const
+{
+ return std::make_shared<trackhat_camera>();
+}
+
+pt_runtime_traits::pointer<pt_point_extractor> trackhat_metadata::make_point_extractor() const
+{
+ return std::make_shared<trackhat_extractor>();
+}
+
+pt_runtime_traits::pointer<pt_frame> trackhat_metadata::make_frame() const
+{
+ return std::make_shared<trackhat_frame>();
+}
+
+pt_runtime_traits::pointer<pt_preview> trackhat_metadata::make_preview(int w, int h) const
+{
+ return std::make_shared<trackhat_preview>(w, h);
+}
+
+QString trackhat_metadata::get_module_name() const
+{
+ return bundle_name;
+}
+
+trackhat_pt::trackhat_pt() :
+ Tracker_PT(pt_runtime_traits::pointer<pt_runtime_traits>(new trackhat_metadata))
+{
+}
+
+trackhat_pt_dialog::trackhat_pt_dialog() : TrackerDialog_PT(bundle_name)
+{
+}
+
+OPENTRACK_DECLARE_TRACKER(trackhat_pt, trackhat_pt_dialog, trackhat_module)
diff --git a/tracker-trackhat/metadata.hpp b/tracker-trackhat/metadata.hpp
new file mode 100644
index 00000000..9bbd8617
--- /dev/null
+++ b/tracker-trackhat/metadata.hpp
@@ -0,0 +1,29 @@
+#pragma once
+#include "trackhat.hpp"
+#include "../tracker-pt/ftnoir_tracker_pt.h"
+#include "../tracker-pt/ftnoir_tracker_pt_dialog.h"
+
+class trackhat_pt final : public Tracker_PT
+{
+ Q_OBJECT
+
+public:
+ trackhat_pt();
+};
+
+class trackhat_pt_dialog final : public TrackerDialog_PT
+{
+ Q_OBJECT
+
+public:
+ trackhat_pt_dialog();
+};
+
+class trackhat_module final : public Metadata
+{
+ Q_OBJECT
+
+public:
+ QString name() override { return tr("TrackHat Point Tracker"); }
+ QIcon icon() override { return QIcon(":/images/trackhat-64x64.png"); }
+};
diff --git a/tracker-trackhat/tracker_trackhat.qrc b/tracker-trackhat/tracker_trackhat.qrc
new file mode 100644
index 00000000..d54010a0
--- /dev/null
+++ b/tracker-trackhat/tracker_trackhat.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/trackhat-64x64.png</file>
+ </qresource>
+</RCC>
diff --git a/tracker-trackhat/trackhat.hpp b/tracker-trackhat/trackhat.hpp
new file mode 100644
index 00000000..eaf0e2df
--- /dev/null
+++ b/tracker-trackhat/trackhat.hpp
@@ -0,0 +1,89 @@
+#pragma once
+
+#include "../tracker-pt/pt-api.hpp"
+#include "track_hat_driver.h"
+#include "compat/macros.hpp"
+
+#include <opencv2/core.hpp>
+
+struct trackhat_camera final : pt_camera
+{
+ trackhat_camera();
+ ~trackhat_camera() override;
+
+ OTR_DISABLE_MOVE_COPY(trackhat_camera);
+
+ bool start(const pt_settings& s) override;
+ void stop() override;
+
+ pt_camera::result get_frame(pt_frame& frame) override;
+ pt_camera::result get_info() const override;
+ pt_camera_info get_desired() const override;
+
+ QString get_desired_name() const override;
+ QString get_active_name() const override;
+
+ void set_fov(f value) override;
+ void show_camera_settings() override;
+
+ static constexpr int sensor_size = 2940*2;
+ static constexpr int sensor_fov = 52;
+ static constexpr int point_count = TRACK_HAT_NUMBER_OF_POINTS;
+
+private:
+ enum device_status { th_noinit, th_init, th_detect, th_connect, th_running, };
+
+ trackHat_Device_t device {};
+ device_status status = th_noinit;
+ TH_ErrorCode error_code = TH_SUCCESS;
+};
+
+struct trackhat_frame final : pt_frame
+{
+ trackHat_Points_t points = {};
+
+ trackhat_frame() = default;
+ ~trackhat_frame() override = default;
+};
+
+struct trackhat_preview final : pt_preview
+{
+ QImage get_bitmap() override;
+ void draw_head_center(f x, f y) override;
+ void set_last_frame(const pt_frame&) override; // NOLINT(misc-unconventional-assign-operator)
+
+ trackhat_preview(int w, int h);
+ ~trackhat_preview() override = default;
+ void draw_points();
+ void draw_center();
+
+ OTR_DISABLE_MOVE_COPY(trackhat_preview);
+
+ cv::Mat frame_bgr, frame_bgra;
+ numeric_types::vec2 center{-1, -1};
+ trackHat_Points_t points = {};
+};
+
+struct trackhat_extractor final : pt_point_extractor
+{
+ void extract_points(const pt_frame& data, pt_preview&, bool, std::vector<vec2>& points) override;
+
+ OTR_DISABLE_MOVE_COPY(trackhat_extractor);
+
+ trackhat_extractor() = default;
+ ~trackhat_extractor() override = default;
+};
+
+struct trackhat_metadata final : pt_runtime_traits
+{
+ pt_runtime_traits::pointer<pt_camera> make_camera() const override;
+ pt_runtime_traits::pointer<pt_point_extractor> make_point_extractor() const override;
+ pt_runtime_traits::pointer<pt_frame> make_frame() const override;
+ pt_runtime_traits::pointer<pt_preview> make_preview(int w, int h) const override;
+ QString get_module_name() const override;
+
+ OTR_DISABLE_MOVE_COPY(trackhat_metadata);
+
+ trackhat_metadata() = default;
+ ~trackhat_metadata() override = default;
+};