diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2021-09-25 13:52:02 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-03-29 00:04:47 +0200 |
commit | 75c76a673253b6bb780b2fe1a8719bff9e32827d (patch) | |
tree | 0655f966dad0b993e1226740358af161c6e61777 | |
parent | cefacef8befa30050a27f008ec57cb7764af1c1d (diff) |
tracker/trackhat: initial revision
-rw-r--r-- | installer/trackhat-file-list.txt | 64 | ||||
-rw-r--r-- | sdk-paths-sthalik@MSVC-windows.cmake | 1 | ||||
-rw-r--r-- | tracker-trackhat/CMakeLists.txt | 14 | ||||
-rw-r--r-- | tracker-trackhat/camera.cpp | 129 | ||||
-rw-r--r-- | tracker-trackhat/extractor.cpp | 26 | ||||
-rw-r--r-- | tracker-trackhat/frame.cpp | 84 | ||||
-rw-r--r-- | tracker-trackhat/images/trackhat-64x64.png | bin | 0 -> 1430 bytes | |||
-rw-r--r-- | tracker-trackhat/images/trackhat.ico | bin | 0 -> 3758 bytes | |||
-rw-r--r-- | tracker-trackhat/images/trackhat.png | bin | 0 -> 14581 bytes | |||
-rw-r--r-- | tracker-trackhat/lang/nl_NL.ts | 11 | ||||
-rw-r--r-- | tracker-trackhat/lang/ru_RU.ts | 11 | ||||
-rw-r--r-- | tracker-trackhat/lang/stub.ts | 11 | ||||
-rw-r--r-- | tracker-trackhat/lang/zh_CN.ts | 11 | ||||
-rw-r--r-- | tracker-trackhat/metadata.cpp | 41 | ||||
-rw-r--r-- | tracker-trackhat/metadata.hpp | 29 | ||||
-rw-r--r-- | tracker-trackhat/tracker_trackhat.qrc | 5 | ||||
-rw-r--r-- | tracker-trackhat/trackhat.hpp | 89 |
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 Binary files differnew file mode 100644 index 00000000..9e856c23 --- /dev/null +++ b/tracker-trackhat/images/trackhat-64x64.png diff --git a/tracker-trackhat/images/trackhat.ico b/tracker-trackhat/images/trackhat.ico Binary files differnew file mode 100644 index 00000000..b5f34db3 --- /dev/null +++ b/tracker-trackhat/images/trackhat.ico diff --git a/tracker-trackhat/images/trackhat.png b/tracker-trackhat/images/trackhat.png Binary files differnew file mode 100644 index 00000000..4f17de81 --- /dev/null +++ b/tracker-trackhat/images/trackhat.png 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; +}; |