summaryrefslogtreecommitdiffhomepage
path: root/tracker-wii
diff options
context:
space:
mode:
authorWei Shuai <cpuwolf@gmail.com>2018-01-26 22:02:07 +0800
committerWei Shuai <cpuwolf@gmail.com>2018-01-26 22:02:07 +0800
commit4a2a1b636df7a67722b6b5764efa8cfc63c6a5e1 (patch)
treebd375c924fa72f9eb3ce1d78356785077836f3c1 /tracker-wii
parentd057e5db1c9ca81d5f60b9cd8001f60dd155f145 (diff)
tracker/wii: new home
Diffstat (limited to 'tracker-wii')
-rw-r--r--tracker-wii/CMakeLists.txt6
-rw-r--r--tracker-wii/Resources/wii.icobin0 -> 10134 bytes
-rw-r--r--tracker-wii/Resources/wii.pngbin0 -> 2974 bytes
-rw-r--r--tracker-wii/lang/nl_NL.ts4
-rw-r--r--tracker-wii/lang/ru_RU.ts4
-rw-r--r--tracker-wii/lang/stub.ts4
-rw-r--r--tracker-wii/tracker_wii.qrc5
-rw-r--r--tracker-wii/wii_camera.cpp225
-rw-r--r--tracker-wii/wii_camera.h74
-rw-r--r--tracker-wii/wii_frame.cpp91
-rw-r--r--tracker-wii/wii_frame.hpp64
-rw-r--r--tracker-wii/wii_module.cpp83
-rw-r--r--tracker-wii/wii_point_extractor.cpp143
-rw-r--r--tracker-wii/wii_point_extractor.h38
14 files changed, 741 insertions, 0 deletions
diff --git a/tracker-wii/CMakeLists.txt b/tracker-wii/CMakeLists.txt
new file mode 100644
index 00000000..cab5b6a1
--- /dev/null
+++ b/tracker-wii/CMakeLists.txt
@@ -0,0 +1,6 @@
+find_package(OpenCV 3.0 QUIET)
+if(OpenCV_FOUND)
+ otr_module(tracker-wii)
+ target_link_libraries(opentrack-tracker-wii opentrack-tracker-pt-base opentrack-wiiyourself)
+ target_include_directories(opentrack-tracker-wii PRIVATE "${CMAKE_SOURCE_DIR}/tracker-pt")
+endif() \ No newline at end of file
diff --git a/tracker-wii/Resources/wii.ico b/tracker-wii/Resources/wii.ico
new file mode 100644
index 00000000..44204a68
--- /dev/null
+++ b/tracker-wii/Resources/wii.ico
Binary files differ
diff --git a/tracker-wii/Resources/wii.png b/tracker-wii/Resources/wii.png
new file mode 100644
index 00000000..d83b6e77
--- /dev/null
+++ b/tracker-wii/Resources/wii.png
Binary files differ
diff --git a/tracker-wii/lang/nl_NL.ts b/tracker-wii/lang/nl_NL.ts
new file mode 100644
index 00000000..9e739505
--- /dev/null
+++ b/tracker-wii/lang/nl_NL.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="nl_NL">
+</TS>
diff --git a/tracker-wii/lang/ru_RU.ts b/tracker-wii/lang/ru_RU.ts
new file mode 100644
index 00000000..f62cf2e1
--- /dev/null
+++ b/tracker-wii/lang/ru_RU.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru_RU">
+</TS>
diff --git a/tracker-wii/lang/stub.ts b/tracker-wii/lang/stub.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/tracker-wii/lang/stub.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/tracker-wii/tracker_wii.qrc b/tracker-wii/tracker_wii.qrc
new file mode 100644
index 00000000..a7a50512
--- /dev/null
+++ b/tracker-wii/tracker_wii.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>Resources/wii.png</file>
+ </qresource>
+</RCC>
diff --git a/tracker-wii/wii_camera.cpp b/tracker-wii/wii_camera.cpp
new file mode 100644
index 00000000..75ce3950
--- /dev/null
+++ b/tracker-wii/wii_camera.cpp
@@ -0,0 +1,225 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* 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 "wii_camera.h"
+#include "wii_frame.hpp"
+
+#include "compat/sleep.hpp"
+#include "compat/camera-names.hpp"
+#include "compat/math-imports.hpp"
+
+#include <opencv2/imgproc.hpp>
+
+#include "cv/video-property-page.hpp"
+
+
+using namespace pt_module;
+
+WIICamera::WIICamera(const QString& module_name) : s { module_name }
+{
+ cam_info.fps = 70;
+ cam_info.res_x = 1024;
+ cam_info.res_y = 768;
+ cam_info.fov = 42.0f;
+ cam_info.idx = 0;
+}
+
+QString WIICamera::get_desired_name() const
+{
+ return desired_name;
+}
+
+QString WIICamera::get_active_name() const
+{
+ return active_name;
+}
+
+void WIICamera::show_camera_settings()
+{
+
+}
+
+WIICamera::result WIICamera::get_info() const
+{
+ if (cam_info.res_x == 0 || cam_info.res_y == 0)
+ return result(false, pt_camera_info());
+ return result(true, cam_info);
+}
+
+WIICamera::result WIICamera::get_frame(pt_frame& frame_)
+{
+ cv::Mat& frame = frame_.as<WIIFrame>()->mat;
+ struct wii_info& wii = frame_.as<WIIFrame>()->wii;
+
+ const wii_camera_status new_frame = _get_frame(frame);
+ //create a fake blank frame
+ frame = cv::Mat(cam_info.res_x, cam_info.res_y, CV_8UC3, cv::Scalar(0, 0, 0));
+ wii.status = new_frame;
+
+ switch (new_frame)
+ {
+ case wii_cam_data_change:
+ _get_status(wii);
+ _get_points(wii);
+ break;
+ case wii_cam_data_no_change:
+ return result(false, cam_info);
+ }
+
+ return result(true, cam_info);
+}
+
+pt_camera_open_status WIICamera::start(int idx, int fps, int res_x, int res_y)
+{
+ m_pDev = std::make_unique<wiimote>();
+ m_pDev->ChangedCallback = on_state_change;
+ m_pDev->CallbackTriggerFlags = (state_change_flags)(CONNECTED |
+ EXTENSION_CHANGED |
+ MOTIONPLUS_CHANGED);
+ return cam_open_ok_no_change;
+}
+
+void WIICamera::stop()
+{
+ onExit = true;
+ m_pDev->ChangedCallback = NULL;
+ m_pDev->Disconnect();
+ Beep(1000, 200);
+ if (m_pDev) {
+ m_pDev=nullptr;
+ m_pDev = NULL;
+ }
+
+ desired_name = QString();
+ active_name = QString();
+ cam_info = pt_camera_info();
+ cam_desired = pt_camera_info();
+}
+
+wii_camera_status WIICamera::_get_frame(cv::Mat& frame)
+{
+ wii_camera_status ret = wii_cam_wait_for_connect;
+
+ if (!m_pDev->IsConnected()) {
+ qDebug() << "wii wait";
+ if (!m_pDev->Connect(wiimote::FIRST_AVAILABLE)) {
+ Beep(500, 30); Sleep(1000);
+ goto goodbye;
+ }
+ }
+
+ if (m_pDev->RefreshState() == NO_CHANGE) {
+ Sleep(1); // don't hog the CPU if nothing changed
+ ret = wii_cam_data_no_change;
+ goto goodbye;
+ }
+
+ // did we loose the connection?
+ if (m_pDev->ConnectionLost())
+ {
+ goto goodbye;
+ }
+
+ ret = wii_cam_data_change;
+goodbye:
+ return ret;
+}
+
+bool WIICamera::_get_points(struct wii_info& wii)
+{
+ bool dot_sizes = (m_pDev->IR.Mode == wiimote_state::ir::EXTENDED);
+ bool ret = false;
+ int point_count = 0;
+
+ for (unsigned index = 0; index < 4; index++)
+ {
+ wiimote_state::ir::dot &dot = m_pDev->IR.Dot[index];
+ if (dot.bVisible) {
+ wii.Points[index].ux = dot.RawX;
+ wii.Points[index].uy = dot.RawY;
+ if (dot_sizes) {
+ wii.Points[index].isize = dot.Size;
+ } else {
+ wii.Points[index].isize = 1;
+ }
+ wii.Points[index].bvis = dot.bVisible;
+ point_count++;
+ ret = true;
+ } else {
+ wii.Points[index].ux = 0;
+ wii.Points[index].uy = 0;
+ wii.Points[index].isize = 0;
+ wii.Points[index].bvis = dot.bVisible;
+ }
+ }
+ m_pDev->SetLEDs(3 - point_count);
+ return ret;
+}
+
+void WIICamera::_get_status(struct wii_info& wii)
+{
+ //draw battery status
+ wii.BatteryPercent = m_pDev->BatteryPercent;
+ wii.bBatteryDrained = m_pDev->bBatteryDrained;
+
+ //draw horizon
+ static int p = 0;
+ static int r = 0;
+ if (m_pDev->Nunchuk.Acceleration.Orientation.UpdateAge < 10)
+ {
+ p = m_pDev->Acceleration.Orientation.Pitch;
+ r = m_pDev->Acceleration.Orientation.Roll;
+ }
+
+ wii.Pitch = p;
+ wii.Roll = r;
+}
+
+void WIICamera::on_state_change(wiimote &remote,
+ state_change_flags changed,
+ const wiimote_state &new_state)
+{
+ // the wiimote just connected
+ if (changed & CONNECTED)
+ {
+ /* wiimote connected */
+ remote.SetLEDs(0x0f);
+ Beep(1000, 300); Sleep(500);
+
+ qDebug() << "wii connected";
+
+ if (new_state.ExtensionType != wiimote::BALANCE_BOARD)
+ {
+ if (new_state.bExtension)
+ remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR_EXT); // no IR dots
+ else
+ remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR); // IR dots
+ }
+ }
+ // another extension was just connected:
+ else if (changed & EXTENSION_CONNECTED)
+ {
+
+ Beep(1000, 200);
+
+ // switch to a report mode that includes the extension data (we will
+ // loose the IR dot sizes)
+ // note: there is no need to set report types for a Balance Board.
+ if (!remote.IsBalanceBoard())
+ remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR_EXT);
+ }
+ else if (changed & EXTENSION_DISCONNECTED)
+ {
+
+ Beep(200, 300);
+
+ // use a non-extension report mode (this gives us back the IR dot sizes)
+ remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR);
+ }
+}
diff --git a/tracker-wii/wii_camera.h b/tracker-wii/wii_camera.h
new file mode 100644
index 00000000..7bd4a7ae
--- /dev/null
+++ b/tracker-wii/wii_camera.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#pragma once
+
+#include "pt-api.hpp"
+
+#include "compat/timer.hpp"
+
+#include <functional>
+#include <memory>
+#include <tuple>
+
+#include <opencv2/core.hpp>
+#include <opencv2/videoio.hpp>
+
+#include <QString>
+
+#include <wiiyourself/wiimote.h>
+#include "wii_frame.hpp"
+
+namespace pt_module {
+
+struct WIICamera final : pt_camera
+{
+ WIICamera(const QString& module_name);
+
+ pt_camera_open_status start(int idx, int fps, int res_x, int res_y) override;
+ void stop() override;
+
+ result get_frame(pt_frame& Frame) override;
+ result get_info() const override;
+
+ pt_camera_info get_desired() const override { return cam_desired; }
+ QString get_desired_name() const override;
+ QString get_active_name() const override;
+
+ operator bool() const override { return m_pDev && (!m_pDev->ConnectionLost()); }
+
+ void set_fov(double value) override {}
+ void show_camera_settings() override;
+
+
+private:
+ std::unique_ptr<wiimote> m_pDev;
+ static void on_state_change(wiimote &remote,
+ state_change_flags changed,
+ const wiimote_state &new_state);
+ bool onExit = false;
+ pt_frame internalframe;
+
+ wii_camera_status _get_frame(cv::Mat& Frame);
+ bool _get_points(struct wii_info&);
+ void _get_status(struct wii_info&);
+
+ double dt_mean = 0;
+
+ Timer t;
+
+ pt_camera_info cam_info;
+ pt_camera_info cam_desired;
+ QString desired_name, active_name;
+
+ pt_settings s;
+
+ static constexpr inline double dt_eps = 1./384;
+};
+
+} // ns pt_module
diff --git a/tracker-wii/wii_frame.cpp b/tracker-wii/wii_frame.cpp
new file mode 100644
index 00000000..9e367926
--- /dev/null
+++ b/tracker-wii/wii_frame.cpp
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* 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 "wii_frame.hpp"
+
+#include "compat/math.hpp"
+
+#include <cstring>
+#include <tuple>
+
+#include <opencv2/imgproc.hpp>
+
+using namespace pt_module;
+
+WIIPreview& WIIPreview::operator=(const pt_frame& frame_)
+{
+ const cv::Mat& frame = frame_.as_const<const WIIFrame>()->mat;
+ ensure_size(frame_copy, frame_out.cols, frame_out.rows, CV_8UC3);
+
+ if (frame.channels() != 3)
+ {
+ once_only(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels());
+ return *this;
+ }
+
+ const bool need_resize = frame.cols != frame_out.cols || frame.rows != frame_out.rows;
+ if (need_resize)
+ cv::resize(frame, frame_copy, cv::Size(frame_out.cols, frame_out.rows), 0, 0, cv::INTER_NEAREST);
+ else
+ frame.copyTo(frame_copy);
+
+ return *this;
+}
+
+WIIPreview::WIIPreview(int w, int h)
+{
+ ensure_size(frame_out, w, h, CV_8UC4);
+
+ frame_out.setTo(cv::Scalar(0, 0, 0, 0));
+}
+
+QImage WIIPreview::get_bitmap()
+{
+ int stride = frame_out.step.p[0];
+
+ if (stride < 64 || stride < frame_out.cols * 4)
+ {
+ once_only(qDebug() << "bad stride" << stride
+ << "for bitmap size" << frame_copy.cols << frame_copy.rows);
+ return QImage();
+ }
+
+ cv::cvtColor(frame_copy, frame_out, cv::COLOR_BGR2BGRA);
+
+ return QImage((const unsigned char*) frame_out.data,
+ frame_out.cols, frame_out.rows,
+ stride,
+ QImage::Format_ARGB32);
+}
+
+void WIIPreview::draw_head_center(double x, double y)
+{
+ double px_, py_;
+
+ std::tie(px_, py_) = to_pixel_pos(x, y, frame_copy.cols, frame_copy.rows);
+
+ int px = iround(px_), py = iround(py_);
+
+ constexpr int len = 9;
+
+ static const cv::Scalar color(0, 255, 255);
+ cv::line(frame_copy,
+ cv::Point(px - len, py),
+ cv::Point(px + len, py),
+ color, 1);
+ cv::line(frame_copy,
+ cv::Point(px, py - len),
+ cv::Point(px, py + len),
+ color, 1);
+}
+
+void WIIPreview::ensure_size(cv::Mat& frame, int w, int h, int type)
+{
+ if (frame.cols != w || frame.rows != h)
+ frame = cv::Mat(h, w, type);
+}
diff --git a/tracker-wii/wii_frame.hpp b/tracker-wii/wii_frame.hpp
new file mode 100644
index 00000000..2bffa862
--- /dev/null
+++ b/tracker-wii/wii_frame.hpp
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*/
+#pragma once
+
+#include "pt-api.hpp"
+
+#include <opencv2/core.hpp>
+#include <QImage>
+
+
+
+namespace pt_module {
+
+enum wii_camera_status : unsigned { wii_cam_wait_for_connect, wii_cam_data_no_change, wii_cam_data_change };
+
+struct wii_info_points {
+ unsigned ux;
+ unsigned uy;
+ int isize;
+ bool bvis;
+};
+
+struct wii_info {
+ struct wii_info_points Points[4];
+ bool bBatteryDrained;
+ unsigned char BatteryPercent;
+ float Pitch;
+ float Roll;
+ wii_camera_status status;
+};
+
+struct WIIFrame final : pt_frame
+{
+ cv::Mat mat;
+ struct wii_info wii;
+
+ operator const cv::Mat&() const& { return mat; }
+ operator cv::Mat&() & { return mat; }
+};
+
+struct WIIPreview final : pt_preview
+{
+ WIIPreview(int w, int h);
+
+ WIIPreview& operator=(const pt_frame& frame) override;
+ QImage get_bitmap() override;
+ void draw_head_center(double x, double y) override;
+
+ operator cv::Mat&() { return frame_copy; }
+ operator cv::Mat const&() const { return frame_copy; }
+
+private:
+ static void ensure_size(cv::Mat& frame, int w, int h, int type);
+
+ bool fresh = true;
+ cv::Mat frame_copy, frame_color, frame_resize, frame_out;
+};
+
+} // ns pt_module
diff --git a/tracker-wii/wii_module.cpp b/tracker-wii/wii_module.cpp
new file mode 100644
index 00000000..40131f69
--- /dev/null
+++ b/tracker-wii/wii_module.cpp
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*/
+#include "ftnoir_tracker_pt.h"
+#include "api/plugin-api.hpp"
+
+#include "wii_camera.h"
+#include "wii_frame.hpp"
+#include "wii_point_extractor.h"
+#include "ftnoir_tracker_pt_dialog.h"
+
+#include "pt-api.hpp"
+
+#include <memory>
+
+static const QString module_name = "tracker-wii-pt";
+
+using namespace pt_module;
+
+struct wii_pt_module_traits final : pt_runtime_traits
+{
+ pointer<pt_camera> make_camera() const override
+ {
+ return pointer<pt_camera>(new WIICamera(module_name));
+ }
+
+ pointer<pt_point_extractor> make_point_extractor() const override
+ {
+ return pointer<pt_point_extractor>(new WIIPointExtractor(module_name));
+ }
+
+ QString get_module_name() const override
+ {
+ return module_name;
+ }
+
+ pointer<pt_frame> make_frame() const override
+ {
+ return pointer<pt_frame>(new WIIFrame);
+ }
+
+ pointer<pt_preview> make_preview(int w, int h) const override
+ {
+ return pointer<pt_preview>(new WIIPreview(w, h));
+ }
+};
+
+struct wii_tracker_pt : Tracker_PT
+{
+ wii_tracker_pt() : Tracker_PT(pointer<pt_runtime_traits>(new wii_pt_module_traits))
+ {
+ }
+};
+
+
+struct wii_dialog_pt : TrackerDialog_PT
+{
+ wii_dialog_pt();
+};
+
+class wii_metadata_pt : public Metadata
+{
+ QString name() { return _("WiiPointTracker 1.1"); }
+ QIcon icon() { return QIcon(":/Resources/wii.png"); }
+};
+
+// ns pt_module
+
+using namespace pt_module;
+
+
+
+wii_dialog_pt::wii_dialog_pt() : TrackerDialog_PT(module_name)
+{
+ ui.camera_settings_groupbox->hide();
+ ui.groupBox_2->hide();
+}
+
+OPENTRACK_DECLARE_TRACKER(wii_tracker_pt, wii_dialog_pt, wii_metadata_pt)
diff --git a/tracker-wii/wii_point_extractor.cpp b/tracker-wii/wii_point_extractor.cpp
new file mode 100644
index 00000000..f1fc013d
--- /dev/null
+++ b/tracker-wii/wii_point_extractor.cpp
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* 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 "wii_point_extractor.h"
+
+#include "point_tracker.h"
+#include "wii_frame.hpp"
+
+#include "cv/numeric.hpp"
+#include "compat/math.hpp"
+
+#include <opencv2/videoio.hpp>
+
+#undef PREVIEW
+//#define PREVIEW
+
+#if defined PREVIEW
+# include <opencv2/highgui.hpp>
+#endif
+
+#include <cmath>
+#include <algorithm>
+#include <cinttypes>
+#include <memory>
+
+#include <QDebug>
+
+using namespace types;
+using namespace pt_module;
+
+
+WIIPointExtractor::WIIPointExtractor(const QString& module_name) : s(module_name)
+{
+
+}
+
+//define a temp draw function
+void WIIPointExtractor::_draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thinkness)
+{
+ static constexpr int len = 9;
+
+ cv::Point p2(iround(p[0] * preview_frame.cols + preview_frame.cols / 2),
+ iround(-p[1] * preview_frame.cols + preview_frame.rows / 2));
+
+ cv::line(preview_frame,
+ cv::Point(p2.x - len, p2.y),
+ cv::Point(p2.x + len, p2.y),
+ color,
+ thinkness);
+ cv::line(preview_frame,
+ cv::Point(p2.x, p2.y - len),
+ cv::Point(p2.x, p2.y + len),
+ color,
+ thinkness);
+};
+
+bool WIIPointExtractor::_draw_points(cv::Mat& preview_frame, const struct wii_info &wii, std::vector<vec2>& points)
+{
+ const float W = 1024.0f;
+ const float H = 768.0f;
+ points.reserve(4);
+ points.clear();
+
+ for (unsigned index = 0; index < 4; index++)
+ {
+ const struct wii_info_points &dot = wii.Points[index];
+ if (dot.bvis) {
+ //qDebug() << "wii:" << dot.RawX << "+" << dot.RawY;
+ //anti-clockwise rotate the 2D point
+ const float RX = W - dot.ux;
+ const float RY = H - dot.uy;
+ //vec2 dt((dot.RawX - W / 2.0f) / W, -(dot.RawY - H / 2.0f) / W);
+ //vec2 dt((RX - W / 2.0f) / W, -(RY - H / 2.0f) / W);
+ //vec2 dt((2.0f*RX - W) / W, -(2.0f*RY - H ) / W);
+ vec2 dt;
+ std::tie(dt[0], dt[1]) = to_screen_pos(RX, RY, W, H);
+
+ points.push_back(dt);
+ _draw_point(preview_frame, dt, cv::Scalar(0, 255, 0), dot.isize);
+ }
+ }
+ const bool success = points.size() >= PointModel::N_POINTS;
+
+ return success;
+}
+
+void WIIPointExtractor::_draw_bg(cv::Mat& preview_frame, const struct wii_info &wii)
+{
+ //draw battery status
+ cv::line(preview_frame,
+ cv::Point(0, 0),
+ cv::Point(preview_frame.cols*wii.BatteryPercent / 100, 0),
+ (wii.bBatteryDrained ? cv::Scalar(255, 0, 0) : cv::Scalar(0, 140, 0)),
+ 2);
+
+ //draw horizon
+ int pdelta = iround((preview_frame.rows / 4) * tan((wii.Pitch)* M_PI / 180.0f));
+ int rdelta = iround((preview_frame.cols / 4) * tan((wii.Roll)* M_PI / 180.0f));
+
+ cv::line(preview_frame,
+ cv::Point(0, preview_frame.rows / 2 + rdelta - pdelta),
+ cv::Point(preview_frame.cols, preview_frame.rows / 2 - rdelta - pdelta),
+ cv::Scalar(80, 80, 80),
+ 1);
+}
+
+
+void WIIPointExtractor::extract_points(const pt_frame& frame_, pt_preview& preview_frame_, std::vector<vec2>& points)
+{
+ const cv::Mat& frame = frame_.as_const<WIIFrame>()->mat;
+ const struct wii_info& wii = frame_.as_const<WIIFrame>()->wii;
+ cv::Mat& preview_frame = *preview_frame_.as<WIIPreview>();
+
+ //create a blank frame
+ //cv::Mat blank_frame(preview_frame.cols, preview_frame.rows, CV_8UC3, cv::Scalar(0, 0, 0));
+ //cv::cvtColor(_frame, _frame2, cv::COLOR_BGR2BGRA);
+ //cv::resize(blank_frame, preview_frame, cv::Size(preview_frame.cols, preview_frame.rows), 0, 0, cv::INTER_NEAREST);
+
+ switch (wii.status) {
+ case wii_cam_data_change:
+ _draw_bg(preview_frame, wii);
+ _draw_points(preview_frame, wii, points);
+ break;
+ case wii_cam_wait_for_connect:
+ char txtbuf[64];
+ sprintf(txtbuf, "%s", "wait for WIImote");
+ //draw wait text
+ cv::putText(preview_frame,
+ txtbuf,
+ cv::Point(preview_frame.cols / 10, preview_frame.rows / 2),
+ cv::FONT_HERSHEY_SIMPLEX,
+ 1,
+ cv::Scalar(255, 255, 255),
+ 1);
+ break;
+ }
+}
+
diff --git a/tracker-wii/wii_point_extractor.h b/tracker-wii/wii_point_extractor.h
new file mode 100644
index 00000000..be0e5f45
--- /dev/null
+++ b/tracker-wii/wii_point_extractor.h
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2017-2018 Wei Shuai <cpuwolf@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*/
+#pragma once
+
+#include "pt-api.hpp"
+
+#include <vector>
+
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc.hpp>
+
+namespace pt_module {
+
+using namespace types;
+
+class WIIPointExtractor final : public pt_point_extractor
+{
+public:
+ // extracts points from frame and draws some processing info into frame, if draw_output is set
+ // dt: time since last call in seconds
+ void extract_points(const pt_frame& frame, pt_preview& preview_frame, std::vector<vec2>& points) override;
+ WIIPointExtractor(const QString& module_name);
+private:
+ static constexpr int max_blobs = 16;
+
+ pt_settings s;
+ void _draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thinkness = 1);
+ bool _draw_points(cv::Mat& preview_frame, const struct wii_info &wii, std::vector<vec2>& points);
+ void _draw_bg(cv::Mat& preview_frame, const struct wii_info &wii);
+};
+
+} // ns impl
+