summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDonovan Baarda <abo@minkirri.apana.org.au>2014-10-15 14:07:20 +1100
committerDonovan Baarda <abo@minkirri.apana.org.au>2014-10-15 14:07:20 +1100
commitdbd04e283082ab869a22abf03c4c6280b03935bb (patch)
tree3951c6f91f76047e655f35e04db4eecd576c49df
parentd880464fbe9180aefde94594330126e115066dc3 (diff)
parent051a2e4392bc75b246cc5cb897ae0bbb1f92042e (diff)
Merge branch 'unstable' of https://github.com/opentrack/opentrack into dev/kalman
Conflicts: ftnoir_filter_kalman/ftnoir_filter_kalman.h
-rw-r--r--.gitattributes8
-rw-r--r--.gitignore10
-rw-r--r--3rdparty-notices/FACETRACKNOIR-COPYING.txt4
-rw-r--r--3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt29
-rw-r--r--CMakeLists.txt217
-rw-r--r--FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui1790
-rw-r--r--FTNoIR_Tracker_PT/boost-compat.h5
-rw-r--r--FTNoIR_Tracker_PT/frame_observer.cpp18
-rw-r--r--FTNoIR_Tracker_PT/frame_observer.h76
-rw-r--r--FTNoIR_Tracker_PT/ftnoir_tracker_pt.h95
-rw-r--r--FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp321
-rw-r--r--FTNoIR_Tracker_PT/point_extractor.h35
-rw-r--r--FTNoIR_Tracker_PT/point_tracker.cpp380
-rw-r--r--FTNoIR_Tracker_PT/point_tracker.h129
-rw-r--r--README.md7
-rw-r--r--TODO.txt29
-rw-r--r--bin/settings/facetracknoir supported games.csv1004
-rw-r--r--cmake/mingw-w64.cmake28
-rw-r--r--compat/compat.cpp9
-rw-r--r--compat/compat.h4
-rw-r--r--compat/qt-bug-appeasement.cpp1
-rw-r--r--dinput/dinput8.libbin19978 -> 0 bytes
-rw-r--r--dinput/dxguid.libbin105732 -> 0 bytes
-rw-r--r--dinput/strmiids.libbin272820 -> 0 bytes
-rw-r--r--documentation/filemapping example.docbin35840 -> 0 bytes
-rw-r--r--documentation/qt 4.5 with visual studio 2.pdfbin575691 -> 0 bytes
-rw-r--r--documentation/setting up qt.pdfbin20759 -> 0 bytes
-rw-r--r--documentation/using shared memory for freetrack server.pdfbin13514 -> 0 bytes
-rw-r--r--documentation/working with qt visual studio plugin.pdfbin314796 -> 0 bytes
-rw-r--r--facetracknoir/clientfiles/FlightGear/readme.txt16
-rw-r--r--facetracknoir/clientfiles/cute-octopus-vector-material_15-1831.jpgbin0 -> 71514 bytes
-rwxr-xr-xfacetracknoir/clientfiles/make-csv.pl72
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/README-CREDIT.txt6
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.am54
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.in491
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/ft_tester/fttester.rc.in67
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/ft_tester/main.cpp211
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/ft_tester/resource.h27
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.h17
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.spec23
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_dll.h58
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_main.c444
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.c150
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.h17
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/Makefile.am78
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/Makefile.in512
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/main.cpp100
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/npifc.c302
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/npifc.h66
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/npview.rc.in49
-rw-r--r--facetracknoir/clientfiles/very-important-source-code/tester/resource.h23
l---------facetracknoir/clientfiles/very-important-source-code/tester/rest.c1
l---------facetracknoir/clientfiles/very-important-source-code/tester/rest.h1
-rw-r--r--facetracknoir/curve-config.cpp187
-rw-r--r--facetracknoir/curve-config.h13
-rw-r--r--facetracknoir/export.hpp7
-rw-r--r--facetracknoir/facetracknoir.cpp398
-rw-r--r--facetracknoir/facetracknoir.h109
-rw-r--r--facetracknoir/facetracknoir.ui2835
-rw-r--r--facetracknoir/ftnoir_curves.ui2015
-rw-r--r--facetracknoir/ftnoir_keyboardshortcuts.ui434
-rw-r--r--facetracknoir/gain-control.hpp198
-rw-r--r--facetracknoir/global-settings.cpp132
-rw-r--r--facetracknoir/global-settings.h93
-rw-r--r--facetracknoir/global-shortcuts.cpp3
-rw-r--r--facetracknoir/lerp.hpp60
-rw-r--r--facetracknoir/main-facetracknoir.qrc1
-rw-r--r--facetracknoir/main-settings.hpp18
-rw-r--r--facetracknoir/main.cpp77
-rw-r--r--facetracknoir/mappings.hpp88
-rw-r--r--facetracknoir/options.h306
-rw-r--r--facetracknoir/plugin-api.hpp11
-rw-r--r--facetracknoir/plugin-qt-api.hpp68
-rw-r--r--facetracknoir/plugin-support.cpp158
-rw-r--r--facetracknoir/plugin-support.h55
-rw-r--r--facetracknoir/pose.hpp44
-rw-r--r--facetracknoir/qcopyable-mutex.hpp37
-rw-r--r--facetracknoir/qt-moc.h10
-rw-r--r--facetracknoir/quat.hpp66
-rw-r--r--facetracknoir/rotation.h64
-rw-r--r--facetracknoir/shortcuts.cpp14
-rw-r--r--facetracknoir/timer.hpp12
-rw-r--r--facetracknoir/tracker.cpp362
-rw-r--r--facetracknoir/tracker.h111
-rw-r--r--facetracknoir/tracker_types.cpp44
-rw-r--r--facetracknoir/tracker_types.h19
-rw-r--r--facetracknoir/uielements/curves.pngbin2850 -> 3457 bytes
-rw-r--r--facetracknoir/uielements/no-feed.pngbin0 -> 128664 bytes
-rw-r--r--facetracknoir/version.c5
-rw-r--r--freetrackclient/build-msvc.sh33
-rw-r--r--freetrackclient/freetrackclient.c114
-rw-r--r--freetrackclient/freetrackclient.cpp262
-rw-r--r--freetrackclient/freetrackclient.def6
-rw-r--r--ftnoir_csv/csv.cpp18
-rw-r--r--ftnoir_csv/csv.h11
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.cpp139
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.h160
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp6
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp4
-rw-r--r--ftnoir_filter_base/ftnoir_filter_base.h29
-rw-r--r--ftnoir_filter_base/ftnoir_filter_base_global.h16
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp88
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2.h35
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp30
-rw-r--r--ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp28
-rwxr-xr-x[-rw-r--r--]ftnoir_filter_kalman/ftnoir_filter_kalman.h27
-rw-r--r--ftnoir_filter_kalman/kalman.cpp10
-rw-r--r--ftnoir_posewidget/glwidget.h13
-rw-r--r--ftnoir_protocol_base/ftnoir_protocol_base.h57
-rw-r--r--ftnoir_protocol_base/ftnoir_protocol_base_global.h16
-rw-r--r--ftnoir_protocol_fg/ftnoir_fgcontrols.ui286
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg.cpp5
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg.h3
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp6
-rw-r--r--ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp4
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui268
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp8
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h5
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp6
-rw-r--r--ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp4
-rw-r--r--ftnoir_protocol_ft/ftnoir_ftcontrols.ui405
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft.cpp86
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft.h25
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp38
-rw-r--r--ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp29
-rw-r--r--ftnoir_protocol_ft/fttypes.h60
-rw-r--r--ftnoir_protocol_ftn/ftnoir_ftncontrols.ui532
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp5
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn.h6
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp6
-rw-r--r--ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp4
-rw-r--r--ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp5
-rw-r--r--ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h6
-rw-r--r--ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp4
-rw-r--r--ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp4
-rw-r--r--ftnoir_protocol_mouse/ftnoir_mousecontrols.ui410
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp6
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse.h7
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp6
-rw-r--r--ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp4
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc.cpp18
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc.h13
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp6
-rw-r--r--ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp4
-rw-r--r--ftnoir_protocol_sc/ftnoir_sccontrols.ui144
-rw-r--r--ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp15
-rw-r--r--ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h30
-rw-r--r--ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp4
-rw-r--r--ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp4
-rw-r--r--ftnoir_protocol_wine/ftnoir_protocol_wine.cpp20
-rw-r--r--ftnoir_protocol_wine/ftnoir_protocol_wine.h53
-rw-r--r--ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp28
-rw-r--r--ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp18
-rw-r--r--ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx29
-rw-r--r--ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx11
-rw-r--r--ftnoir_protocol_wine/wine-shm.h4
-rw-r--r--ftnoir_tracker_aruco/ar_video_widget.cpp12
-rw-r--r--ftnoir_tracker_aruco/ar_video_widget.h22
-rw-r--r--ftnoir_tracker_aruco/aruco-trackercontrols.ui425
-rw-r--r--ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp457
-rw-r--r--ftnoir_tracker_aruco/ftnoir_tracker_aruco.h59
-rw-r--r--ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h3
-rw-r--r--ftnoir_tracker_aruco/include/boarddetector.h2
-rw-r--r--ftnoir_tracker_aruco/include/cameraparameters.h6
-rw-r--r--ftnoir_tracker_aruco/include/cvdrawingutils.h2
-rw-r--r--ftnoir_tracker_aruco/include/exports.h6
-rw-r--r--ftnoir_tracker_aruco/include/marker.h16
-rw-r--r--ftnoir_tracker_aruco/include/markerdetector.h64
-rw-r--r--ftnoir_tracker_aruco/trans_calib.cpp44
-rw-r--r--ftnoir_tracker_aruco/trans_calib.h (renamed from FTNoIR_Tracker_PT/trans_calib.h)78
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_base.h65
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_base_global.h18
-rw-r--r--ftnoir_tracker_base/ftnoir_tracker_types.h4
-rw-r--r--ftnoir_tracker_freepie-udp/freepie-udp-controls.ui69
-rw-r--r--ftnoir_tracker_freepie-udp/freepie-udp-res.qrc5
-rw-r--r--ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp94
-rw-r--r--ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h65
-rw-r--r--ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp27
-rw-r--r--ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp27
-rw-r--r--ftnoir_tracker_freepie-udp/glovepie.pngbin0 -> 3584 bytes
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht.cpp45
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht.h11
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h3
-rw-r--r--ftnoir_tracker_ht/ht-trackercontrols.ui91
-rw-r--r--ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui168
-rw-r--r--ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp49
-rw-r--r--ftnoir_tracker_hydra/ftnoir_tracker_hydra.h42
-rw-r--r--ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp13
-rw-r--r--ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp13
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp82
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick.h17
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui422
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp13
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp4
-rw-r--r--ftnoir_tracker_pt/FTNoIR_PT_Controls.ui1207
-rw-r--r--ftnoir_tracker_pt/Resources/Logo_IR.png (renamed from FTNoIR_Tracker_PT/Resources/Logo_IR.png)bin10386 -> 10386 bytes
-rw-r--r--ftnoir_tracker_pt/Resources/cap_front.png (renamed from FTNoIR_Tracker_PT/Resources/cap_front.png)bin1164 -> 1164 bytes
-rw-r--r--ftnoir_tracker_pt/Resources/cap_side.png (renamed from FTNoIR_Tracker_PT/Resources/cap_side.png)bin1733 -> 1733 bytes
-rw-r--r--ftnoir_tracker_pt/Resources/clip_front.png (renamed from FTNoIR_Tracker_PT/Resources/clip_front.png)bin571 -> 571 bytes
-rw-r--r--ftnoir_tracker_pt/Resources/clip_side.png (renamed from FTNoIR_Tracker_PT/Resources/clip_side.png)bin2677 -> 2677 bytes
-rw-r--r--ftnoir_tracker_pt/camera.cpp (renamed from FTNoIR_Tracker_PT/camera.cpp)679
-rw-r--r--ftnoir_tracker_pt/camera.h (renamed from FTNoIR_Tracker_PT/camera.h)286
-rw-r--r--ftnoir_tracker_pt/doc/index.htm (renamed from FTNoIR_Tracker_PT/doc/index.htm)0
-rw-r--r--ftnoir_tracker_pt/doc/logo.png (renamed from FTNoIR_Tracker_PT/doc/logo.png)bin10386 -> 10386 bytes
-rw-r--r--ftnoir_tracker_pt/doc/ptrack.ico (renamed from FTNoIR_Tracker_PT/doc/ptrack.ico)bin4286 -> 4286 bytes
-rw-r--r--ftnoir_tracker_pt/doc/settings1.png (renamed from FTNoIR_Tracker_PT/doc/settings1.png)bin25013 -> 25013 bytes
-rw-r--r--ftnoir_tracker_pt/doc/settings2.png (renamed from FTNoIR_Tracker_PT/doc/settings2.png)bin26841 -> 26841 bytes
-rw-r--r--ftnoir_tracker_pt/doc/settings3.png (renamed from FTNoIR_Tracker_PT/doc/settings3.png)bin29547 -> 29547 bytes
-rw-r--r--ftnoir_tracker_pt/doc/style.css (renamed from FTNoIR_Tracker_PT/doc/style.css)262
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.cpp (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt.cpp)491
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.h91
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.qrc (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt.qrc)0
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp258
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.h)132
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.cpp)84
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.h)53
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h (renamed from FTNoIR_Tracker_PT/ftnoir_tracker_pt_settings.h)165
-rw-r--r--ftnoir_tracker_pt/point_extractor.cpp (renamed from FTNoIR_Tracker_PT/point_extractor.cpp)324
-rw-r--r--ftnoir_tracker_pt/point_extractor.h35
-rw-r--r--ftnoir_tracker_pt/point_tracker.cpp289
-rw-r--r--ftnoir_tracker_pt/point_tracker.h114
-rw-r--r--ftnoir_tracker_pt/pt_video_widget.cpp (renamed from FTNoIR_Tracker_PT/pt_video_widget.cpp)110
-rw-r--r--ftnoir_tracker_pt/pt_video_widget.h (renamed from FTNoIR_Tracker_PT/pt_video_widget.h)127
-rw-r--r--ftnoir_tracker_pt/trans_calib.cpp (renamed from FTNoIR_Tracker_PT/trans_calib.cpp)86
-rw-r--r--ftnoir_tracker_pt/trans_calib.h39
-rw-r--r--ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui126
-rw-r--r--ftnoir_tracker_rift/ftnoir_tracker_rift.cpp110
-rw-r--r--ftnoir_tracker_rift/ftnoir_tracker_rift.h57
-rw-r--r--ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp13
-rw-r--r--ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp4
-rw-r--r--ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui450
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp.cpp69
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp.h41
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp40
-rw-r--r--ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp29
-rw-r--r--make-tar.sh17
-rw-r--r--opentrack-api/context.cpp112
-rw-r--r--opentrack-api/gnuc-version-script.txt12
-rw-r--r--opentrack-api/opentrack-guts.h57
-rw-r--r--opentrack-api/opentrack.h58
-rw-r--r--opentrack-api/trackers.cpp38
-rw-r--r--opentrack-version.h7
-rw-r--r--qfunctionconfigurator/functionconfig.cpp319
-rw-r--r--qfunctionconfigurator/functionconfig.h90
-rw-r--r--qfunctionconfigurator/qfunctionconfigurator.cpp267
-rw-r--r--qfunctionconfigurator/qfunctionconfigurator.h97
-rw-r--r--qxt-mini/plat/qxtglobalshortcut_mac.cpp456
-rw-r--r--qxt-mini/plat/qxtglobalshortcut_x11.cpp470
-rw-r--r--qxt-mini/qxtglobalshortcut.cpp448
-rw-r--r--qxt-mini/qxtglobalshortcut.h128
-rw-r--r--x-plane-plugin/plugin.c6
251 files changed, 14394 insertions, 15286 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..5f7a58f5
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,8 @@
+*.cpp text=auto eol=lf
+*.hpp text=auto eol=lf
+*.c text=auto eol=lf
+*.h text=auto eol=lf
+*.cxx text=auto eol=lf
+*.txt text=auto eol=lf
+*.ui text=auto eol=lf
+*.qrc text=auto eol=lf
diff --git a/.gitignore b/.gitignore
index 9c4f50ff..b1b38c3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,6 @@
/CMakeLists.txt.user
*~
/build*
-/install
-/bin/tracker-ht/headtracker-ftnoir.exe
-/bin/tracker-ht/libgcc_s_dw2-1.dll
-/bin/tracker-ht/libstdc++-6.dll
-/bin/tracker-ht/bounding-box.raw
-/bin/tracker-ht/flandmark_model.dat
-/bin/tracker-ht/head.raw
/installer/Output
-/nbproject/
+# merely git cola saves there
+/patches/
diff --git a/3rdparty-notices/FACETRACKNOIR-COPYING.txt b/3rdparty-notices/FACETRACKNOIR-COPYING.txt
index befeafb5..1b2b7a07 100644
--- a/3rdparty-notices/FACETRACKNOIR-COPYING.txt
+++ b/3rdparty-notices/FACETRACKNOIR-COPYING.txt
@@ -1,3 +1,7 @@
+The opentrack project is a fork of "FaceTrackNoIR" software.
+
+Original project's site located at <http://facetracknoir.sourceforge.net/home/default.htm>
+
********************************************************************************
* FaceTrackNoIR This program is a private project of the some enthusiastic *
* gamers from Holland, who don't like to pay much for *
diff --git a/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt b/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt
deleted file mode 100644
index 80f54ae2..00000000
--- a/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2006, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b2e9f99..2de8856d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,10 @@
project(opentrack)
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.11)
+cmake_policy(SET CMP0020 NEW)
+
+if(MSVC)
+ message(FATAL_ERROR "Support for MSVC removed due to incomplete C++11 support")
+endif()
include(CMakeParseArguments)
@@ -32,7 +37,6 @@ if(APPLE)
set(CMAKE_STATIC_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_MODULE_LINKER_FLAGS}")
- set(CMAKE_CXX_FLAGS " -stdlib=libc++ -std=c++11 ${CMAKE_CXX_FLAGS} -fvisibility=hidden")
endif()
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
@@ -44,48 +48,12 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-add_definitions(-DOPENTRACK_API -DIN_OPENTRACK)
-
-if(MSVC)
- add_definitions(-DNOMINMAX)
-endif()
-
-if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE)
- add_definitions(-std=c++11)
-endif()
-
-if(WIN32 AND MSVC)
- set(SDK_GOOGLE_BREAKPAD "" CACHE PATH "google-breakpad for crash reporting")
-endif()
-
-if(MINGW)
- set(SDK_MINGW_PREFIX "" CACHE PATH "mingw prefix")
-endif()
-
-if(SDK_GOOGLE_BREAKPAD AND WIN32)
- add_definitions(-DOPENTRACK_BREAKPAD)
- include_directories("${SDK_GOOGLE_BREAKPAD}/src/client/windows/handler")
- include_directories("${SDK_GOOGLE_BREAKPAD}/src/")
-endif()
-
-if(WIN32 AND DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700)
- find_path (WIN8_SDK_ROOT_DIR
- Include/um/windows.h
- PATHS
- "$ENV{ProgramFiles}/Windows Kits/8.0"
- "$ENV{ProgramFiles(x86)}/Windows Kits/8.0"
- DOC "Windows 8 SDK root directory"
- )
+# note, hatire supports both ftnoir and opentrack
+# don't remove without being sure as hell -sh 20140922
+add_definitions(-DOPENTRACK_API)
- if(WIN8_SDK_ROOT_DIR)
- SET(CMAKE_LIBRARY_PATH "${WIN8_SDK_ROOT_DIR}/Lib/win8/um/x86")
- endif()
-endif()
-
-if(WIN32 AND DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700)
- SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
- SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
- SET (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
+if(CMAKE_COMPILER_IS_GNUCXX OR APPLE)
+ set(CMAKE_CXX_FLAGS " -std=c++11 ${CMAKE_CXX_FLAGS} ")
endif()
if(UNIX)
@@ -105,18 +73,9 @@ SET(SDK_RIFT "" CACHE PATH "libOVR path")
include_directories(${CMAKE_SOURCE_DIR})
-if(MINGW)
- # qt scripts are broken
- set(Qt5Gui_user32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libuser32.a)
- set(Qt5Gui_opengl32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libopengl32.a)
- set(Qt5Gui_glu32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libglu32.a)
- set(Qt5Gui_gdi32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libgdi32.a)
-endif()
-
find_package(OpenCV REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Xml Network Widgets Gui ${maybe-serial-port} QUIET)
-cmake_policy(SET CMP0020 NEW)
include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS})
add_definitions(${Qt5Core_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5Gui_DEFINITIONS} ${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS})
@@ -127,15 +86,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ftnoir_posewidget)
set(SDK_ARUCO_LIBPATH "" CACHE FILEPATH "Path to Aruco static library")
-SET(SDK_OPENCV_STATIC FALSE CACHE BOOL "Whether OpenCV is statically linked")
if(WIN32)
set(SDK_SIMCONNECT "" CACHE PATH "Path to SimConnect SDK")
- set(SDK_DIRECTX "" CACHE PATH "Path to DirectX SDK")
set(SDK_FSUIPC "" CACHE PATH "Path to FSUIPC")
- if(SDK_DIRECTX)
- include_directories("${SDK_DIRECTX}/Include")
- link_directories("${SDK_DIRECTX}/Lib")
- endif()
endif()
if(NOT WIN32)
@@ -178,17 +131,9 @@ endif()
set(EXTRA-MOCS "${CMAKE_SOURCE_DIR}/facetracknoir/options.h")
function(link_with_dinput8 n)
- if(WIN32)
- if(MSVC)
- target_link_libraries(${n}
- "${CMAKE_SOURCE_DIR}/dinput/dinput8.lib"
- "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib"
- "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib"
- uuid)
- else()
- target_link_libraries(${n} dinput8 dxguid strmiids)
- endif()
- endif()
+ if(WIN32)
+ target_link_libraries(${n} dinput8 dxguid strmiids)
+ endif()
endfunction()
macro(opentrack_module n dir)
@@ -209,7 +154,7 @@ macro(opentrack_library n)
if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE)
SET_TARGET_PROPERTIES(${n} PROPERTIES
LINK_FLAGS "${foolib_LINK} -Wl,--version-script=${CMAKE_SOURCE_DIR}/facetracknoir/${version-script}-version-script.txt"
- COMPILE_FLAGS "${foolib_COMPILE}"
+ COMPILE_FLAGS "${foolib_COMPILE} -fvisibility=hidden -fvisibility-inlines-hidden"
)
else()
set_target_properties(${n} PROPERTIES LINK_FLAGS "${foolib_LINK}" COMPILE_FLAGS "${foolib_COMPILE}")
@@ -217,8 +162,6 @@ macro(opentrack_library n)
install(TARGETS ${n} RUNTIME DESTINATION . LIBRARY DESTINATION .)
endmacro()
-file(GLOB opentrack-lib-c "opentrack-api/*.cpp" "facetracknoir/global-settings.cpp" "opentrack-api/*.h" "facetracknoir/global-settings.h")
-
opentrack_module(opentrack-bin facetracknoir)
opentrack_module(opentrack-pose-widget ftnoir_posewidget)
opentrack_module(opentrack-spline-widget qfunctionconfigurator)
@@ -245,11 +188,14 @@ opentrack_module(opentrack-proto-libevdev ftnoir_protocol_libevdev)
opentrack_module(opentrack-tracker-ht ftnoir_tracker_ht)
opentrack_module(opentrack-tracker-aruco ftnoir_tracker_aruco)
-opentrack_module(opentrack-tracker-pt FTNoIR_Tracker_PT)
+opentrack_module(opentrack-tracker-pt ftnoir_tracker_pt)
opentrack_module(opentrack-tracker-udp ftnoir_tracker_udp)
opentrack_module(opentrack-tracker-joystick ftnoir_tracker_joystick)
opentrack_module(opentrack-tracker-rift ftnoir_tracker_rift)
opentrack_module(opentrack-tracker-hydra ftnoir_tracker_hydra)
+opentrack_module(opentrack-tracker-freepie-udp ftnoir_tracker_freepie-udp)
+
+file(GLOB opentrack-version-c "facetracknoir/version.c")
file(GLOB opentrack-csv-c "ftnoir_csv/*.cpp" "ftnoir_csv/*.h")
@@ -262,7 +208,7 @@ file(GLOB opentrack-xplane-plugin-c "x-plane-plugin/*.c")
# freetrack
-file(GLOB opentrack-freetrack-c "freetrackclient/*.cpp")
+file(GLOB opentrack-freetrack-c "freetrackclient/*.c")
if(SDK_XPLANE)
# probably librt already included
@@ -312,6 +258,11 @@ target_link_libraries(opentrack-pose-widget ${MY_QT_LIBS})
add_library(opentrack-spline-widget SHARED ${opentrack-spline-widget-c})
target_link_libraries(opentrack-spline-widget ${MY_QT_LIBS})
+add_library(opentrack-version STATIC ${opentrack-version-c})
+set_target_properties(opentrack-version PROPERTIES
+ COMPILE_DEFINITIONS
+ "IN_VERSION_UNIT;OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\"")
+
opentrack_library(opentrack-filter-accela)
opentrack_library(opentrack-filter-kalman)
opentrack_library(opentrack-filter-ewma)
@@ -322,12 +273,12 @@ opentrack_library(opentrack-proto-fgfs)
if(SDK_VJOY)
include_directories(${SDK_VJOY})
- opentrack_library(opentrack-proto-vjoy)
- if(MSVC)
- target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.lib")
- else()
- target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.dll")
+ set(link-flags)
+ if(CMAKE_C_COMPILER_IS_GNUCC)
+ set(link-flags "-Wl,--enable-stdcall-fixup")
endif()
+ opentrack_library(opentrack-proto-vjoy LINK ${link-flags})
+ target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.dll")
endif()
if(SDK_ENABLE_LIBEVDEV)
@@ -338,10 +289,7 @@ if(SDK_ENABLE_LIBEVDEV)
endif()
if(SDK_FSUIPC)
- if(MSVC)
- set(link-flags "/NODEFAULTLIB:libc")
- endif()
- opentrack_library(opentrack-proto-fsuipc LINK "${link-flags}")
+ opentrack_library(opentrack-proto-fsuipc)
target_link_libraries(opentrack-proto-fsuipc "${SDK_FSUIPC}/FSUIPC_User.lib")
endif()
@@ -359,9 +307,7 @@ endif()
if(WIN32)
add_library(freetrackclient SHARED ${opentrack-freetrack-c})
- if(CMAKE_COMPILER_IS_GNUCC)
- set_target_properties(freetrackclient PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup -fno-lto -Wl,-kill-at" PREFIX "" COMPILE_FLAGS "-fno-lto")
- endif()
+ set_target_properties(freetrackclient PROPERTIES PREFIX "")
endif()
opentrack_library(opentrack-proto-udp)
@@ -374,23 +320,23 @@ if(SDK_WINE_PREFIX)
opentrack_library(opentrack-proto-wine)
target_link_libraries(opentrack-proto-wine opentrack-compat opentrack-csv)
if(NOT SDK_WINE_NO_WRAPPER)
- set(my-rt -lrt)
- if(APPLE)
- set(my-rt)
- endif()
+ set(my-rt -lrt)
+ if(APPLE)
+ set(my-rt)
+ endif()
+ file(GLOB wine-deps "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/*.cxx")
add_custom_command(
OUTPUT opentrack-wrapper-wine.exe.so
- DEPENDS "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx"
- "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx"
- "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx"
- COMMAND "${SDK_WINE_PREFIX}/bin/wineg++" -g -O2 -m32 -o
+ DEPENDS ${wine-deps}
+ COMMAND "${SDK_WINE_PREFIX}/bin/wineg++" -g -O2 -m32 -std=c++11 -o
opentrack-wrapper-wine.exe -I "${CMAKE_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx"
"${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx"
"${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx"
${my-rt})
add_custom_target(wine-wrapper ALL DEPENDS opentrack-wrapper-wine.exe.so)
- add_dependencies(wine-wrapper opentrack-compat opentrack-proto-wine)
+ add_dependencies(opentrack-proto-wine wine-wrapper)
+ add_dependencies(wine-wrapper opentrack-compat)
endif()
endif()
@@ -398,15 +344,8 @@ opentrack_library(opentrack-tracker-ht)
target_link_libraries(opentrack-tracker-ht opentrack-compat)
if(SDK_ARUCO_LIBPATH)
- include_directories(${CMAKE_SOURCE_DIR}/ftnoir_tracker_aruco/include)
opentrack_library(opentrack-tracker-aruco)
target_link_libraries(opentrack-tracker-aruco ${SDK_ARUCO_LIBPATH} ${OpenCV_LIBS})
- if(WIN32 AND MSVC)
- target_link_libraries(opentrack-tracker-aruco
- "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib"
- "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib"
- uuid)
- endif()
endif()
link_with_dinput8(opentrack-tracker-ht)
@@ -418,6 +357,7 @@ target_link_libraries(opentrack-tracker-pt ${OpenCV_LIBS})
link_with_dinput8(opentrack-tracker-pt)
opentrack_library(opentrack-tracker-udp)
+opentrack_library(opentrack-tracker-freepie-udp)
if(SDK_RIFT)
include_directories("${SDK_RIFT}/Include")
@@ -428,24 +368,16 @@ if(SDK_RIFT)
set(link-flags "-framework CoreFoundation -framework CoreGraphics -framework IOKit -framework Quartz")
set(c-flags "-fno-strict-aliasing")
else()
- if(MSVC)
- set(link-flags "/NODEFAULTLIB:LIBCMT")
- else()
- set(c-flags "-fno-strict-aliasing")
- endif()
+ set(c-flags "-fno-strict-aliasing")
endif()
opentrack_library(opentrack-tracker-rift LINK "${link-flags}" COMPILE "${c-flags}")
- if(MSVC)
- target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/Lib/Win32/libovr.lib" winmm.lib setupapi.lib)
+ if(WIN32)
+ target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" winmm setupapi ws2_32 imagehlp wbemuuid)
else()
- if(WIN32)
- target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" winmm setupapi)
- else()
- if(NOT APPLE)
+ if(NOT APPLE)
target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" udev Xinerama)
- else()
+ else()
target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a")
- endif()
endif()
endif()
endif()
@@ -493,30 +425,16 @@ if(UNIX OR APPLE)
SET_TARGET_PROPERTIES(opentrack-qxt-mini PROPERTIES COMPILE_FLAGS "-DBUILD_QXT_CORE=42 -DBUILD_QXT_WIDGETS=42 -DBUILD_QXT_GUI=42")
target_link_libraries(opentrack-qxt-mini ${MY_QT_LIBS})
if(NOT APPLE)
- target_link_libraries(opentrack-qxt-mini X11)
+ target_link_libraries(opentrack-qxt-mini X11)
endif()
endif()
+
add_executable(opentrack ${opentrack-win32-executable} ${opentrack-bin-c} ${opentrack-bin-uih} ${opentrack-bin-rcc})
-set_target_properties(opentrack PROPERTIES COMPILE_DEFINITIONS OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\")
-set(OPENTRACK_COMMIT_VERSION \"${OPENTRACK__COMMIT}\")
-configure_file("${CMAKE_SOURCE_DIR}/opentrack-version.h" "${CMAKE_BINARY_DIR}/opentrack-version.h" @ONLY NEWLINE_STYLE UNIX)
if(APPLE)
SET_TARGET_PROPERTIES(opentrack-qxt-mini PROPERTIES LINK_FLAGS "-framework Carbon -framework CoreFoundation")
endif()
-add_library(opentrack-api SHARED ${opentrack-lib-c})
-target_link_libraries(opentrack-api ${MY_QT_LIBS})
-if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE)
- SET_TARGET_PROPERTIES(opentrack-api PROPERTIES
- LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/opentrack-api/gnuc-version-script.txt"
- COMPILE_FLAGS "-fvisibility=protected -fvisibility-inlines-hidden"
- COMPILE_DEFINITIONS IN_OPENTRACK_API
- )
-endif()
-
-set_target_properties(opentrack PROPERTIES COMPILE_DEFINITIONS OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\")
-
if(UNIX OR APPLE)
target_link_libraries(opentrack opentrack-qxt-mini)
endif()
@@ -533,23 +451,12 @@ if(CMAKE_SYSTEM STREQUAL LINUX)
link_libraries(rt)
endif()
-if(MSVC)
- SET_TARGET_PROPERTIES(opentrack PROPERTIES LINK_FLAGS "/ENTRY:mainCRTStartup")
-endif()
-target_link_libraries(opentrack opentrack-pose-widget opentrack-spline-widget ${MY_QT_LIBS} ${QXT_QXTCORE_LIB_RELEASE} ${QXT_QXTWIDGETS_LIB_RELEASE})
+target_link_libraries(opentrack opentrack-version opentrack-pose-widget opentrack-spline-widget ${MY_QT_LIBS} ${QXT_QXTCORE_LIB_RELEASE} ${QXT_QXTWIDGETS_LIB_RELEASE})
if(NOT WIN32)
target_link_libraries(opentrack dl)
- target_link_libraries(opentrack-api dl)
-endif()
-if(SDK_GOOGLE_BREAKPAD)
- if(MSVC)
- target_link_libraries(opentrack
- "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/crash_generation_client.lib"
- "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/exception_handler.lib"
- "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/common.lib")
- endif()
+else()
+ target_link_libraries(opentrack winmm)
endif()
-set_target_properties(opentrack PROPERTIES COMPILE_FLAGS -DOPENTRACK_MAIN)
# make install
@@ -569,13 +476,12 @@ install(DIRECTORY "${CMAKE_SOURCE_DIR}/3rdparty-notices" DESTINATION .)
install(FILES "${CMAKE_SOURCE_DIR}/bin/NPClient.dll" "${CMAKE_SOURCE_DIR}/bin/NPClient64.dll" "${CMAKE_SOURCE_DIR}/bin/TrackIR.exe" DESTINATION .)
install(DIRECTORY "${CMAKE_SOURCE_DIR}/bin/settings" "${CMAKE_SOURCE_DIR}/facetracknoir/clientfiles" DESTINATION .)
-if(NOT WIN32 AND SDK_WINE_PREFIX)
+if(NOT WIN32 AND SDK_WINE_PREFIX AND NOT SDK_WINE_NO_WRAPPER)
install(FILES "${CMAKE_BINARY_DIR}/opentrack-wrapper-wine.exe.so"
DESTINATION .)
endif()
install(TARGETS
- opentrack-api
opentrack-compat
opentrack-csv
opentrack-pose-widget
@@ -592,8 +498,17 @@ if(WIN32)
install(FILES "${CMAKE_SOURCE_DIR}/bin/cleye.config" DESTINATION .)
endif()
-if(MSVC)
- file(GLOB pdbs1 "${CMAKE_BINARY_DIR}/Release/*.pdb")
- file(GLOB pdbs2 "${CMAKE_BINARY_DIR}/*.pdb")
- install(FILES ${pdbs1} ${pdbs2} DESTINATION .)
+string(TIMESTAMP filename-date "%Y%m%d")
+set(filename-ostype ${CMAKE_SYSTEM_NAME})
+get_git_head_revision(filename-branch_0 filename-hash_0)
+if(filename-hash_0)
+ string(SUBSTRING "${filename-hash_0}" 0 7 filename-hash)
endif()
+string(REPLACE "refs/heads/" "" filename-branch_1 "${filename-branch_0}")
+string(REPLACE "/" "-" filename-branch "${filename-branch_1}")
+set(filename_0 opentrack-${filename-ostype}-${filename-branch}-${filename-date}-${filename-hash})
+string(TOLOWER "${filename_0}" filename_1)
+set(filename "${CMAKE_BINARY_DIR}/${filename_1}.tar.xz")
+
+add_custom_command(OUTPUT ${filename} COMMAND env sh "${CMAKE_SOURCE_DIR}/make-tar.sh" "${CMAKE_INSTALL_PREFIX}" "${filename}")
+add_custom_target(tarball DEPENDS ${filename})
diff --git a/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui b/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui
deleted file mode 100644
index 0bbec7e1..00000000
--- a/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui
+++ /dev/null
@@ -1,1790 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICPTClientControls</class>
- <widget class="QWidget" name="UICPTClientControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>459</width>
- <height>621</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>PointTracker Settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="ftnoir_tracker_pt.qrc">
- <normaloff>:/Resources/Logo_IR.png</normaloff>:/Resources/Logo_IR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetFixedSize</enum>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>General</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QGroupBox" name="groupBox_6">
- <property name="title">
- <string>Tracker Thread</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_43">
- <property name="text">
- <string>Auto-reset time</string>
- </property>
- <property name="buddy">
- <cstring>reset_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="reset_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Time until automatic reset of tracker's internal state when no valid tracking result is found</string>
- </property>
- <property name="suffix">
- <string>ms</string>
- </property>
- <property name="maximum">
- <number>9999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_17">
- <property name="text">
- <string>Dynamic Pose Resolution</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="dynpose_check">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QPushButton" name="reset_button">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Reset the tracker's internal state</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
- </property>
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Roll:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableRoll</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Pitch:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnablePitch</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Yaw:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableYaw</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>X:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableX</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QCheckBox" name="chkEnableX">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Y:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableY</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QCheckBox" name="chkEnableY">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Z:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableZ</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QCheckBox" name="chkEnableZ">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="2">
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="2">
- <spacer name="horizontalSpacer_8">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string>Camera</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="toolTip">
- <string>The camera device used as input</string>
- </property>
- <property name="title">
- <string>Camera Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="label_2">
- <property name="minimumSize">
- <size>
- <width>55</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Device</string>
- </property>
- <property name="buddy">
- <cstring>camdevice_combo</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="camdevice_combo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Camera device used as input</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_8">
- <item>
- <layout class="QGridLayout" name="gridLayout_8">
- <item row="0" column="0">
- <widget class="QLabel" name="label_36">
- <property name="minimumSize">
- <size>
- <width>55</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Resolution</string>
- </property>
- </widget>
- </item>
- <item row="0" column="5">
- <widget class="QLabel" name="label_37">
- <property name="text">
- <string>FPS</string>
- </property>
- <property name="buddy">
- <cstring>fps_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="6">
- <widget class="QSpinBox" name="fps_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Desired capture framerate</string>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_41">
- <property name="text">
- <string>x</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="res_x_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Desired capture width</string>
- </property>
- <property name="maximum">
- <number>2000</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QSpinBox" name="res_y_spin">
- <property name="toolTip">
- <string>Desired capture height</string>
- </property>
- <property name="maximum">
- <number>2000</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_34">
- <property name="text">
- <string>F/W</string>
- </property>
- <property name="buddy">
- <cstring>f_dspin</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="f_dspin">
- <property name="toolTip">
- <string>The camera's focal length devided by its sensor width</string>
- </property>
- <property name="decimals">
- <number>2</number>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="7">
- <spacer name="horizontalSpacer_9">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7"/>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string>Camera Orientation</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Pitch</string>
- </property>
- <property name="buddy">
- <cstring>campitch_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="campitch_spin">
- <property name="contextMenuPolicy">
- <enum>Qt::DefaultContextMenu</enum>
- </property>
- <property name="toolTip">
- <string>The angle the camera is facing upwards</string>
- </property>
- <property name="minimum">
- <number>-99</number>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_20">
- <property name="text">
- <string>Yaw</string>
- </property>
- <property name="buddy">
- <cstring>camyaw_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="camyaw_spin">
- <property name="contextMenuPolicy">
- <enum>Qt::DefaultContextMenu</enum>
- </property>
- <property name="toolTip">
- <string>The angle the camera is facing leftwards</string>
- </property>
- <property name="minimum">
- <number>-99</number>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_21">
- <property name="text">
- <string>deg (positve = leftwards)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="camroll_combo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Rotation of the camera image</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>deg (positive = upwards)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_19">
- <property name="text">
- <string>deg</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_18">
- <property name="text">
- <string>Roll</string>
- </property>
- <property name="buddy">
- <cstring>camroll_combo</cstring>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_10">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Point Extraction</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Threshold</string>
- </property>
- <property name="buddy">
- <cstring>threshold_slider</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSlider" name="threshold_slider">
- <property name="toolTip">
- <string>Intensity threshold for point extraction</string>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="value">
- <number>127</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_secondary">
- <item>
- <widget class="QLabel" name="label_secondary">
- <property name="text">
- <string>Hysteresis</string>
- </property>
- <property name="buddy">
- <cstring>threshold_secondary_slider</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSlider" name="threshold_secondary_slider">
- <property name="toolTip">
- <string>Per pixel hysteresis width (leave left if there is little difference between dot and non-dot, move right for increased stability against pixel noise)</string>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Min Diameter</string>
- </property>
- <property name="buddy">
- <cstring>mindiam_spin</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="mindiam_spin">
- <property name="toolTip">
- <string>Minimum point diameter</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_12">
- <property name="text">
- <string>px</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Max Diameter</string>
- </property>
- <property name="buddy">
- <cstring>maxdiam_spin</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="maxdiam_spin">
- <property name="toolTip">
- <string>Maximum point diameter</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>px</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_4">
- <attribute name="title">
- <string>Model</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_16">
- <item>
- <widget class="QTabWidget" name="model_tabs">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>2</number>
- </property>
- <property name="usesScrollButtons">
- <bool>false</bool>
- </property>
- <property name="documentMode">
- <bool>false</bool>
- </property>
- <property name="tabsClosable">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="tab_5">
- <attribute name="title">
- <string>Clip</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_13">
- <item>
- <widget class="QGroupBox" name="groupBox_8">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_16">
- <item>
- <widget class="QWidget" name="widget_4" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>150</width>
- <height>160</height>
- </size>
- </property>
- <widget class="QLabel" name="label_44">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>30</y>
- <width>71</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_side.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_theight_spin">
- <property name="geometry">
- <rect>
- <x>100</x>
- <y>50</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_tlength_spin">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>10</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_bheight_spin">
- <property name="geometry">
- <rect>
- <x>100</x>
- <y>90</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_50">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Side</string>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_blength_spin">
- <property name="geometry">
- <rect>
- <x>40</x>
- <y>140</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_52">
- <property name="geometry">
- <rect>
- <x>70</x>
- <y>70</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="widget_3" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>140</height>
- </size>
- </property>
- <widget class="QLabel" name="label_51">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Front</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_45">
- <property name="geometry">
- <rect>
- <x>40</x>
- <y>30</y>
- <width>21</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_front.png</pixmap>
- </property>
- </widget>
- <widget class="QLabel" name="label_53">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>70</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_6">
- <attribute name="title">
- <string>Cap</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_14">
- <item>
- <widget class="QGroupBox" name="groupBox_9">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_15">
- <item>
- <widget class="QWidget" name="widget" native="true">
- <property name="minimumSize">
- <size>
- <width>140</width>
- <height>130</height>
- </size>
- </property>
- <widget class="QLabel" name="label_46">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>50</y>
- <width>111</width>
- <height>81</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_side.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_height_spin">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>80</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_54">
- <property name="geometry">
- <rect>
- <x>130</x>
- <y>50</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_48">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Side</string>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_length_spin">
- <property name="geometry">
- <rect>
- <x>50</x>
- <y>40</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="widget_2" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>130</height>
- </size>
- </property>
- <widget class="QLabel" name="label_49">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Front</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_55">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>50</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_47">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>50</y>
- <width>81</width>
- <height>81</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_front.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_width_spin">
- <property name="geometry">
- <rect>
- <x>50</x>
- <y>30</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_7">
- <attribute name="title">
- <string>Custom</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_15">
- <item>
- <widget class="QGroupBox" name="groupBox_7">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_12">
- <item>
- <widget class="QLabel" name="label_56">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Location of the two remaining model points&lt;br/&gt;with respect to the reference point in default pose&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_14">
- <item>
- <spacer name="horizontalSpacer_14">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_4">
- <item row="3" column="2">
- <widget class="QSpinBox" name="m1z_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_58">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QSpinBox" name="m1y_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="label_57">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_60">
- <property name="text">
- <string>M1:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QSpinBox" name="m1x_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_63">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_15">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="1" column="2">
- <widget class="QSpinBox" name="m2x_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_67">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="label_69">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QSpinBox" name="m2y_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_70">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_64">
- <property name="text">
- <string>M2:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QSpinBox" name="m2z_spin">
- <property name="suffix">
- <string/>
- </property>
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_16">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_10">
- <property name="title">
- <string>Model Position (mm)</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_11">
- <item>
- <widget class="QLabel" name="label_59">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Translation from head center to model reference point&lt;br/&gt; in default pose&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_17">
- <item>
- <spacer name="horizontalSpacer_17">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="3" column="1">
- <widget class="QSpinBox" name="tz_spin">
- <property name="suffix">
- <string/>
- </property>
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_61">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_62">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_66">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="ty_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="tx_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_18">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="tcalib_button">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Calibrate</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_19">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_3">
- <attribute name="title">
- <string>About</string>
- </attribute>
- <widget class="QLabel" name="label_10">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>30</y>
- <width>161</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;FTNoIR PointTracker Plugin&lt;br/&gt;Version 1.1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;by Patrick Ruoff&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://ftnoirpt.sourceforge.net/&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline; color:#0000ff;&quot;&gt;Manual (external)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QLabel" name="label_35">
- <property name="geometry">
- <rect>
- <x>200</x>
- <y>30</y>
- <width>141</width>
- <height>141</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/Logo_IR.png</pixmap>
- </property>
- </widget>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_5">
- <property name="title">
- <string>Status</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_38">
- <property name="text">
- <string>Camera Info:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="caminfo_label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>120</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Extracted Points:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="pointinfo_label">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QPushButton" name="btnApply">
- <property name="text">
- <string>Save</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="ok_button">
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="text">
- <string>Ok</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cancel_button">
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>reset_spin</tabstop>
- <tabstop>chkEnableRoll</tabstop>
- <tabstop>chkEnablePitch</tabstop>
- <tabstop>chkEnableYaw</tabstop>
- <tabstop>chkEnableX</tabstop>
- <tabstop>chkEnableY</tabstop>
- <tabstop>chkEnableZ</tabstop>
- <tabstop>camdevice_combo</tabstop>
- <tabstop>res_x_spin</tabstop>
- <tabstop>res_y_spin</tabstop>
- <tabstop>fps_spin</tabstop>
- <tabstop>f_dspin</tabstop>
- <tabstop>camroll_combo</tabstop>
- <tabstop>campitch_spin</tabstop>
- <tabstop>camyaw_spin</tabstop>
- <tabstop>threshold_slider</tabstop>
- <tabstop>mindiam_spin</tabstop>
- <tabstop>maxdiam_spin</tabstop>
- <tabstop>model_tabs</tabstop>
- <tabstop>clip_tlength_spin</tabstop>
- <tabstop>clip_theight_spin</tabstop>
- <tabstop>clip_bheight_spin</tabstop>
- <tabstop>clip_blength_spin</tabstop>
- <tabstop>cap_length_spin</tabstop>
- <tabstop>cap_height_spin</tabstop>
- <tabstop>cap_width_spin</tabstop>
- <tabstop>m1x_spin</tabstop>
- <tabstop>m1y_spin</tabstop>
- <tabstop>m1z_spin</tabstop>
- <tabstop>m2x_spin</tabstop>
- <tabstop>m2y_spin</tabstop>
- <tabstop>m2z_spin</tabstop>
- <tabstop>tx_spin</tabstop>
- <tabstop>ty_spin</tabstop>
- <tabstop>tz_spin</tabstop>
- <tabstop>tcalib_button</tabstop>
- <tabstop>ok_button</tabstop>
- <tabstop>cancel_button</tabstop>
- </tabstops>
- <resources>
- <include location="ftnoir_tracker_pt.qrc"/>
- </resources>
- <connections>
- <connection>
- <sender>dynpose_check</sender>
- <signal>toggled(bool)</signal>
- <receiver>reset_spin</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>172</x>
- <y>110</y>
- </hint>
- <hint type="destinationlabel">
- <x>351</x>
- <y>112</y>
- </hint>
- </hints>
- </connection>
- </connections>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
diff --git a/FTNoIR_Tracker_PT/boost-compat.h b/FTNoIR_Tracker_PT/boost-compat.h
deleted file mode 100644
index 612f2c4d..00000000
--- a/FTNoIR_Tracker_PT/boost-compat.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#include <memory>
-namespace boost {
- using std::shared_ptr;
-}
diff --git a/FTNoIR_Tracker_PT/frame_observer.cpp b/FTNoIR_Tracker_PT/frame_observer.cpp
deleted file mode 100644
index 281f3d57..00000000
--- a/FTNoIR_Tracker_PT/frame_observer.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2013 Patrick Ruoff
- *
- * 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 "frame_observer.h"
-
-//-----------------------------------------------------------------------------
-FrameProvider::~FrameProvider()
-{
- QMutexLocker lock(&observer_mutex);
- for (std::set<FrameObserver*>::iterator iter=frame_observers.begin(); iter!=frame_observers.end(); ++iter)
- {
- (*iter)->on_frame_provider_destroy();
- }
-}
diff --git a/FTNoIR_Tracker_PT/frame_observer.h b/FTNoIR_Tracker_PT/frame_observer.h
deleted file mode 100644
index 585a6ee7..00000000
--- a/FTNoIR_Tracker_PT/frame_observer.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) 2013 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef FRAME_OBSERVER_H
-#define FRAME_OBSERVER_H
-
-#include <QMutex>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <set>
-
-//-----------------------------------------------------------------------------
-// Forward declarations
-class FrameObserver;
-
-//-----------------------------------------------------------------------------
-// Provides means to copy frame and point information if it has observers
-// Instantiate a FrameObserver to get the information
-class FrameProvider
-{
- friend class FrameObserver;
-public:
- ~FrameProvider();
-
-protected:
- virtual bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points) = 0;
-
- bool has_observers() const { QMutexLocker lock(&observer_mutex); return !frame_observers.empty(); }
-
-private:
- mutable QMutex observer_mutex;
- void add_observer(FrameObserver* obs) { QMutexLocker lock(&observer_mutex); frame_observers.insert(obs); }
- void remove_observer(FrameObserver* obs) { QMutexLocker lock(&observer_mutex); frame_observers.erase(obs); }
- std::set<FrameObserver*> frame_observers;
-};
-
-//-----------------------------------------------------------------------------
-// Used to get frame and point information from MutexedFrameProvider
-// Destroy instance if not interested anymore since a living
-// FrameObserver instance causes MutexedFrameProvider to provide the information,
-// potentially reducing its performance
-class FrameObserver
-{
-public:
- FrameObserver(FrameProvider* provider) : provider(provider) {
- provider->add_observer(this);
- }
-
- ~FrameObserver() {
- if (provider) provider->remove_observer(this);
- }
-
- bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points) {
- return provider ? provider->get_frame_and_points(frame, points) : false;
- }
-
- void on_frame_provider_destroy() {
- provider = NULL;
- }
-
-protected:
- FrameProvider* provider;
-
-private:
- FrameObserver(const FrameObserver&);
-};
-
-#endif //FRAME_OBSERVER_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h b/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h
deleted file mode 100644
index 190ed76a..00000000
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef FTNOIR_TRACKER_PT_H
-#define FTNOIR_TRACKER_PT_H
-
-#ifdef OPENTRACK_API
-# include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-# include "facetracknoir/global-settings.h"
-#endif
-#include "ftnoir_tracker_pt_settings.h"
-#include "frame_observer.h"
-#include "camera.h"
-#include "point_extractor.h"
-#include "point_tracker.h"
-#include "pt_video_widget.h"
-#include "facetracknoir/timer.hpp"
-
-#include <QThread>
-#include <QMutex>
-#include <QMutexLocker>
-#include <QTime>
-#include <opencv2/opencv.hpp>
-#include <atomic>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <vector>
-
-//-----------------------------------------------------------------------------
-// Constantly processes the tracking chain in a separate thread
-class Tracker : public ITracker, QThread, public FrameProvider
-{
-public:
- Tracker();
- virtual ~Tracker();
- virtual void StartTracker(QFrame* parent_window);
- virtual void GetHeadPoseData(double* data);
- virtual void refreshVideo();
-
- void apply(settings& s);
- void apply_inner();
- void center();
- void reset(); // reset the trackers internal state variables
- void run();
-
- void get_pose(FrameTrafo* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.get_pose(); }
- int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); }
- void get_cam_info(CamInfo* info) { QMutexLocker lock(&mutex); *info = camera.get_info(); }
-
-protected:
- // --- MutexedFrameProvider interface ---
- virtual bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points);
-
- // --- thread ---
- QMutex mutex;
- // thread commands
- enum Command {
- ABORT = 1<<0,
- PAUSE = 1<<1
- };
- void set_command(Command command);
- void reset_command(Command command);
- volatile int commands;
-
- CVCamera camera;
- FrameRotation frame_rotation;
- PointExtractor point_extractor;
- PointTracker point_tracker;
-
- FrameTrafo X_GH_0; // for centering
- cv::Vec3f t_MH; // translation from model frame to head frame
- cv::Matx33f R_GC; // rotation from opengl reference frame to camera frame
-
- // --- ui ---
- cv::Mat frame; // the output frame for display
-
- PTVideoWidget* video_widget;
- QFrame* video_frame;
- bool tracking_valid;
-
- settings s;
- std::atomic<settings*> new_settings;
- Timer time;
-};
-
-#undef VideoWidget
-
-#endif // FTNOIR_TRACKER_PT_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp b/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp
deleted file mode 100644
index c103b78c..00000000
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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_dialog.h"
-
-#include <QMessageBox>
-#include <QDebug>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <vector>
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-TrackerDialog::TrackerDialog()
- : tracker(NULL),
- video_widget_dialog(NULL),
- timer(this),
- trans_calib_running(false)
-{
- qDebug()<<"TrackerDialog::TrackerDialog";
- setAttribute(Qt::WA_DeleteOnClose, false);
-
- ui.setupUi( this );
-
- vector<string> device_names;
- get_camera_device_names(device_names);
- for (vector<string>::iterator iter = device_names.begin(); iter != device_names.end(); ++iter)
- {
- ui.camdevice_combo->addItem(iter->c_str());
- }
-
- ui.camroll_combo->addItem("-90");
- ui.camroll_combo->addItem("0");
- ui.camroll_combo->addItem("90");
-
- tie_setting(s.dyn_pose_res, ui.dynpose_check);
- tie_setting(s.reset_time, ui.reset_spin);
-
- tie_setting(s.cam_index, ui.camdevice_combo);
- tie_setting(s.cam_f, ui.f_dspin);
- tie_setting(s.cam_res_x, ui.res_x_spin);
- tie_setting(s.cam_res_y, ui.res_y_spin);
- tie_setting(s.cam_fps, ui.fps_spin);
- tie_setting(s.cam_roll, ui.camroll_combo);
- tie_setting(s.cam_pitch, ui.campitch_spin);
- tie_setting(s.cam_yaw, ui.camyaw_spin);
-
- tie_setting(s.threshold_secondary, ui.threshold_secondary_slider);
- tie_setting(s.threshold, ui.threshold_slider);
-
- tie_setting(s.bEnableYaw, ui.chkEnableYaw);
- tie_setting(s.bEnablePitch, ui.chkEnablePitch);
- tie_setting(s.bEnableRoll, ui.chkEnableRoll);
- tie_setting(s.bEnableX, ui.chkEnableX);
- tie_setting(s.bEnableY, ui.chkEnableY);
- tie_setting(s.bEnableZ, ui.chkEnableZ);
-
- tie_setting(s.min_point_size, ui.mindiam_spin);
- tie_setting(s.max_point_size, ui.maxdiam_spin);
-
- tie_setting(s.clip_by, ui.clip_bheight_spin);
- tie_setting(s.clip_bz, ui.clip_blength_spin);
- tie_setting(s.clip_ty, ui.clip_theight_spin);
- tie_setting(s.clip_tz, ui.clip_tlength_spin);
-
- tie_setting(s.cap_x, ui.cap_width_spin);
- tie_setting(s.cap_y, ui.cap_height_spin);
- tie_setting(s.cap_z, ui.cap_length_spin);
-
- tie_setting(s.m01_x, ui.m1x_spin);
- tie_setting(s.m01_y, ui.m1y_spin);
- tie_setting(s.m01_z, ui.m1z_spin);
-
- tie_setting(s.m02_x, ui.m2x_spin);
- tie_setting(s.m02_y, ui.m2y_spin);
- tie_setting(s.m02_z, ui.m2z_spin);
-
- tie_setting(s.t_MH_x, ui.tx_spin);
- tie_setting(s.t_MH_y, ui.ty_spin);
- tie_setting(s.t_MH_z, ui.tz_spin);
-
- connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) );
- connect(ui.reset_button, SIGNAL(clicked()), this, SLOT(doReset()));
-
- connect(ui.ok_button, SIGNAL(clicked()), this, SLOT(doOK()));
- connect(ui.cancel_button, SIGNAL(clicked()), this, SLOT(doCancel()));
- connect(ui.btnApply, SIGNAL(clicked()), this, SLOT(doApply()));
-
- ui.model_tabs->setCurrentIndex(s.active_model_panel);
-
- connect(ui.model_tabs, SIGNAL(currentChanged(int)), this, SLOT(set_model(int)));
- connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info()));
- timer.start(100);
-
- connect(s.b.get(), SIGNAL(bundleChanged()), this, SLOT(do_apply_without_saving()));
-}
-
-void TrackerDialog::set_model_clip()
-{
- s.m01_x = 0;
- s.m01_y = static_cast<double>(s.clip_ty);
- s.m01_z = -static_cast<double>(s.clip_tz);
- s.m02_x = 0;
- s.m02_y = -static_cast<double>(s.clip_by);
- s.m02_z = -static_cast<double>(s.clip_bz);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_cap()
-{
- s.m01_x = -static_cast<double>(s.cap_x);
- s.m01_y = -static_cast<double>(s.cap_y);
- s.m01_z = -static_cast<double>(s.cap_z);
- s.m02_x = static_cast<double>(s.cap_x);
- s.m02_y = -static_cast<double>(s.cap_y);
- s.m02_z = -static_cast<double>(s.cap_z);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_custom()
-{
- settings_changed();
-}
-
-void TrackerDialog::set_model(int val)
-{
- s.active_model_panel = val;
-}
-
-void TrackerDialog::startstop_trans_calib(bool start)
-{
- if (start)
- {
- qDebug()<<"TrackerDialog:: Starting translation calibration";
- trans_calib.reset();
- trans_calib_running = true;
- }
- else
- {
- qDebug()<<"TrackerDialog:: Stoppping translation calibration";
- trans_calib_running = false;
- {
- auto tmp = trans_calib.get_estimate();
- s.t_MH_x = tmp[0];
- s.t_MH_y = tmp[1];
- s.t_MH_z = tmp[2];
- }
- settings_changed();
- }
-}
-
-void TrackerDialog::trans_calib_step()
-{
- if (tracker)
- {
- FrameTrafo X_CM;
- tracker->get_pose(&X_CM);
- trans_calib.update(X_CM.R, X_CM.t);
- cv::Vec3f t_MH = trans_calib.get_estimate();
- s.t_MH_x = t_MH[0];
- s.t_MH_y = t_MH[1];
- s.t_MH_z = t_MH[2];
- }
-}
-
-void TrackerDialog::settings_changed()
-{
- if (tracker) tracker->apply(s);
-}
-
-void TrackerDialog::doCenter()
-{
- if (tracker) tracker->center();
-}
-
-void TrackerDialog::doReset()
-{
- if (tracker) tracker->reset();
-}
-
-void TrackerDialog::save()
-{
- do_apply_without_saving();
- s.b->save();
-}
-
-void TrackerDialog::doOK()
-{
- save();
- close();
-}
-
-void TrackerDialog::do_apply_without_saving()
-{
- switch (s.active_model_panel) {
- default:
- case 0:
- set_model_clip();
- break;
- case 1:
- set_model_cap();
- break;
- case 2:
- set_model_custom();
- break;
- }
- if (tracker) tracker->apply(s);
-}
-
-void TrackerDialog::doApply()
-{
- save();
-}
-
-void TrackerDialog::doCancel()
-{
- s.b->revert();
- close();
-}
-
-void TrackerDialog::widget_destroyed(QObject* obj)
-{
- if (obj == video_widget_dialog) {
- // widget was / will be already deleted by Qt
- destroy_video_widget(false);
- }
-}
-
-void TrackerDialog::create_video_widget()
-{
- // this should not happen but better be sure
- if (video_widget_dialog) destroy_video_widget();
- if (!tracker) return;
-
- video_widget_dialog = new VideoWidgetDialog(this, tracker);
- video_widget_dialog->setAttribute( Qt::WA_DeleteOnClose );
- connect( video_widget_dialog, SIGNAL(destroyed(QObject*)), this, SLOT(widget_destroyed(QObject*)) );
- video_widget_dialog->show();
-}
-
-void TrackerDialog::destroy_video_widget(bool do_delete /*= true*/)
-{
- if (video_widget_dialog) {
- if (do_delete) delete video_widget_dialog;
- video_widget_dialog = NULL;
- }
-}
-
-void TrackerDialog::poll_tracker_info()
-{
- if (tracker)
- {
- QString to_print;
-
- // display caminfo
- CamInfo info;
- tracker->get_cam_info(&info);
- to_print = QString::number(info.res_x)+"x"+QString::number(info.res_y)+" @ "+QString::number(info.fps)+" FPS";
- ui.caminfo_label->setText(to_print);
-
- // display pointinfo
- int n_points = tracker->get_n_points();
- to_print = QString::number(n_points);
- if (n_points == 3)
- to_print += " OK!";
- else
- to_print += " BAD!";
- ui.pointinfo_label->setText(to_print);
-
- // update calibration
- if (trans_calib_running) trans_calib_step();
-
- // update videowidget
- if (video_widget_dialog) {
- video_widget_dialog->get_video_widget()->update_frame_and_points();
- }
- }
- else
- {
- QString to_print = "Tracker offline";
- ui.caminfo_label->setText(to_print);
- ui.pointinfo_label->setText(to_print);
- }
-}
-
-void TrackerDialog::registerTracker(ITracker *t)
-{
- qDebug()<<"TrackerDialog:: Tracker registered";
- tracker = static_cast<Tracker*>(t);
- if (isVisible() & s.b->modifiedp())
- tracker->apply(s);
- ui.tcalib_button->setEnabled(true);
- //ui.center_button->setEnabled(true);
- ui.reset_button->setEnabled(true);
-}
-
-void TrackerDialog::unRegisterTracker()
-{
- qDebug()<<"TrackerDialog:: Tracker un-registered";
- tracker = NULL;
- destroy_video_widget();
- ui.tcalib_button->setEnabled(false);
- //ui.center_button->setEnabled(false);
- ui.reset_button->setEnabled(false);
-}
-
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
-{
- return new TrackerDialog;
-}
diff --git a/FTNoIR_Tracker_PT/point_extractor.h b/FTNoIR_Tracker_PT/point_extractor.h
deleted file mode 100644
index ff36f3ce..00000000
--- a/FTNoIR_Tracker_PT/point_extractor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef POINTEXTRACTOR_H
-#define POINTEXTRACTOR_H
-
-#include <opencv2/opencv.hpp>
-#include <opencv2/imgproc/imgproc_c.h>
-
-// ----------------------------------------------------------------------------
-// Extracts points from an opencv image
-class PointExtractor
-{
-public:
- // extracts points from frame and draws some processing info into frame, if draw_output is set
- // dt: time since last call in seconds
- // WARNING: returned reference is valid as long as object
- const std::vector<cv::Vec2f>& extract_points(cv::Mat frame, float dt, bool draw_output);
- const std::vector<cv::Vec2f>& get_points() { return points; }
- PointExtractor();
-
- int threshold_val;
- int threshold_secondary_val;
- int min_size, max_size;
-
-protected:
- std::vector<cv::Vec2f> points;
- cv::Mat frame_last;
-};
-
-#endif //POINTEXTRACTOR_H
diff --git a/FTNoIR_Tracker_PT/point_tracker.cpp b/FTNoIR_Tracker_PT/point_tracker.cpp
deleted file mode 100644
index dfefdaf8..00000000
--- a/FTNoIR_Tracker_PT/point_tracker.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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 "point_tracker.h"
-
-#include <vector>
-#include <algorithm>
-#include <cmath>
-
-#include <QDebug>
-
-using namespace cv;
-using namespace boost;
-using namespace std;
-
-const float PI = 3.14159265358979323846f;
-
-// ----------------------------------------------------------------------------
-static void get_row(const Matx33f& m, int i, Vec3f& v)
-{
- v[0] = m(i,0);
- v[1] = m(i,1);
- v[2] = m(i,2);
-}
-
-static void set_row(Matx33f& m, int i, const Vec3f& v)
-{
- m(i,0) = v[0];
- m(i,1) = v[1];
- m(i,2) = v[2];
-}
-
-// ----------------------------------------------------------------------------
-PointModel::PointModel(Vec3f M01, Vec3f M02)
- : M01(M01),
- M02(M02)
-{
- // calculate u
- u = M01.cross(M02);
- u /= norm(u);
-
- // calculate projection matrix on M01,M02 plane
- float s11 = M01.dot(M01);
- float s12 = M01.dot(M02);
- float s22 = M02.dot(M02);
- P = 1.0/(s11*s22-s12*s12) * Matx22f(s22, -s12,
- -s12, s11);
-
- // calculate d and d_order for simple freetrack-like point correspondence
- vector<Vec2f> points;
- points.push_back(Vec2f(0,0));
- points.push_back(Vec2f(M01[0], M01[1]));
- points.push_back(Vec2f(M02[0], M02[1]));
- // fit line to orthographically projected points
- // ERROR: yields wrong results with colinear points?!
- /*
- Vec4f line;
- fitLine(points, line, CV_DIST_L2, 0, 0.01, 0.01);
- d[0] = line[0]; d[1] = line[1];
- */
- // TODO: fix this
- d = Vec2f(M01[0]-M02[0], M01[1]-M02[1]);
-
- // sort model points
- get_d_order(points, d_order);
-}
-
-#ifdef OPENTRACK_API
-static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b)
-{
- return a.first < b.first;
-}
-#endif
-
-void PointModel::get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const
-{
- // get sort indices with respect to d scalar product
- vector< pair<float,int> > d_vals;
- for (int i = 0; i<points.size(); ++i)
- d_vals.push_back(pair<float, int>(d.dot(points[i]), i));
-
- struct
- {
- bool operator()(const pair<float, int>& a, const pair<float, int>& b) { return a.first < b.first; }
- } comp;
- std::sort(d_vals.begin(),
- d_vals.end(),
-#ifdef OPENTRACK_API
- d_vals_sort
-#else
- comp
-#endif
- );
-
- for (int i = 0; i<points.size(); ++i)
- d_order[i] = d_vals[i].second;
-}
-
-
-// ----------------------------------------------------------------------------
-PointTracker::PointTracker()
- : init_phase(true),
- dt_valid(0),
- dt_reset(1),
- v_t(0,0,0),
- v_r(0,0,0),
- dynamic_pose_resolution(true)
-{
- X_CM.t[2] = 1000; // default position: 1 m away from cam;
-}
-
-void PointTracker::reset()
-{
- // enter init phase and reset velocities
- init_phase = true;
- dt_valid = 0;
- reset_velocities();
-}
-
-void PointTracker::reset_velocities()
-{
- v_t = Vec3f(0,0,0);
- v_r = Vec3f(0,0,0);
-}
-
-
-bool PointTracker::track(const vector<Vec2f>& points, float f, float dt)
-{
- if (!dynamic_pose_resolution) init_phase = true;
-
- dt_valid += dt;
- // if there was no valid tracking result for too long, do a reset
- if (dt_valid > dt_reset)
- {
- //qDebug()<<"dt_valid "<<dt_valid<<" > dt_reset "<<dt_reset;
- reset();
- }
-
- bool no_model =
-#ifdef OPENTRACK_API
- point_model.get() == NULL;
-#else
- !point_model;
-#endif
-
- // if there is a pointtracking problem, reset the velocities
- if (no_model || points.size() != PointModel::N_POINTS)
- {
- //qDebug()<<"Wrong number of points!";
- reset_velocities();
- return false;
- }
-
- X_CM_old = X_CM; // backup old transformation for velocity calculation
-
- if (!init_phase)
- predict(dt_valid);
-
- // if there is a point correspondence problem something has gone wrong, do a reset
- if (!find_correspondences(points, f))
- {
- //qDebug()<<"Error in finding point correspondences!";
- X_CM = X_CM_old; // undo prediction
- reset();
- return false;
- }
-
- int n_iter = POSIT(f);
- //qDebug()<<"Number of POSIT iterations: "<<n_iter;
-
- if (!init_phase)
- update_velocities(dt_valid);
-
- // we have a valid tracking result, leave init phase and reset time since valid result
- init_phase = false;
- dt_valid = 0;
- return true;
-}
-
-void PointTracker::predict(float dt)
-{
- // predict with constant velocity
- Matx33f R;
- Rodrigues(dt*v_r, R);
- X_CM.R = R*X_CM.R;
- X_CM.t += dt * v_t;
-}
-
-void PointTracker::update_velocities(float dt)
-{
- // update velocities
- Rodrigues(X_CM.R*X_CM_old.R.t(), v_r);
- v_r /= dt;
- v_t = (X_CM.t - X_CM_old.t)/dt;
-}
-
-bool PointTracker::find_correspondences(const vector<Vec2f>& points, float f)
-{
- if (init_phase) {
- // We do a simple freetrack-like sorting in the init phase...
- // sort points
- int point_d_order[PointModel::N_POINTS];
- point_model->get_d_order(points, point_d_order);
-
- // set correspondences
- for (int i=0; i<PointModel::N_POINTS; ++i)
- {
- p[point_model->d_order[i]] = points[point_d_order[i]];
- }
- }
- else {
- // ... otherwise we look at the distance to the projection of the expected model points
- // project model points under current pose
- p_exp[0] = project(Vec3f(0,0,0), f);
- p_exp[1] = project(point_model->M01, f);
- p_exp[2] = project(point_model->M02, f);
-
- // set correspondences by minimum distance to projected model point
- bool point_taken[PointModel::N_POINTS];
- for (int i=0; i<PointModel::N_POINTS; ++i)
- point_taken[i] = false;
-
- float min_sdist = 0;
- int min_idx = 0;
-
- for (int i=0; i<PointModel::N_POINTS; ++i)
- {
- // find closest point to projected model point i
- for (int j=0; j<PointModel::N_POINTS; ++j)
- {
- Vec2f d = p_exp[i]-points[j];
- float sdist = d.dot(d);
- if (sdist < min_sdist || j==0)
- {
- min_idx = j;
- min_sdist = sdist;
- }
- }
- // if one point is closest to more than one model point, abort
- if (point_taken[min_idx]) return false;
- point_taken[min_idx] = true;
- p[i] = points[min_idx];
- }
- }
- return true;
-}
-
-
-
-int PointTracker::POSIT(float f)
-{
- // POSIT algorithm for coplanar points as presented in
- // [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
- // we use the same notation as in the paper here
-
- // The expected rotation used for resolving the ambiguity in POSIT:
- // In every iteration step the rotation closer to R_expected is taken
- Matx33f R_expected;
- if (init_phase)
- R_expected = Matx33f::eye(); // in the init phase, we want to be close to the default pose = no rotation
- else
- R_expected = X_CM.R; // later we want to be close to the last (predicted) rotation
-
- // initial pose = last (predicted) pose
- Vec3f k;
- get_row(R_expected, 2, k);
- float Z0 = init_phase ? 1000 : X_CM.t[2];
-
- float old_epsilon_1 = 0;
- float old_epsilon_2 = 0;
- float epsilon_1 = 1;
- float epsilon_2 = 1;
-
- Vec3f I0, J0;
- Vec2f I0_coeff, J0_coeff;
-
- Vec3f I_1, J_1, I_2, J_2;
- Matx33f R_1, R_2;
- Matx33f* R_current;
-
- const int MAX_ITER = 100;
- const float EPS_THRESHOLD = 1e-4;
-
- int i=1;
- for (; i<MAX_ITER; ++i)
- {
- epsilon_1 = k.dot(point_model->M01)/Z0;
- epsilon_2 = k.dot(point_model->M02)/Z0;
-
- // vector of scalar products <I0, M0i> and <J0, M0i>
- Vec2f I0_M0i(p[1][0]*(1.0 + epsilon_1) - p[0][0],
- p[2][0]*(1.0 + epsilon_2) - p[0][0]);
- Vec2f J0_M0i(p[1][1]*(1.0 + epsilon_1) - p[0][1],
- p[2][1]*(1.0 + epsilon_2) - p[0][1]);
-
- // construct projection of I, J onto M0i plane: I0 and J0
- I0_coeff = point_model->P * I0_M0i;
- J0_coeff = point_model->P * J0_M0i;
- I0 = I0_coeff[0]*point_model->M01 + I0_coeff[1]*point_model->M02;
- J0 = J0_coeff[0]*point_model->M01 + J0_coeff[1]*point_model->M02;
-
- // calculate u component of I, J
- float II0 = I0.dot(I0);
- float IJ0 = I0.dot(J0);
- float JJ0 = J0.dot(J0);
- float rho, theta;
- if (JJ0 == II0) {
- rho = sqrt(abs(2*IJ0));
- theta = -PI/4;
- if (IJ0<0) theta *= -1;
- }
- else {
- rho = sqrt(sqrt( (JJ0-II0)*(JJ0-II0) + 4*IJ0*IJ0 ));
- theta = atan( -2*IJ0 / (JJ0-II0) );
- if (JJ0 - II0 < 0) theta += PI;
- theta /= 2;
- }
-
- // construct the two solutions
- I_1 = I0 + rho*cos(theta)*point_model->u;
- I_2 = I0 - rho*cos(theta)*point_model->u;
-
- J_1 = J0 + rho*sin(theta)*point_model->u;
- J_2 = J0 - rho*sin(theta)*point_model->u;
-
- float norm_const = 1.0/norm(I_1); // all have the same norm
-
- // create rotation matrices
- I_1 *= norm_const; J_1 *= norm_const;
- I_2 *= norm_const; J_2 *= norm_const;
-
- set_row(R_1, 0, I_1);
- set_row(R_1, 1, J_1);
- set_row(R_1, 2, I_1.cross(J_1));
-
- set_row(R_2, 0, I_2);
- set_row(R_2, 1, J_2);
- set_row(R_2, 2, I_2.cross(J_2));
-
- // the single translation solution
- Z0 = norm_const * f;
-
- // pick the rotation solution closer to the expected one
- // in simple metric d(A,B) = || I - A * B^T ||
- float R_1_deviation = norm(Matx33f::eye() - R_expected * R_1.t());
- float R_2_deviation = norm(Matx33f::eye() - R_expected * R_2.t());
-
- if (R_1_deviation < R_2_deviation)
- R_current = &R_1;
- else
- R_current = &R_2;
-
- get_row(*R_current, 2, k);
-
- // check for convergence condition
- if (abs(epsilon_1 - old_epsilon_1) + abs(epsilon_2 - old_epsilon_2) < EPS_THRESHOLD)
- break;
- old_epsilon_1 = epsilon_1;
- old_epsilon_2 = epsilon_2;
- }
-
- // apply results
- X_CM.R = *R_current;
- X_CM.t[0] = p[0][0] * Z0/f;
- X_CM.t[1] = p[0][1] * Z0/f;
- X_CM.t[2] = Z0;
-
- return i;
-
- //Rodrigues(X_CM.R, r);
- //qDebug()<<"iter: "<<i;
- //qDebug()<<"t: "<<X_CM.t[0]<<' '<<X_CM.t[1]<<' '<<X_CM.t[2];
- //Vec3f r;
- //
- //qDebug()<<"r: "<<r[0]<<' '<<r[1]<<' '<<r[2]<<'\n';
-}
diff --git a/FTNoIR_Tracker_PT/point_tracker.h b/FTNoIR_Tracker_PT/point_tracker.h
deleted file mode 100644
index 11034100..00000000
--- a/FTNoIR_Tracker_PT/point_tracker.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef POINTTRACKER_H
-#define POINTTRACKER_H
-
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <list>
-
-// ----------------------------------------------------------------------------
-// Affine frame trafo
-class FrameTrafo
-{
-public:
- FrameTrafo() : R(cv::Matx33f::eye()), t(0,0,0) {}
- FrameTrafo(const cv::Matx33f& R, const cv::Vec3f& t) : R(R),t(t) {}
-
- cv::Matx33f R;
- cv::Vec3f t;
-};
-
-inline FrameTrafo operator*(const FrameTrafo& X, const FrameTrafo& Y)
-{
- return FrameTrafo(X.R*Y.R, X.R*Y.t + X.t);
-}
-
-inline FrameTrafo operator*(const cv::Matx33f& X, const FrameTrafo& Y)
-{
- return FrameTrafo(X*Y.R, X*Y.t);
-}
-
-inline FrameTrafo operator*(const FrameTrafo& X, const cv::Matx33f& Y)
-{
- return FrameTrafo(X.R*Y, X.t);
-}
-
-inline cv::Vec3f operator*(const FrameTrafo& X, const cv::Vec3f& v)
-{
- return X.R*v + X.t;
-}
-
-
-// ----------------------------------------------------------------------------
-// Describes a 3-point model
-// nomenclature as in
-// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
-class PointModel
-{
- friend class PointTracker;
-public:
- static const int N_POINTS = 3;
-
- PointModel(cv::Vec3f M01, cv::Vec3f M02);
-
- const cv::Vec3f& get_M01() const { return M01; };
- const cv::Vec3f& get_M02() const { return M02; };
-
-protected:
- cv::Vec3f M01; // M01 in model frame
- cv::Vec3f M02; // M02 in model frame
-
- cv::Vec3f u; // unit vector perpendicular to M01,M02-plane
-
- cv::Matx22f P;
-
- cv::Vec2f d; // discriminant vector for point correspondence
- int d_order[3]; // sorting of projected model points with respect to d scalar product
-
- void get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const;
-};
-
-// ----------------------------------------------------------------------------
-// Tracks a 3-point model
-// implementing the POSIT algorithm for coplanar points as presented in
-// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
-class PointTracker
-{
-public:
- PointTracker();
-
- // track the pose using the set of normalized point coordinates (x pos in range -0.5:0.5)
- // f : (focal length)/(sensor width)
- // dt : time since last call
- bool track(const std::vector<cv::Vec2f>& points, float f, float dt);
- boost::shared_ptr<PointModel> point_model;
-
- bool dynamic_pose_resolution;
- float dt_reset;
-
- FrameTrafo get_pose() const { return X_CM; }
- void reset();
-
-protected:
- inline cv::Vec2f project(const cv::Vec3f& v_M, float f)
- {
- cv::Vec3f v_C = X_CM * v_M;
- return cv::Vec2f(f*v_C[0]/v_C[2], f*v_C[1]/v_C[2]);
- }
-
- bool find_correspondences(const std::vector<cv::Vec2f>& points, float f);
-
- cv::Vec2f p[PointModel::N_POINTS]; // the points in model order
- cv::Vec2f p_exp[PointModel::N_POINTS]; // the expected point positions
-
- void predict(float dt);
- void update_velocities(float dt);
- void reset_velocities();
-
-
- int POSIT(float f); // The POSIT algorithm, returns the number of iterations
-
- bool init_phase;
- float dt_valid; // time since last valid tracking result
- cv::Vec3f v_t; // velocities
- cv::Vec3f v_r;
- FrameTrafo X_CM; // trafo from model to camera
- FrameTrafo X_CM_old;
-};
-
-#endif //POINTTRACKER_H
diff --git a/README.md b/README.md
index 04704cfe..a362b136 100644
--- a/README.md
+++ b/README.md
@@ -43,17 +43,14 @@ Don't be afraid to submit an issue/feature request if the need arises.
# Credits
-- Stanisław Halik
+- Stanisław Halik (maintainer)
- Chris Thompson (aka mm0zct)
-- Donovan Baarda
+- Donovan Baarda (filtering/control theory expert)
- Ryan Spicer (OSX tester, contributor)
- Patrick Ruoff (PT tracker)
-- FuraX49 (hatire arduino tracker)
- Ulf Schreiber (PT tracker)
- uglyDwarf (high CON)
-- George Trigonakis (tester)
- Wim Vriend (historically)
-- Ron Hendriks (historically)
# Licensing information
diff --git a/TODO.txt b/TODO.txt
deleted file mode 100644
index e9eb232a..00000000
--- a/TODO.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-20131023 sh
- Low-hanging fruit: Go through all forms and replace ok/cancel with
- QButtonBox which works better with layouts.
-20131020 sh
- Add unit testing by means of batch execution, protocol/filter that does
- nothing, add separate executables for readers of specific protocols,
- and run continuous integration every time commit happens that day.
-
- Add statically-typed settings trees, convert result to qsettings-enabled
- ini files. Use metadata props in order to get class name for ini section.
- Required here are also arrays of settings. Use QList<T> for template
- specialization.
-20131019 mm0zct
- Ship more then one profile for configuring the curves etc.
- There are two main user bases, HMD and traditional monitor+webcam users,
- each wants a drastically different curve profile (HMD is 1:1 on all axes)
- Also re:boost, I'd rather avoid extra library dependences if possible.
-
- Rift tracker could do with positional estimation using intertial sensors.
- Rift could do with a return-yaw-to-centre hotkey that's not the global all-axis option.
- Hydra is really just a hack just now, could be improved a lot.
-
- Add per-tracker hotkey support
-20131011 sh
- low-hanging fruit: default saving profiles to a directory in user home,
- not into global stuffies
-
- as for build system, low-hanging fruit is writing functions/macrology
- for all the repetition out there.
diff --git a/bin/settings/facetracknoir supported games.csv b/bin/settings/facetracknoir supported games.csv
index 91b9e6e6..4052806b 100644
--- a/bin/settings/facetracknoir supported games.csv
+++ b/bin/settings/facetracknoir supported games.csv
@@ -1,519 +1,527 @@
No;Game Name;Game protocol;Supported since;Verified;By;INTERNATIONAL_ID;FTN_ID
-1;18 Wheels of Steel: Haulin';FreeTrack20;V160;V;doc-uk;13601;000121F172F35116A02100
-2;1944 D-Day;FreeTrack20;V160;;;15701;00022E542A6A0575F05200
-497;2KMarinNEXT;FreeTrack20;V170;;;3425;0D614F6A0820D1EA8EE800
-3;3D Instructor;FreeTrack20;V160;;;20490;00034B0FC367116611B100
-4;3D Interactive;FreeTrack20;V160;;;20425;0004C6371D77135815A600
+1;18 Wheels of Steel: Haulin';FreeTrack20;V160;V;doc-uk;13601;000121F172F35116A02100
+2;1944 D-Day;FreeTrack20;V160;;;15701;00022E542A6A0575F05200
+497;2KMarinNEXT;FreeTrack20;V170;;;3425;0D614F6A0820D1EA8EE800
+3;3D Instructor;FreeTrack20;V160;;;20490;00034B0FC367116611B100
+4;3D Interactive;FreeTrack20;V160;;;20425;0004C6371D77135815A600
505;3D Interieur Visualisation;FreeTrack20;V160;;;20815;01F9EDEE75DAC2968D9A00
-5;3d Nav;FreeTrack20;V160;;;20235;000579EC0E26932651EA00
-6;3D-Fahrschule Driving Simulator;FreeTrack20;V160;;;20020;000601075146E0E9625B00
-7;3ds Max;FreeTrack20;V160;;;8601;00077A32A1A7523A4DE700
-8;Aaaaa!;FreeTrack20;V160;;;1775;00085485D831DA62CA7E00
-9;Accessible Computer Games;FreeTrack20;V160;;;4301;000916BC07A2F9B35B6300
-10;Aces High II;FreeTrack20;V160;V;bash1;2701;000A4B798B7221A72E5800
-11;ADS;FreeTrack20;V160;;;20690;000BB25377780C8A894400
-12;Aerofly FS;FreeTrack20;V160;V;V4Friend;2025;000C3797169752CAB39A00
-13;Affineon;FreeTrack20;V160;;;20405;000D662B0374339635A000
-14;Air Battles: Sky Defender;FreeTrack20;V160;;;7003;000E7C822098630A2ED700
-15;Air Phobia;FreeTrack20;V160;;;20100;000F0108339B3E78525B00
-16;Air Traffic Control Tower;FreeTrack20;V160;;;3601;0010432C28637A8EF97400
-17;AirBook;FreeTrack20;V160;;;15201;0011D615A9C8430A201A00
-18;America's Army;FreeTrack20;V160;;;4101;00120BCF5753D98399E200
-19;America's Army 3;FreeTrack20;V170;;;14203;00133F3206BCEA252BB700
-20;ANAG 3D;FreeTrack20;V160;;;20250;0014E2D1D7780A72166300
-21;Apache: Air Assault;FreeTrack20;V160;V;paleta77;1875;001591D997A2D912AAA200
-22;Aprisoft Gartenplaner;FreeTrack20;V160;;;20014;0016F2F27A5762FA937A00
-23;Aprisoft Traumhaus Designer;FreeTrack20;V160;;;20013;00174655E792BB825B9300
+5;3d Nav;FreeTrack20;V160;;;20235;000579EC0E26932651EA00
+6;3D-Fahrschule Driving Simulator;FreeTrack20;V160;;;20020;000601075146E0E9625B00
+7;3ds Max;FreeTrack20;V160;;;8601;00077A32A1A7523A4DE700
+8;Aaaaa!;FreeTrack20;V160;;;1775;00085485D831DA62CA7E00
+9;Accessible Computer Games;FreeTrack20;V160;;;4301;000916BC07A2F9B35B6300
+10;Aces High II;FreeTrack20;V160;V;bash1;2701;000A4B798B7221A72E5800
+11;ADS;FreeTrack20;V160;;;20690;000BB25377780C8A894400
+12;Aerofly FS;FreeTrack20;V160;V;V4Friend;2025;000C3797169752CAB39A00
+13;Affineon;FreeTrack20;V160;;;20405;000D662B0374339635A000
+14;Air Battles: Sky Defender;FreeTrack20;V160;;;7003;000E7C822098630A2ED700
+15;Air Phobia;FreeTrack20;V160;;;20100;000F0108339B3E78525B00
+16;Air Traffic Control Tower;FreeTrack20;V160;;;3601;0010432C28637A8EF97400
+17;AirBook;FreeTrack20;V160;;;15201;0011D615A9C8430A201A00
+18;America's Army;FreeTrack20;V160;;;4101;00120BCF5753D98399E200
+19;America's Army 3;FreeTrack20;V170;;;14203;00133F3206BCEA252BB700
+20;ANAG 3D;FreeTrack20;V160;;;20250;0014E2D1D7780A72166300
+21;Apache: Air Assault;FreeTrack20;V160;V;paleta77;1875;001591D997A2D912AAA200
+519;Apex Motorsports;FreeTrack20;V160;;;3675;02078F3159271BBE676800
+22;Aprisoft Gartenplaner;FreeTrack20;V160;;;20014;0016F2F27A5762FA937A00
+23;Aprisoft Traumhaus Designer;FreeTrack20;V160;;;20013;00174655E792BB825B9300
498;ARI;FreeTrack20;V160;;;20795;01F23FB9A61044E206E200
-24;ArmA;FreeTrack20;V160;V;EmBeES;10601;0018F2F27A57631A40F200
-25;ArmA 2;FreeTrack20;V170;V;V4Friend, Ronski;7502;0019EB3616B3A44F05B900
-26;ArmA 2 Operation Arrowhead;FreeTrack20;V160;V;vn88holden;0;001ABC224B7783DAF0D500
-27;ArmA 3;FreeTrack20;V170;;;7503;001BB69411ABD4E2B39900
-28;Armored Assault - Gold Edition;FreeTrack20;V170;;;1303;001CA7F7CAA00814ECA700
-29;Arvoch Alliance;FreeTrack20;V160;;;14908;001D318F8773BAE29A9300
-30;Arvoch Conflict;FreeTrack20;V160;;;14901;001E5C1FDE722DAE2BA900
-31;Auditory Displays for the blind;FreeTrack20;V160;;;20035;001F0FC9FF862F9D34BA00
-486;Autodesk;FreeTrack20;V160;;;20755;01E6953FA7F759AF33AC00
-32;AV Core Technology;FreeTrack20;V160;;;20016;00204655E791166FEB5300
-33;AVRS;FreeTrack20;V160;;;20340;0021231517525830F41D00
-482;B.O.M.B.;FreeTrack20;V160;;;3325;01E248ECCB81191AD49F00
-34;BAE Systems HILAS cockpit;FreeTrack20;V160;;;20019;00220D9C887FD88E98B300
-35;Battle of Britain (iENT);FreeTrack20;V170;;;1305;00230BA119195B701AED00
-36;Battle of Britain II - Wings of Victory;FreeTrack20;V160;V;Normalguy;7001;002452135882CA6419E200
-37;Battlecruiser;FreeTrack20;V160;;;6101;00257C822098728A442900
-38;Battlefield 2;FreeTrack20;V170;;;9601;0026B1560A2A7327659200
-39;Battlefield 2 Trauma Studios;FreeTrack20;V160;;;6501;002720C7529B733AE2EA00
-40;Battlefield 2142;FreeTrack20;V170;;;9602;00281C739AD3817FD43300
-41;Battleground Europe : World War II Online;FreeTrack20;V160;;;3301;0029F07957792CAD3DAF00
-42;Battleground Europe : WWII Online;FreeTrack20;V160;;;11201;002A985017330A844A1200
-43;Beckman Institute UIUC;FreeTrack20;V160;;;20012;002BB59DEFA8322A926A00
-44;Beyond The Red Line;FreeTrack20;V160;;;13301;002CE7A7FAA27424BA2A00
-45;BF2 (Unsupported Demo);FreeTrack20;V160;;;9651;002DC6371D86156AEB6000
-46;Big Scale Racing;FreeTrack20;V160;;;8301;002E4655E7A24ADDB99200
-47;Birds of Prey;FreeTrack20;V160;;;1601;002FBF8C4EAA57730B3200
-48;Birds of Steel;FreeTrack20;V160;;;1878;0030D7690F607233A21E00
-49;Boeing;FreeTrack20;V160;;;20351;0031044872BA630A033E00
-50;Boeing Demo;FreeTrack20;V160;;;20350;003228C57B369A37B13600
-51;Bomber Squadron;FreeTrack20;V160;;;1850;00338481733B9E32A83A00
-52;Brain-IT Group;FreeTrack20;V160;;;20050;0034E482F5772C9330B100
-53;Brothers In Arms;FreeTrack20;V160;;;13501;003503FB872CA8439D1F00
-82;C-Spine;FreeTrack20;V160;;;4901;00525FD692C188FB8B2D00
-54;C.A.R.S.;FreeTrack20;V170;;;2825;003698EFE2EB6EE8E11300
-55;C.U.B.;FreeTrack20;V160;;;20505;0037848174F986FD85F500
-56;CameraGripTools;FreeTrack20;V160;;;20150;003870A8B761FA524A4200
-57;Caterpillar Simulators;FreeTrack20;V160;;;23080;0039F52E4221742FA63100
-58;CCG Metamedia;FreeTrack20;V160;;;20009;003A6FA8A8DD86FE8BDB00
-59;CEWIT Immersive Cabin;FreeTrack20;V160;;;20370;003B90B5780C90078DEE00
-60;Chopper;FreeTrack20;V160;;;3150;003CC166C8632A32EA2300
-61;Clearbox;FreeTrack20;V160;;;20565;003D5C1FDE74279D1DB800
-62;CNKFsoft;FreeTrack20;V160;;;20495;003ED7690F6073187B0000
-487;Cognitics;FreeTrack20;V160;;;20760;01E715A96D19515BFC1500
-63;Colin McRae DiRT 2;FreeTrack20;V170;V;V4Friend;8107;003F7815C5379491C73300
-64;Colin McRae Rally 04;FreeTrack20;V160;;;8103;0040D13C2A843DA526A610
-65;Comanche;FreeTrack20;V160;;;2275;00414097C36A12BA32BA00
-66;Combat Flight Simulator 3;FreeTrack20;V160;V;V4Friend;2304;00420EC5F763AB21CA7310
-67;Combat Helo;FreeTrack20;V160;;;2001;004329DFA863FAE1EA7300
+24;ArmA;FreeTrack20;V160;V;EmBeES;10601;0018F2F27A57631A40F200
+25;ArmA 2;FreeTrack20;V170;V;V4Friend Ronski;7502;0019EB3616B3A44F05B900
+26;ArmA 2 Operation Arrowhead;FreeTrack20;V160;V;vn88holden;0;001ABC224B7783DAF0D500
+27;ArmA 3;FreeTrack20;V170;;;7503;001BB69411ABD4E2B39900
+28;Armored Assault - Gold Edition;FreeTrack20;V170;;;1303;001CA7F7CAA00814ECA700
+29;Arvoch Alliance;FreeTrack20;V160;;;14908;001D318F8773BAE29A9300
+30;Arvoch Conflict;FreeTrack20;V160;;;14901;001E5C1FDE722DAE2BA900
+31;Auditory Displays for the blind;FreeTrack20;V160;;;20035;001F0FC9FF862F9D34BA00
+486;Autodesk;FreeTrack20;V160;;;20755;01E6953FA7F759AF33AC00
+32;AV Core Technology;FreeTrack20;V160;;;20016;00204655E791166FEB5300
+33;AVRS;FreeTrack20;V160;;;20340;0021231517525830F41D00
+482;B.O.M.B.;FreeTrack20;V160;;;3325;01E248ECCB81191AD49F00
+34;BAE Systems HILAS cockpit;FreeTrack20;V160;;;20019;00220D9C887FD88E98B300
+35;Battle of Britain (iENT);FreeTrack20;V170;;;1305;00230BA119195B701AED00
+36;Battle of Britain II - Wings of Victory;FreeTrack20;V160;V;Normalguy;7001;002452135882CA6419E200
+37;Battlecruiser;FreeTrack20;V160;;;6101;00257C822098728A442900
+38;Battlefield 2;FreeTrack20;V170;;;9601;0026B1560A2A7327659200
+39;Battlefield 2 Trauma Studios;FreeTrack20;V160;;;6501;002720C7529B733AE2EA00
+40;Battlefield 2142;FreeTrack20;V170;;;9602;00281C739AD3817FD43300
+41;Battleground Europe : World War II Online;FreeTrack20;V160;;;3301;0029F07957792CAD3DAF00
+42;Battleground Europe : WWII Online;FreeTrack20;V160;;;11201;002A985017330A844A1200
+43;Beckman Institute UIUC;FreeTrack20;V160;;;20012;002BB59DEFA8322A926A00
+44;Beyond The Red Line;FreeTrack20;V160;;;13301;002CE7A7FAA27424BA2A00
+45;BF2 (Unsupported Demo);FreeTrack20;V160;;;9651;002DC6371D86156AEB6000
+46;Big Scale Racing;FreeTrack20;V160;;;8301;002E4655E7A24ADDB99200
+47;Birds of Prey;FreeTrack20;V160;;;1601;002FBF8C4EAA57730B3200
+48;Birds of Steel;FreeTrack20;V160;;;1878;0030D7690F607233A21E00
+49;Boeing;FreeTrack20;V160;;;20351;0031044872BA630A033E00
+50;Boeing Demo;FreeTrack20;V160;;;20350;003228C57B369A37B13600
+51;Bomber Squadron;FreeTrack20;V160;;;1850;00338481733B9E32A83A00
+52;Brain-IT Group;FreeTrack20;V160;;;20050;0034E482F5772C9330B100
+53;Brothers In Arms;FreeTrack20;V160;;;13501;003503FB872CA8439D1F00
+82;C-Spine;FreeTrack20;V160;;;4901;00525FD692C188FB8B2D00
+54;C.A.R.S.;FreeTrack20;V170;;;2825;003698EFE2EB6EE8E11300
+55;C.U.B.;FreeTrack20;V160;;;20505;0037848174F986FD85F500
+56;CameraGripTools;FreeTrack20;V160;;;20150;003870A8B761FA524A4200
+57;Caterpillar Simulators;FreeTrack20;V160;;;23080;0039F52E4221742FA63100
+58;CCG Metamedia;FreeTrack20;V160;;;20009;003A6FA8A8DD86FE8BDB00
+59;CEWIT Immersive Cabin;FreeTrack20;V160;;;20370;003B90B5780C90078DEE00
+60;Chopper;FreeTrack20;V160;;;3150;003CC166C8632A32EA2300
+61;Clearbox;FreeTrack20;V160;;;20565;003D5C1FDE74279D1DB800
+62;CNKFsoft;FreeTrack20;V160;;;20495;003ED7690F6073187B0000
+487;Cognitics;FreeTrack20;V160;;;20760;01E715A96D19515BFC1500
+63;Colin McRae DiRT 2;FreeTrack20;V170;V;V4Friend;8107;003F7815C5379491C73300
+64;Colin McRae Rally 04;FreeTrack20;V160;;;8103;0040D13C2A843DA526A610
+65;Comanche;FreeTrack20;V160;;;2275;00414097C36A12BA32BA00
+66;Combat Flight Simulator 3;FreeTrack20;V160;V;V4Friend;2304;00420EC5F763AB21CA7310
+67;Combat Helo;FreeTrack20;V160;;;2001;004329DFA863FAE1EA7300
515;Combined Arms;FreeTrack20;V160;;;1309;0203387EDB1A5AFEADB600
-68;Commandos Strike Force;FreeTrack20;V160;;;8801;0044C1BBF892DB037A7200
-69;Concept RS;FreeTrack20;V160;;;10701;004537971697736A72DA00
-70;Condor: The Competitive Soaring Simulator;FreeTrack20;V160;V;MicheleF;5901;004670A8B762DA623A1300
-71;Conflict Taiwan;FreeTrack20;V160;;;1950;0047D7690F6073399E2000
-72;Corys;FreeTrack20;V160;;;20550;0048157D78738A342A8D00
-73;Counter Strike;FreeTrack20;V160;;;12501;004953FE1E862AB73DA600
-74;Crane Simulator;FreeTrack20;V160;;;20048;004A6B62C6A7931972DA00
-75;Crashday;FreeTrack20;V160;;;5601;004BD6E585F893D933BA00
-76;Creanex Training Simulator;FreeTrack20;V160;;;20205;004CF478D277A40A929A00
-77;Creative Labs headset;FreeTrack20;V160;;;20018;004D348B1743E961FA6300
-78;Cross Racing Championship;FreeTrack20;V160;;;4801;004E20C763AB232B5E8900
-79;Crysis Mod;FreeTrack20;V160;;;1625;004F90B57839B231A24200
-80;Crystal Growth Simulation;FreeTrack20;V160;;;20029;005026F79742FB241A6200
-81;Crytek;FreeTrack20;V170;;;2775;0051D5F1EBBAD81C714600
-83;D2x-XL;FreeTrack20;V160;;;16001;00532E20237BEDABEB8A00
-84;Dark Horizons Lore;FreeTrack20;V160;;;7901;005487801A852AA7385200
-85;Dawn of Aces - Gold Edition;FreeTrack20;V170;;;1304;0055A9ED7700814190DE00
-86;Dawn of Aces II;FreeTrack20;V160;;;1302;00566925967C2BB0285500
+68;Commandos Strike Force;FreeTrack20;V160;;;8801;0044C1BBF892DB037A7200
+69;Concept RS;FreeTrack20;V160;;;10701;004537971697736A72DA00
+70;Condor: The Competitive Soaring Simulator;FreeTrack20;V160;V;MicheleF;5901;004670A8B762DA623A1300
+71;Conflict Taiwan;FreeTrack20;V160;;;1950;0047D7690F6073399E2000
+72;Corys;FreeTrack20;V160;;;20550;0048157D78738A342A8D00
+73;Counter Strike;FreeTrack20;V160;;;12501;004953FE1E862AB73DA600
+74;Crane Simulator;FreeTrack20;V160;;;20048;004A6B62C6A7931972DA00
+75;Crashday;FreeTrack20;V160;;;5601;004BD6E585F893D933BA00
+76;Creanex Training Simulator;FreeTrack20;V160;;;20205;004CF478D277A40A929A00
+77;Creative Labs headset;FreeTrack20;V160;;;20018;004D348B1743E961FA6300
+78;Cross Racing Championship;FreeTrack20;V160;;;4801;004E20C763AB232B5E8900
+79;Crysis Mod;FreeTrack20;V160;;;1625;004F90B57839B231A24200
+80;Crystal Growth Simulation;FreeTrack20;V160;;;20029;005026F79742FB241A6200
+81;Crytek;FreeTrack20;V170;;;2775;0051D5F1EBBAD81C714600
+83;D2x-XL;FreeTrack20;V160;;;16001;00532E20237BEDABEB8A00
+84;Dark Horizons Lore;FreeTrack20;V160;;;7901;005487801A852AA7385200
+85;Dawn of Aces - Gold Edition;FreeTrack20;V170;;;1304;0055A9ED7700814190DE00
+86;Dawn of Aces II;FreeTrack20;V160;;;1302;00566925967C2BB0285500
513;Dawn of Aces/Red Baron;FreeTrack20;V160;;;1307;0201916C14F32918D9B800
-87;DBS WalkAndFollow;FreeTrack20;V160;;;2525;005770A8B77008BDE89200
-88;DCS: Black Shark;FreeTrack20;V170;V;EmBeES;1006;0058F688FC9B0556868F00
-89;DCS: A-10C Warthog (32 and 64 bit);FreeTrack20;V170;V;fabri91, Shadow;1003;0059B6DCD15F5A572F6500
-90;Dead Reckoning;FreeTrack20;V160;;;10401;005A4C2F6752F912D66200
-91;Delivery;FreeTrack20;V160;;;15901;005BF3E85B1A8534AE3400
-471;Demon Core;FreeTrack20;V160;;;3225;01D7D1DC6052A165A7AC00
-92;DiRT;FreeTrack20;V160;;;8104;005C72456F7523881F1800
-93;DiRT 3;FreeTrack20;V170;;;8108;005DABA016ED2DFBDF6F00
-94;Door3;FreeTrack20;V160;;;20665;005ED13C2A853DA82F6B00
-95;Down In Flames;FreeTrack20;V160;;;1025;005F29DFA873FB82A66000
-96;Driver Test;FreeTrack20;V160;;;20265;00609343487C3FAA429D00
-97;Driver's Republic;FreeTrack20;V160;;;14001;0061D24C3F8A3F9C33AB00
-98;DriveSim;FreeTrack20;V160;;;5001;0062DD7CC2B47830A14400
-99;Driving Simulator;FreeTrack20;V160;;;13001;00630AC67539AC3F9F3A00
-100;dSphere TBA;FreeTrack20;V160;;;2425;0064A2AE4981FB5389A300
-101;DTS;FreeTrack20;V160;;;20625;006505B37C12868B3E8500
-102;Dungeons and Dragons Online;FreeTrack20;V170;;;1575;0066BD4D4DDC6BB6818800
-103;DY Demo;FreeTrack20;V160;;;20345;006727D5047A15540F9D00
-104;EADS Testing;FreeTrack20;V160;;;20303;00680288709760D5512900
+87;DBS WalkAndFollow;FreeTrack20;V160;;;2525;005770A8B77008BDE89200
+88;DCS: Black Shark;FreeTrack20;V170;V;EmBeES;1006;0058F688FC9B0556868F00
+89;DCS: A-10C Warthog (32 and 64 bit);FreeTrack20;V170;V;fabri91 Shadow;1003;0059B6DCD15F5A572F6500
+90;Dead Reckoning;FreeTrack20;V160;;;10401;005A4C2F6752F912D66200
+91;Delivery;FreeTrack20;V160;;;15901;005BF3E85B1A8534AE3400
+471;Demon Core;FreeTrack20;V160;;;3225;01D7D1DC6052A165A7AC00
+92;DiRT;FreeTrack20;V160;;;8104;005C72456F7523881F1800
+93;DiRT 3;FreeTrack20;V170;;;8108;005DABA016ED2DFBDF6F00
+94;Door3;FreeTrack20;V160;;;20665;005ED13C2A853DA82F6B00
+95;Down In Flames;FreeTrack20;V160;;;1025;005F29DFA873FB82A66000
+96;Driver Test;FreeTrack20;V160;;;20265;00609343487C3FAA429D00
+97;Driver's Republic;FreeTrack20;V160;;;14001;0061D24C3F8A3F9C33AB00
+98;DriveSim;FreeTrack20;V160;;;5001;0062DD7CC2B47830A14400
+99;Driving Simulator;FreeTrack20;V160;;;13001;00630AC67539AC3F9F3A00
+100;dSphere TBA;FreeTrack20;V160;;;2425;0064A2AE4981FB5389A300
+101;DTS;FreeTrack20;V160;;;20625;006505B37C12868B3E8500
+102;Dungeons and Dragons Online;FreeTrack20;V170;;;1575;0066BD4D4DDC6BB6818800
+103;DY Demo;FreeTrack20;V160;;;20345;006727D5047A15540F9D00
+104;EADS Testing;FreeTrack20;V160;;;20303;00680288709760D5512900
504;EAFIT;FreeTrack20;V160;;;20810;01F8D2675ABC163E99B000
-105;Eagle Lander 3D;FreeTrack20;V160;;;11901;00697686E5A7B209C27900
-106;EasyVR;FreeTrack20;V160;;;20220;006A68292872FAC4588100
-107;ECA-Sindel;FreeTrack20;V160;;;20590;006BC5BEE479FD75FB8500
+105;Eagle Lander 3D;FreeTrack20;V160;;;11901;00697686E5A7B209C27900
+106;EasyVR;FreeTrack20;V160;;;20220;006A68292872FAC4588100
+107;ECA-Sindel;FreeTrack20;V160;;;20590;006BC5BEE479FD75FB8500
508;Elite: Dangerous;FreeTrack20;V170;;;3475;0D93A9485EECA12E18BE00
-481;Embers of Caerus;FreeTrack20;V170;;;3275;0CCB4134258D7E10119E00
-108;EMS Simulations;FreeTrack20;V160;;;20390;006CA59E687D1589DE8500
-109;Enemy Engaged 2;FreeTrack20;V160;;;2102;006D010873EA635AEDC800
-110;Enemy Engaged: Commanche vs Hokum;FreeTrack20;V160;;;2101;006E157D789379636AED00
-111;Envision TE;FreeTrack20;V160;;;20320;006FD13C2A863CAF26AB00
-112;EON Reality;FreeTrack20;V160;;;20410;0070B6C6142771F82EE900
-113;eSigma;FreeTrack20;V160;;;20700;0071950F9AA60DAD2E9F00
-114;Euro Truck Simulator;FreeTrack20;V160;V;mamsa;13602;00721B4BFF8B3EA3296600
-115;EVE Online;FreeTrack20;V160;;;11801;0073F47CC377C2388DC900
-116;Eventology;FreeTrack20;V160;;;12201;0074849F8B469C2BAC3600
-117;EVOC-101 Training;FreeTrack20;V160;;;20038;00756925967D2088FC6200
-118;Evochron Alliance 2.0;FreeTrack20;V160;;;14904;00767A32A1A8735A022900
-119;Evochron Legends;FreeTrack20;V160;;;14906;0077D6E585F8B41A12BA00
-120;Evochron Mercenary;FreeTrack20;V160;V;Scavenger4711 ;14907;00783752FBC7B42B221A00
-121;Evochron Renegades;FreeTrack20;V160;;;14905;0079621E7763FB421A1300
-122;EZCA;FreeTrack20;V160;V;dennison ;2475;007A6DBB52F7B147510601
-125;F-22 Total Air War;FreeTrack20;V160;;;1750;007D20C79F475F0621DB00
-126;F-35 PTA;FreeTrack20;V160;;;20185;007E26F7977E96C0352100
-148;F-Trainer;FreeTrack20;V160;;;20615;0094C6371D8AFB8C3E9900
-123;F1 2011/2012;FreeTrack20;V170;;;8109;007B265ECD74893EA12900
-124;F1 Challenge 99-02;FreeTrack20;V160;;;4401;007CA15F278FB660C9D210
-127;FAAC;FreeTrack20;V160;;;20500;007F0F00F489118300C000
-128;Farmer Simulator 2009;FreeTrack20;V160;;;1725;0080926ED8A1EB628AB300
-129;Faros Driving Simulator;FreeTrack20;V160;;;8001;0081B1C6647A1EA839A800
-130;Faubert Lab Car Simulator;FreeTrack20;V160;;;20480;00822E542A7F2DB61F9700
-131;Ferrari Virtual Academy;FreeTrack20;V160;V;sosna1983 ;0;0083C0AF8C24B62D974000
-132;FIFA 09;FreeTrack20;V170;;;9002;0084288979C65B0DAA0D00
-133;Fighter Ace;FreeTrack20;V160;;;8401;0085E2D1D77D259837B700
-134;Fighter Ops;FreeTrack20;V160;;;9301;00860FC9FF8B23A033BA00
-135;Fighter Squadron: Screamin Demons Over Europe;FreeTrack20;V160;;;1675;00872E20237D259A27A600
-136;First Eagles, Wings Over Europe, Strike Fighters;FreeTrack20;V160;;;1101;0088311857638A73BB7E00
-469;Flight Gear;FreeTrack20;V160;;;12901;01D5D896C66B030606E000
-466;Flight Simulator 2002;FreeTrack20;V160;;;2302;01D21F7650E254B4514B00
-467;Flight Simulator 2004;FreeTrack20;V160;;;2303;01D3E91BAAB385B2362E00
-468;Flight Simulator X;FreeTrack20;V160;;;2305;01D41C31F42FAF32603600
-137;FlightGear;FlightGear;V110;V;V4Friend;0;0089054E8839A02FAB2F00
-138;Flyboys / Warbirds;FreeTrack20;V160;;;1301;008ABB5BF72C8934AB2B00
-139;Flyer;FreeTrack20;V160;;;1650;008BD1C9F27826AE2CA500
-140;Flying Tigers;FreeTrack20;V160;;;7002;008C91D997F29A930B0200
-141;FlyingGuns;FreeTrack20;V160;;;14801;008D7A32A1A882BAA28A00
-142;Ford Racing 3;FreeTrack20;V160;;;6901;008E27D5047C2BA62F5800
-143;Free Falcon 4.0;FreeTrack20;V160;;;1901;008F157D78A3B962E55000
-144;Free Falcon 4.0: Allied Force;FreeTrack20;V160;;;8901;0090656DD6793CA9325900
-145;Free Falcon 5;FreeTrack20;V160;V;V4Friend;1902;00911038C3AAB32590E900
-146;FreeSpace2;FreeTrack20;V160;;;13302;0092C8CDF8C2EA63496300
-147;FTAlpha;FreeTrack20;V160;;;20270;00936C69677F1D772AA900
-149;Full Out;FreeTrack20;V160;;;1701;009527D5047C31A0375800
-150;Future Pinball;FreeTrack20;V160;V;V4Friend;13101;00969343487E42B541AA00
-151;Game VR;FreeTrack20;V160;;;20325;009756BA018030B0355500
-152;GameLab;FreeTrack20;V160;;;20555;00985485D891DB23092200
-472;Games Farm;FreeTrack20;V160;;;3250;01D875C0981E627E5C7600
-153;Gamma;FreeTrack20;V160;;;1050;009921007D1B9D38A76F00
+481;Embers of Caerus;FreeTrack20;V170;;;3275;0CCB4134258D7E10119E00
+108;EMS Simulations;FreeTrack20;V160;;;20390;006CA59E687D1589DE8500
+109;Enemy Engaged 2;FreeTrack20;V160;;;2102;006D010873EA635AEDC800
+110;Enemy Engaged: Commanche vs Hokum;FreeTrack20;V160;;;2101;006E157D789379636AED00
+524;Enemy Starfighter;FreeTrack20;V160;;;3725;020C7EF3AC4F08C8787600
+111;Envision TE;FreeTrack20;V160;;;20320;006FD13C2A863CAF26AB00
+112;EON Reality;FreeTrack20;V160;;;20410;0070B6C6142771F82EE900
+113;eSigma;FreeTrack20;V160;;;20700;0071950F9AA60DAD2E9F00
+114;Euro Truck Simulator;FreeTrack20;V160;V;mamsa;13602;00721B4BFF8B3EA3296600
+115;EVE Online;FreeTrack20;V160;;;11801;0073F47CC377C2388DC900
+116;Eventology;FreeTrack20;V160;;;12201;0074849F8B469C2BAC3600
+117;EVOC-101 Training;FreeTrack20;V160;;;20038;00756925967D2088FC6200
+118;Evochron Alliance 2.0;FreeTrack20;V160;;;14904;00767A32A1A8735A022900
+119;Evochron Legends;FreeTrack20;V160;;;14906;0077D6E585F8B41A12BA00
+120;Evochron Mercenary;FreeTrack20;V160;V;Scavenger4711 ;14907;00783752FBC7B42B221A00
+121;Evochron Renegades;FreeTrack20;V160;;;14905;0079621E7763FB421A1300
+122;EZCA;FreeTrack20;V160;V;dennison ;2475;007A6DBB52F7B147510601
+125;F-22 Total Air War;FreeTrack20;V160;;;1750;007D20C79F475F0621DB00
+126;F-35 PTA;FreeTrack20;V160;;;20185;007E26F7977E96C0352100
+148;F-Trainer;FreeTrack20;V160;;;20615;0094C6371D8AFB8C3E9900
+123;F1 2011/2012;FreeTrack20;V170;;;8109;007B265ECD74893EA12900
+124;F1 Challenge 99-02;FreeTrack20;V160;;;4401;007CA15F278FB660C9D210
+127;FAAC;FreeTrack20;V160;;;20500;007F0F00F489118300C000
+128;Farmer Simulator 2009;FreeTrack20;V160;;;1725;0080926ED8A1EB628AB300
+129;Faros Driving Simulator;FreeTrack20;V160;;;8001;0081B1C6647A1EA839A800
+130;Faubert Lab Car Simulator;FreeTrack20;V160;;;20480;00822E542A7F2DB61F9700
+131;Ferrari Virtual Academy;FreeTrack20;V160;V;sosna1983 ;0;0083C0AF8C24B62D974000
+132;FIFA 09;FreeTrack20;V170;;;9002;0084288979C65B0DAA0D00
+133;Fighter Ace;FreeTrack20;V160;;;8401;0085E2D1D77D259837B700
+134;Fighter Ops;FreeTrack20;V160;;;9301;00860FC9FF8B23A033BA00
+135;Fighter Squadron: Screamin Demons Over Europe;FreeTrack20;V160;;;1675;00872E20237D259A27A600
+136;First Eagles Wings Over Europe Strike Fighters;FreeTrack20;V160;;;1101;0088311857638A73BB7E00
+469;Flight Gear;FreeTrack20;V160;;;12901;01D5D896C66B030606E000
+466;Flight Simulator 2002;FreeTrack20;V160;;;2302;01D21F7650E254B4514B00
+467;Flight Simulator 2004;FreeTrack20;V160;;;2303;01D3E91BAAB385B2362E00
+468;Flight Simulator X;FreeTrack20;V160;;;2305;01D41C31F42FAF32603600
+137;FlightGear;FlightGear;V110;V;V4Friend;0;0089054E8839A02FAB2F00
+138;Flyboys / Warbirds;FreeTrack20;V160;;;1301;008ABB5BF72C8934AB2B00
+139;Flyer;FreeTrack20;V160;;;1650;008BD1C9F27826AE2CA500
+140;Flying Tigers;FreeTrack20;V160;;;7002;008C91D997F29A930B0200
+141;FlyingGuns;FreeTrack20;V160;;;14801;008D7A32A1A882BAA28A00
+142;Ford Racing 3;FreeTrack20;V160;;;6901;008E27D5047C2BA62F5800
+143;Free Falcon 4.0;FreeTrack20;V160;;;1901;008F157D78A3B962E55000
+144;Free Falcon 4.0: Allied Force;FreeTrack20;V160;;;8901;0090656DD6793CA9325900
+145;Free Falcon 5;FreeTrack20;V160;V;V4Friend;1902;00911038C3AAB32590E900
+146;FreeSpace2;FreeTrack20;V160;;;13302;0092C8CDF8C2EA63496300
+147;FTAlpha;FreeTrack20;V160;;;20270;00936C69677F1D772AA900
+149;Full Out;FreeTrack20;V160;;;1701;009527D5047C31A0375800
+150;Future Pinball;FreeTrack20;V160;V;V4Friend;13101;00969343487E42B541AA00
+151;Game VR;FreeTrack20;V160;;;20325;009756BA018030B0355500
+152;GameLab;FreeTrack20;V160;;;20555;00985485D891DB23092200
+472;Games Farm;FreeTrack20;V160;;;3250;01D875C0981E627E5C7600
+153;Gamma;FreeTrack20;V160;;;1050;009921007D1B9D38A76F00
503;Garry's Mod;FreeTrack20;V160;;;12503;01F74EEB71FA7F37856900
-483;Generic Robotics;FreeTrack20;V160;;;20750;01E3FE7B4F05872A415400
-475;Glider Sim;FreeTrack20;V160;;;20720;01DB42130C4B0620871C00
-154;Global Ground Support Deicing Simulation;FreeTrack20;V160;;;20330;009ACFE709237A3AA11F00
-155;GosNIIAS Sim Trainer;FreeTrack20;V160;;;20355;009BB78B06EC8A2DB81800
-156;Gothic 3;FreeTrack20;V160;;;14401;009C37971697B36AD32A00
-157;Grand Prix Legends;FreeTrack20;V160;;;6701;009D521358D3D933B96E01
-158;Grand Theft Auto: San Andreas;FreeTrack20;V160;;;7808;009E5F3D95777D3BA23700
-159;GRID;FreeTrack20;V160;V;LeapoEclipse ;8105;009FD8175F8D1D7C0D3800
-160;GSE Power Plant Simulation;FreeTrack20;V160;;;20044;00A0432C28C217BEF93300
-161;GT Legends;FreeTrack20;V160;V;TrickyDee ;3902;00A116BC08020581CA8200
-162;GTR;FreeTrack20;V160;;;3901;00A2FD6BFE39A881B85B00
-163;GTR2 EVO;FreeTrack20;V160;V;zild1221 ;0;00A34B0FC37B2198F96300
-164;Gun Commander;FreeTrack20;V160;;;2675;00A4E2D1D77E319FEE8600
-165;Half Life 2;FreeTrack20;V160;;;7806;00A556BA018130AF365500
-166;Halo;FreeTrack20;V160;;;3801;00A656BA018130AF3F9C00
+483;Generic Robotics;FreeTrack20;V160;;;20750;01E3FE7B4F05872A415400
+475;Glider Sim;FreeTrack20;V160;;;20720;01DB42130C4B0620871C00
+154;Global Ground Support Deicing Simulation;FreeTrack20;V160;;;20330;009ACFE709237A3AA11F00
+155;GosNIIAS Sim Trainer;FreeTrack20;V160;;;20355;009BB78B06EC8A2DB81800
+156;Gothic 3;FreeTrack20;V160;;;14401;009C37971697B36AD32A00
+157;Grand Prix Legends;FreeTrack20;V160;;;6701;009D521358D3D933B96E01
+158;Grand Theft Auto: San Andreas;FreeTrack20;V160;;;7808;009E5F3D95777D3BA23700
+159;GRID;FreeTrack20;V160;V;LeapoEclipse ;8105;009FD8175F8D1D7C0D3800
+160;GSE Power Plant Simulation;FreeTrack20;V160;;;20044;00A0432C28C217BEF93300
+161;GT Legends;FreeTrack20;V160;V;TrickyDee ;3902;00A116BC08020581CA8200
+162;GTR;FreeTrack20;V160;;;3901;00A2FD6BFE39A881B85B00
+163;GTR2 EVO;FreeTrack20;V160;V;zild1221 ;0;00A34B0FC37B2198F96300
+164;Gun Commander;FreeTrack20;V160;;;2675;00A4E2D1D77E319FEE8600
+520;H1Z1;FreeTrack20;V170;;;6004;1774F090B1BA9E782D0800
+165;Half Life 2;FreeTrack20;V160;;;7806;00A556BA018130AF365500
+166;Halo;FreeTrack20;V160;;;3801;00A656BA018130AF3F9C00
502;hapTEL;FreeTrack20;V160;;;20805;01F63ADE510A20446B6A00
-167;Hardware Control Simulator, Railway Electronics;FreeTrack20;V160;;;20705;00A7F3E85B1A8930B42F00
-168;Harrier Attack II;FreeTrack20;V160;;;1175;00A8F2F27A57D20A940900
+167;Hardware Control Simulator Railway Electronics;FreeTrack20;V160;;;20705;00A7F3E85B1A8930B42F00
+168;Harrier Attack II;FreeTrack20;V160;;;1175;00A8F2F27A57D20A940900
499;Harry's Hard Choices Interactive;FreeTrack20;V160;;;20800;01F33A21BAE3DB6D48A000
-169;HAWX;FreeTrack20;V160;V;EmBeES ;0;00A9D615A9C8B088717000
-170;Herissons (Paris France);FreeTrack20;V160;;;20001;00AAEA1CBED8C20B430B00
-171;HOBI;FreeTrack20;V160;;;20335;00ABB253777F1779168900
-172;HoverAssault;FreeTrack20;V160;;;5303;00AC521358E3AA832A4000
-173;HPC;FreeTrack20;V160;;;20600;00AD0FC9FF8D0A7CEF9500
-174;HPG Tracking;FreeTrack20;V160;;;20255;00AE0288A1879D98930900
-175;HTW;FreeTrack20;V160;;;20630;00AF26F797911901C22C00
-176;Huawei Software;FreeTrack20;V160;;;20660;00B04655E8030A733AB300
-177;HueSpace;FreeTrack20;V160;;;20510;00B1231517C44960FB6300
-178;Hyper Vision;FreeTrack20;V160;;;15101;00B2DB242B657D43B32300
-179;iAmFootball;FreeTrack20;V160;;;1250;00B3B59DEFAAAFDB301A00
-180;id Research;FreeTrack20;V170;;;2950;00B4E723B873D7FC87D700
-181;IESA;FreeTrack20;V160;;;20037;00B5157D78D0E840AD7100
-182;IL-2 Cliffs of Dover;FreeTrack20;V160;V;V4Friend;0;00B6282282095F00521000
-183;IL-2 Forgotten Battles, ACE, Pacific Fighters;FreeTrack20;V160;V;Glenn;1001;00B722FD79137100621100
-484;IL-2 Sturmovik: Battle of Stalingrad;FreeTrack20;V170;;;1008;03F04D5368D1FD2DF2AE00
-184;Illumina;FreeTrack20;V160;;;1350;00B8054E8B39A33DB02400
-185;ILP;FreeTrack20;V160;;;20310;00B9F07957801789C9A600
-186;Imagine 3D ATC Tower Simulation;FreeTrack20;V160;;;20032;00BAEF7A8F4B8812B95300
-187;In Touch Technologies Inc.;FreeTrack20;V160;;;20006;00BB84817A3A5124B23D00
-188;Inglobe;FreeTrack20;V160;;;20360;00BCE7A7FAA27B2DA82700
-189;Innovatec Simulator;FreeTrack20;V160;;;20036;00BD22FD7935B23DB82C00
-190;Insurgency;FreeTrack20;V160;;;9401;00BEB6C61427B3EA744B00
-191;Intific;FreeTrack20;V160;;;20655;00BF2BCA747F2AA8309D00
-192;iRacing;FreeTrack20;V160;V;vn88holden ;14101;00C0103AF1AA730A236900
-193;IREQ Robotic Camera Control;FreeTrack20;V160;;;20027;00C10448E0E8618521EB00
-194;ISIC;FreeTrack20;V160;;;20680;00C2DEE3582F8F217E0B00
+169;HAWX;FreeTrack20;V160;V;EmBeES ;0;00A9D615A9C8B088717000
+170;Herissons (Paris France);FreeTrack20;V160;;;20001;00AAEA1CBED8C20B430B00
+523;hiCRANE2;FreeTrack20;V160;;;20835;020BA8FC8C7DFFA1381A00
+171;HOBI;FreeTrack20;V160;;;20335;00ABB253777F1779168900
+172;HoverAssault;FreeTrack20;V160;;;5303;00AC521358E3AA832A4000
+173;HPC;FreeTrack20;V160;;;20600;00AD0FC9FF8D0A7CEF9500
+174;HPG Tracking;FreeTrack20;V160;;;20255;00AE0288A1879D98930900
+175;HTW;FreeTrack20;V160;;;20630;00AF26F797911901C22C00
+176;Huawei Software;FreeTrack20;V160;;;20660;00B04655E8030A733AB300
+177;HueSpace;FreeTrack20;V160;;;20510;00B1231517C44960FB6300
+178;Hyper Vision;FreeTrack20;V160;;;15101;00B2DB242B657D43B32300
+179;iAmFootball;FreeTrack20;V160;;;1250;00B3B59DEFAAAFDB301A00
+180;id Research;FreeTrack20;V170;;;2950;00B4E723B873D7FC87D700
+181;IESA;FreeTrack20;V160;;;20037;00B5157D78D0E840AD7100
+182;IL-2 Cliffs of Dover;FreeTrack20;V160;V;V4Friend;0;00B6282282095F00521000
+183;IL-2 Forgotten Battles ACE Pacific Fighters;FreeTrack20;V160;V;Glenn;1001;00B722FD79137100621100
+484;IL-2 Sturmovik: Battle of Stalingrad;FreeTrack20;V170;;;1008;03F04D5368D1FD2DF2AE00
+184;Illumina;FreeTrack20;V160;;;1350;00B8054E8B39A33DB02400
+185;ILP;FreeTrack20;V160;;;20310;00B9F07957801789C9A600
+186;Imagine 3D ATC Tower Simulation;FreeTrack20;V160;;;20032;00BAEF7A8F4B8812B95300
+187;In Touch Technologies Inc.;FreeTrack20;V160;;;20006;00BB84817A3A5124B23D00
+188;Inglobe;FreeTrack20;V160;;;20360;00BCE7A7FAA27B2DA82700
+189;Innovatec Simulator;FreeTrack20;V160;;;20036;00BD22FD7935B23DB82C00
+190;Insurgency;FreeTrack20;V160;;;9401;00BEB6C61427B3EA744B00
+191;Intific;FreeTrack20;V160;;;20655;00BF2BCA747F2AA8309D00
+192;iRacing;FreeTrack20;V160;V;vn88holden ;14101;00C0103AF1AA730A236900
+193;IREQ Robotic Camera Control;FreeTrack20;V160;;;20027;00C10448E0E8618521EB00
+194;ISIC;FreeTrack20;V160;;;20680;00C2DEE3582F8F217E0B00
506;ITCL;FreeTrack20;V160;;;20820;01FAD19412681DC9CC6100
-195;IVD Online;FreeTrack20;V160;;;20535;00C390B57E1D7DDD883D00
-196;J.J. Keller and Associates;FreeTrack20;V160;;;20002;00C4E482F57FE77CF46300
-197;Janes F18;FreeTrack20;V160;;;9001;00C55F3D9577802AAF2E00
-198;Javal Ent.;FreeTrack20;V160;;;2650;00C622FD7A28BA2FAEEA00
-199;JC Demo;FreeTrack20;V160;;;20470;00C70AC67B0A630D9B3900
-200;Jet Thunder;FreeTrack20;V160;;;4501;00C82100801FA4EA9A3500
-201;Jetfighter V;FreeTrack20;V160;;;2501;00C9F52E42217B33A63200
-202;JFIST;FreeTrack20;V160;;;20560;00CAC932727C0F8D208600
-203;John Deere Vehicle Simulator;FreeTrack20;V160;;;20175;00CB29DFA8D3FA92A66000
-204;Jump to Lightspeed;FreeTrack20;V160;;;6001;00CCC166C8D3FA12E52400
-205;Jumpgate;FreeTrack20;V160;;;15001;00CD26F797B32A63E99200
-206;Jumpgate Evolution;FreeTrack20;V170;;;15002;00CE5936D4F93DCE0CE700
-207;KAF Keymapper;FreeTrack20;V160;;;3101;00CF934348830E87EB8300
-476;KAI FLight Simulator;FreeTrack20;V160;;;20725;01DCC522132A5C01EDE500
-208;Key Macro View;FreeTrack20;V160;;;12001;00D016BC08431B1EF90100
-209;kiwi.vg;FreeTrack20;V160;;;20395;00D1409A430AB33633E900
-210;L-3;FreeTrack20;V160;;;20465;00D2F885EFA8DE67878B00
-211;L-3 Communications;FreeTrack20;V160;;;20051;00D3D6E585F92F765E7800
-212;Lionhead MGS Game Research;FreeTrack20;V160;;;15301;00D4C1BBF9227B238AE200
-213;Live For Speed;FreeTrack20;V160;V;zild1221 ;7101;00D528228526A833521300
-214;Live for Speed S2;FreeTrack20;V160;;;11601;00D63752FBC8235B923500
-218;Lock-On: Modern Air Combat;FreeTrack20;V160;;;1002;00DAAC156D903C993B6200
-215;Lockheed Martin Littoral Combat Ship simulator;FreeTrack20;V160;;;20025;00D771ED5E802A9827A000
-216;Lockheed Martin Prepar3D;SimConnect;V130;V;elelbe ;0;00D8D615A9C8F36932AA00
-217;LockOn: Flaming Cliffs 2;FreeTrack20;V170;V;EmBeES ;1005;00D9AFB0D279F3A6F72200
-219;London NHS;FreeTrack20;V160;;;20640;00DB2E2023832BA123A100
-220;Lore (Dark Horizons);FreeTrack20;V160;;;5302;00DCF478D27833DB62D500
-221;Love;FreeTrack20;V160;;;3125;00DD71ED5E802AAB214800
-222;Lucid Engine;FreeTrack20;V160;;;10501;00DE71ED5E803098259C00
+195;IVD Online;FreeTrack20;V160;;;20535;00C390B57E1D7DDD883D00
+196;J.J. Keller and Associates;FreeTrack20;V160;;;20002;00C4E482F57FE77CF46300
+197;Janes F18;FreeTrack20;V160;;;9001;00C55F3D9577802AAF2E00
+198;Javal Ent.;FreeTrack20;V160;;;2650;00C622FD7A28BA2FAEEA00
+199;JC Demo;FreeTrack20;V160;;;20470;00C70AC67B0A630D9B3900
+200;Jet Thunder;FreeTrack20;V160;;;4501;00C82100801FA4EA9A3500
+201;Jetfighter V;FreeTrack20;V160;;;2501;00C9F52E42217B33A63200
+202;JFIST;FreeTrack20;V160;;;20560;00CAC932727C0F8D208600
+203;John Deere Vehicle Simulator;FreeTrack20;V160;;;20175;00CB29DFA8D3FA92A66000
+204;Jump to Lightspeed;FreeTrack20;V160;;;6001;00CCC166C8D3FA12E52400
+205;Jumpgate;FreeTrack20;V160;;;15001;00CD26F797B32A63E99200
+206;Jumpgate Evolution;FreeTrack20;V170;;;15002;00CE5936D4F93DCE0CE700
+207;KAF Keymapper;FreeTrack20;V160;;;3101;00CF934348830E87EB8300
+476;KAI FLight Simulator;FreeTrack20;V160;;;20725;01DCC522132A5C01EDE500
+208;Key Macro View;FreeTrack20;V160;;;12001;00D016BC08431B1EF90100
+209;kiwi.vg;FreeTrack20;V160;;;20395;00D1409A430AB33633E900
+521;Kongsberg GlobalSim;FreeTrack20;V160;;;20825;0209B2C573D990BF764700
+210;L-3;FreeTrack20;V160;;;20465;00D2F885EFA8DE67878B00
+211;L-3 Communications;FreeTrack20;V160;;;20051;00D3D6E585F92F765E7800
+522;LG Electronics;FreeTrack20;V160;;;20830;020A3678F5833D513DCA00
+212;Lionhead MGS Game Research;FreeTrack20;V160;;;15301;00D4C1BBF9227B238AE200
+213;Live For Speed;FreeTrack20;V160;V;zild1221 ;7101;00D528228526A833521300
+214;Live for Speed S2;FreeTrack20;V160;;;11601;00D63752FBC8235B923500
+218;Lock-On: Modern Air Combat;FreeTrack20;V160;;;1002;00DAAC156D903C993B6200
+215;Lockheed Martin Littoral Combat Ship simulator;FreeTrack20;V160;;;20025;00D771ED5E802A9827A000
+216;Lockheed Martin Prepar3D;SimConnect;V130;V;elelbe ;0;00D8D615A9C8F36932AA00
+217;LockOn: Flaming Cliffs 2;FreeTrack20;V170;V;EmBeES ;1005;00D9AFB0D279F3A6F72200
+219;London NHS;FreeTrack20;V160;;;20640;00DB2E2023832BA123A100
+220;Lore (Dark Horizons);FreeTrack20;V160;;;5302;00DCF478D27833DB62D500
+221;Love;FreeTrack20;V160;;;3125;00DD71ED5E802AAB214800
+222;Lucid Engine;FreeTrack20;V160;;;10501;00DE71ED5E803098259C00
514;M4 Tank Brigade;FreeTrack20;V160;;;1308;02024ED5A3A26741604300
-223;M4 Tank Platoon;FreeTrack20;V160;;;1306;00DFDCC441A8E036320900
-224;Mach 1;FreeTrack20;V160;;;2575;00E0231518130942466000
-225;ManuVAR;FreeTrack20;V160;;;20455;00E153FE1E901CB0448800
-226;MaqSIM4;FreeTrack20;V160;;;20026;00E28F54A207D29B611700
-227;Mech Tactical Sim;FreeTrack20;V160;;;9501;00E3F3E85B1A8E34A53300
+223;M4 Tank Platoon;FreeTrack20;V160;;;1306;00DFDCC441A8E036320900
+224;Mach 1;FreeTrack20;V160;;;2575;00E0231518130942466000
+225;ManuVAR;FreeTrack20;V160;;;20455;00E153FE1E901CB0448800
+226;MaqSIM4;FreeTrack20;V160;;;20026;00E28F54A207D29B611700
+227;Mech Tactical Sim;FreeTrack20;V160;;;9501;00E3F3E85B1A8E34A53300
+228;Mechwarrior Online;FreeTrack20;V170;;;3025;00E414954226DB5D8CE200
516;MechWarrior Online;FreeTrack20;V170;;;3026;0BD2E0DCBC723836CD2400
-228;Mechwarrior Online;FreeTrack20;V170;;;3025;00E414954226DB5D8CE200
-229;Medical Image Visualization;FreeTrack20;V160;;;20295;00E59343488532A5359B00
-230;Meggitt Defense Systems;FreeTrack20;V160;;;20045;00E6926ED9122AB22AF300
-231;MetaVR;FreeTrack20;V160;;;20545;00E7C5BEE48120A8308800
-232;Meteoroid Maze;FreeTrack20;V160;;;13003;00E8F079578430AD2EB200
-233;MeVEA;FreeTrack20;V160;;;2250;00E9D24C3F933289028700
-234;Micro Flight;FreeTrack20;V160;V;V4Friend;5101;00EABA89D078439932EA00
-235;Microsoft ESP;FreeTrack20;V160;;;2306;00EB0AC67E30A63BA53F00
-236;Microsoft Flight;FreeTrack20;V170;V;V4Friend;2307;00ECAFBC54959539C51500
-237;Microsoft Flight Simulator 3;FreeTrack20;V160;V;V4Friend;0;00ED5909437D36963EA810
-238;Microsoft FS2002/2004;FSUIPC;V130;V;V4Friend;0;00EE44958F34992CB43A00
-239;Microsoft FSX;SimConnect;V130;V;V4Friend;0;00EFF478D278437A73AA00
-240;Microsoft Train Simulator;FreeTrack20;V160;;;7805;00F00449225A439A13FB00
-494;MiddleVR;FreeTrack20;V160;;;20785;01EE1227DF43CA90C26100
-241;Mig Alley;FreeTrack20;V160;;;1501;00F17686E5A83289CDA700
-242;Mimik Vehicle Simulator;FreeTrack20;V160;;;20585;00F2AB1D58A8E35A531A00
-243;Miner Wars;FreeTrack20;V160;;;2550;00F3C5BEE48124A234A400
-244;MKMapper Keymapper;FreeTrack20;V160;;;2201;00F487801A8E14822EA200
-245;ModelSim;FreeTrack20;V160;;;20540;00F544958F3A9A1FB11A00
-246;Morgan State University;FreeTrack20;V160;;;20010;00F65909437D3CA5339A00
-247;Motor Company;FreeTrack20;V160;;;11501;00F70288F37A629A7DD700
-248;Motorsport Simulators;FreeTrack20;V160;;;4201;00F8F52E42217E3DA63B00
-249;Mouse Emulation;FreeTrack20;V160;;;8501;00F9950F9A8E29B93A9700
-250;MS World Tour Kart 2004;FreeTrack20;V160;;;6601;00FA9F819CA27F10591600
-251;MSN Virtual Earth;FreeTrack20;V160;;;2309;00FBF47CC37842091DC900
-252;mTBI Balance;FreeTrack20;V160;;;20420;00FC72456F9E0E78145800
-253;NASA Crew Exploration Vehicle;FreeTrack20;V160;;;20017;00FD028900985FA5501A00
-254;NASCAR Heat;FreeTrack20;V160;;;2602;00FE311857E10880B84100
-255;NASCAR Racing 2003 season;FreeTrack20;V160;;;7804;00FFDE661F6D920B87FC10
-256;NASCAR SimRacing;FreeTrack20;V160;;;6201;01004098708870D761A500
-257;NecroVisioN;FreeTrack20;V160;;;15601;0101621E77F2EA830A8100
-258;NetKar Pro;FreeTrack20;V160;V;sosna1983 ;10901;01028C3958334A5169A300
-259;Nitro Stunt Racing;FreeTrack20;V160;;;13901;0103C0AF9428B82DA5ED00
-260;North Eastern University;FreeTrack20;V160;;;20003;0104A2AE4823BB7449DE00
-261;Novint;FreeTrack20;V160;;;2725;01051C76F8137B823A4300
-262;NVH Sound Simulator;FreeTrack20;V160;;;20695;010655A2AA93158DDE9500
-479;OHJCH;FreeTrack20;V160;;;20740;01DF992E6C0DA43A703600
-263;OMSI Bus Simulator;FreeTrack20;V160;V;Thiago ;2225;0107F47CC37861A9606600
-264;Onadime - Realtime Animation;FreeTrack20;V160;;;20049;010853FE1E9229A3339B00
-265;Open Falcon 4.5;FreeTrack20;V160;V;muplex ;0;0109B1C664832D9B385500
-266;Operation Air Assault 2;FreeTrack20;V160;;;5401;010ABB5BF72C9238973B00
-267;Operation Flashpoint 2 (inactive);FreeTrack20;V160;;;7601;010BD1C9F2812A9A399400
-268;Operation Flashpoint(r): Dragon Rising(tm);FreeTrack20;V170;;;8106;010C3328780E1322676100
-269;OptiMetrics;FreeTrack20;V160;;;20011;010D55A2AA942FB9288F00
-270;OpusFSX;FreeTrack20;V160;;;3175;010E1C76F8238B72D7C100
-271;Orbiter 2005 Plug-In;FreeTrack20;V160;;;10301;010F87801A903B9736A600
-272;Orbiter 2006;FreeTrack20;V160;V;Ripley;10303;0110D24C3F953F9526BA00
-273;Orbiter 2006 Plug-In;FreeTrack20;V160;;;10302;0111054E913F9931B72000
-274;Oryx Vehicle Simulators;FreeTrack20;V160;;;20028;0112C8CDF952EBA4763100
-275;Outer Conflict: Frontiers;FreeTrack20;V160;;;1900;01136C6967883EAA23AB00
-276;Over Flanders Fields;FreeTrack20;V160;V;Summelar ;2325;0114A59E68873E9B315210
-277;PanoPro;FreeTrack20;V160;;;20525;0115B6C61428231A23E900
-278;Paraworld;FreeTrack20;V160;;;14501;0116656DD6832BB62EB000
-279;Phoenix R/C;FreeTrack20;V160;;;3075;0117B6C61428238A334B00
-280;Pivot Maritime;FreeTrack20;V160;;;20365;01187686E5A8628AB2AA00
-281;PlanetSide 2;FreeTrack20;V170;;;6002;0119BB34B53FDC5C5AAF00
-474;PlanetSide 2 M.E.;FreeTrack20;V160;;;6003;01DA321EF31DA48C159A00
-282;Pointman;FreeTrack20;V160;;;7525;011ACFE70923833D9B2B00
-283;Power Driving Simulator;FreeTrack20;V160;;;20675;011BB78B06EC932DBC2F00
-470;Prepar3D;FreeTrack20;V160;;;20440;01D6DA768CE8AA43D8DC00
-284;Priston Tale;FreeTrack20;V160;;;9701;011C849F9642A030AC3600
-285;Project Reality (BF2 Mod);FreeTrack20;V160;;;9201;011D3C2C1C922CB239A800
-286;Project Torque (Invictus);FreeTrack20;V160;;;4802;011E612F28540B52797100
-287;Project X;FreeTrack20;V160;;;20022;011FE9D85E4842DA439900
-288;Quanser;FreeTrack20;V160;;;20435;0120950F9A922FA535A500
-289;QuantaDyn;FreeTrack20;V160;;;20575;012199BB5C9433A739B600
-290;Quest 3D Xframe Plugin;FreeTrack20;V160;;;20043;0122FD6BFE39A923C98200
-291;Quest3D;FreeTrack20;V160;;;1425;01234B0FC38542AB3BB700
-292;Quest3D - CINEACT integration;FreeTrack20;V160;;;20040;0124A15F28340AB3CA9000
-303;R-concept X (AdrenalinStorm);FreeTrack20;V160;;;9101;012F72456F83E6993AA600
-293;R.U.D.O. Tools;FreeTrack20;V160;;;20039;0125612F287FB9BEA76E00
-294;RACE (the WTCC game);FreeTrack20;V160;;;3904;01263C2C1C94FA86146300
-295;RACE 07, RACE, GTR 2;FreeTrack20;V160;V;zild1221, TrickyDee ;3903;0127C0AF9800870056FD00
-296;RaceOn;FreeTrack20;V160;V;zild1221 ;0;0128621E7832AA82388200
-297;Racer;FreeTrack20;V160;;;2401;01296D2D103862E932EA00
-298;Racer S;FreeTrack20;V160;;;20030;012AEA1CBED961CA52CB00
-490;RaceRoom Racing Experience;FreeTrack20;V160;;;3905;01EA9124F663AF03BBC500
-299;Rail Simulator 1;FreeTrack20;V160;;;1550;012BB253778929A0395900
-300;Railway Work Simulator;FreeTrack20;V160;;;20225;012C91D998B1E9933B9100
-301;RailWorks 2;FreeTrack20;V160;;;2750;012D3919C4972D9D299000
+229;Medical Image Visualization;FreeTrack20;V160;;;20295;00E59343488532A5359B00
+230;Meggitt Defense Systems;FreeTrack20;V160;;;20045;00E6926ED9122AB22AF300
+231;MetaVR;FreeTrack20;V160;;;20545;00E7C5BEE48120A8308800
+232;Meteoroid Maze;FreeTrack20;V160;;;13003;00E8F079578430AD2EB200
+233;MeVEA;FreeTrack20;V160;;;2250;00E9D24C3F933289028700
+234;Micro Flight;FreeTrack20;V160;V;V4Friend;5101;00EABA89D078439932EA00
+235;Microsoft ESP;FreeTrack20;V160;;;2306;00EB0AC67E30A63BA53F00
+236;Microsoft Flight;FreeTrack20;V170;V;V4Friend;2307;00ECAFBC54959539C51500
+237;Microsoft Flight Simulator 3;FreeTrack20;V160;V;V4Friend;0;00ED5909437D36963EA810
+238;Microsoft FS2002/2004;FSUIPC;V130;V;V4Friend;0;00EE44958F34992CB43A00
+239;Microsoft FSX;SimConnect;V130;V;V4Friend;0;00EFF478D278437A73AA00
+240;Microsoft Train Simulator;FreeTrack20;V160;;;7805;00F00449225A439A13FB00
+494;MiddleVR;FreeTrack20;V160;;;20785;01EE1227DF43CA90C26100
+241;Mig Alley;FreeTrack20;V160;;;1501;00F17686E5A83289CDA700
+242;Mimik Vehicle Simulator;FreeTrack20;V160;;;20585;00F2AB1D58A8E35A531A00
+243;Miner Wars;FreeTrack20;V160;;;2550;00F3C5BEE48124A234A400
+244;MKMapper Keymapper;FreeTrack20;V160;;;2201;00F487801A8E14822EA200
+245;ModelSim;FreeTrack20;V160;;;20540;00F544958F3A9A1FB11A00
+246;Morgan State University;FreeTrack20;V160;;;20010;00F65909437D3CA5339A00
+247;Motor Company;FreeTrack20;V160;;;11501;00F70288F37A629A7DD700
+248;Motorsport Simulators;FreeTrack20;V160;;;4201;00F8F52E42217E3DA63B00
+249;Mouse Emulation;FreeTrack20;V160;;;8501;00F9950F9A8E29B93A9700
+250;MS World Tour Kart 2004;FreeTrack20;V160;;;6601;00FA9F819CA27F10591600
+251;MSN Virtual Earth;FreeTrack20;V160;;;2309;00FBF47CC37842091DC900
+252;mTBI Balance;FreeTrack20;V160;;;20420;00FC72456F9E0E78145800
+253;NASA Crew Exploration Vehicle;FreeTrack20;V160;;;20017;00FD028900985FA5501A00
+254;NASCAR Heat;FreeTrack20;V160;;;2602;00FE311857E10880B84100
+255;NASCAR Racing 2003 season;FreeTrack20;V160;;;7804;00FFDE661F6D920B87FC10
+256;NASCAR SimRacing;FreeTrack20;V160;;;6201;01004098708870D761A500
+257;NecroVisioN;FreeTrack20;V160;;;15601;0101621E77F2EA830A8100
+258;NetKar Pro;FreeTrack20;V160;V;sosna1983 ;10901;01028C3958334A5169A300
+259;Nitro Stunt Racing;FreeTrack20;V160;;;13901;0103C0AF9428B82DA5ED00
+260;North Eastern University;FreeTrack20;V160;;;20003;0104A2AE4823BB7449DE00
+261;Novint;FreeTrack20;V160;;;2725;01051C76F8137B823A4300
+262;NVH Sound Simulator;FreeTrack20;V160;;;20695;010655A2AA93158DDE9500
+479;OHJCH;FreeTrack20;V160;;;20740;01DF992E6C0DA43A703600
+263;OMSI Bus Simulator;FreeTrack20;V160;V;Thiago ;2225;0107F47CC37861A9606600
+264;Onadime - Realtime Animation;FreeTrack20;V160;;;20049;010853FE1E9229A3339B00
+265;Open Falcon 4.5;FreeTrack20;V160;V;muplex ;0;0109B1C664832D9B385500
+266;Operation Air Assault 2;FreeTrack20;V160;;;5401;010ABB5BF72C9238973B00
+267;Operation Flashpoint 2 (inactive);FreeTrack20;V160;;;7601;010BD1C9F2812A9A399400
+268;Operation Flashpoint(r): Dragon Rising(tm);FreeTrack20;V170;;;8106;010C3328780E1322676100
+269;OptiMetrics;FreeTrack20;V160;;;20011;010D55A2AA942FB9288F00
+270;OpusFSX;FreeTrack20;V160;;;3175;010E1C76F8238B72D7C100
+271;Orbiter 2005 Plug-In;FreeTrack20;V160;;;10301;010F87801A903B9736A600
+272;Orbiter 2006;FreeTrack20;V160;V;Ripley;10303;0110D24C3F953F9526BA00
+273;Orbiter 2006 Plug-In;FreeTrack20;V160;;;10302;0111054E913F9931B72000
+274;Oryx Vehicle Simulators;FreeTrack20;V160;;;20028;0112C8CDF952EBA4763100
+275;Outer Conflict: Frontiers;FreeTrack20;V160;;;1900;01136C6967883EAA23AB00
+276;Over Flanders Fields;FreeTrack20;V160;V;Summelar ;2325;0114A59E68873E9B315210
+277;PanoPro;FreeTrack20;V160;;;20525;0115B6C61428231A23E900
+278;Paraworld;FreeTrack20;V160;;;14501;0116656DD6832BB62EB000
+279;Phoenix R/C;FreeTrack20;V160;;;3075;0117B6C61428238A334B00
+280;Pivot Maritime;FreeTrack20;V160;;;20365;01187686E5A8628AB2AA00
+281;PlanetSide 2;FreeTrack20;V170;;;6002;0119BB34B53FDC5C5AAF00
+474;PlanetSide 2 M.E.;FreeTrack20;V160;;;6003;01DA321EF31DA48C159A00
+282;Pointman;FreeTrack20;V160;;;7525;011ACFE70923833D9B2B00
+283;Power Driving Simulator;FreeTrack20;V160;;;20675;011BB78B06EC932DBC2F00
+470;Prepar3D;FreeTrack20;V160;;;20440;01D6DA768CE8AA43D8DC00
+284;Priston Tale;FreeTrack20;V160;;;9701;011C849F9642A030AC3600
+285;Project Reality (BF2 Mod);FreeTrack20;V160;;;9201;011D3C2C1C922CB239A800
+286;Project Torque (Invictus);FreeTrack20;V160;;;4802;011E612F28540B52797100
+287;Project X;FreeTrack20;V160;;;20022;011FE9D85E4842DA439900
+288;Quanser;FreeTrack20;V160;;;20435;0120950F9A922FA535A500
+289;QuantaDyn;FreeTrack20;V160;;;20575;012199BB5C9433A739B600
+290;Quest 3D Xframe Plugin;FreeTrack20;V160;;;20043;0122FD6BFE39A923C98200
+291;Quest3D;FreeTrack20;V160;;;1425;01234B0FC38542AB3BB700
+292;Quest3D - CINEACT integration;FreeTrack20;V160;;;20040;0124A15F28340AB3CA9000
+303;R-concept X (AdrenalinStorm);FreeTrack20;V160;;;9101;012F72456F83E6993AA600
+293;R.U.D.O. Tools;FreeTrack20;V160;;;20039;0125612F287FB9BEA76E00
+294;RACE (the WTCC game);FreeTrack20;V160;;;3904;01263C2C1C94FA86146300
+295;RACE 07 RACE GTR 2;FreeTrack20;V160;V;zild1221 TrickyDee ;3903;0127C0AF9800870056FD00
+296;RaceOn;FreeTrack20;V160;V;zild1221 ;0;0128621E7832AA82388200
+297;Racer;FreeTrack20;V160;;;2401;01296D2D103862E932EA00
+298;Racer S;FreeTrack20;V160;;;20030;012AEA1CBED961CA52CB00
+490;RaceRoom Racing Experience;FreeTrack20;V160;;;3905;01EA9124F663AF03BBC500
+299;Rail Simulator 1;FreeTrack20;V160;;;1550;012BB253778929A0395900
+300;Railway Work Simulator;FreeTrack20;V160;;;20225;012C91D998B1E9933B9100
+301;RailWorks 2;FreeTrack20;V160;;;2750;012D3919C4972D9D299000
507;RailWorks 5 (TS2014);FreeTrack20;V160;;;1551;01FB8B5232CB1502C95A00
-302;Raydon Driving Simulator;FreeTrack20;V160;;;3701;012E5485D941DBE2FB5300
-304;Real Time Visual;FreeTrack20;V160;;;9901;0130B1C664862297365500
-305;RealFlight;FreeTrack20;V160;;;4001;0131AC6E87892E993A8B00
-306;Reality Manager;FreeTrack20;V160;;;20046;0132DB242B65872FA42A00
-307;RealWorld;FreeTrack20;V160;;;20215;0133B59DEFA9322A727800
-308;Red Baron 3D;FreeTrack20;V160;;;1125;0134C6371D96349CEB7A00
-309;Red Orchestra: Heroes of Stalingrad;FreeTrack20;V170;;;12602;013521F9121056CD997300
-310;Red Orchestra: Ostfront;FreeTrack20;V170;;;12601;01369A9A2BE97252BB9000
-311;Redline Monitor;FreeTrack20;V160;;;20210;01373752FBC8831A72AA00
-312;REFLEX XTR;FreeTrack20;V160;;;2150;0138054E94127D14881300
-313;Remote Presence;FreeTrack20;V160;;;20710;01399BC3BDA93229D2BB00
-314;rFactor;FreeTrack20;V160;V;V4Friend;7401;013AEF7A8F4B8AA0495200
-315;rFactor Pro;FreeTrack20;V170;;;7403;013B175198D74BE8E89600
-316;rFactor2;FreeTrack20;V170;;;7402;013CBFF3A86D34DA24C000
-317;Richard Burns Rally;FreeTrack20;V160;V;zild1221;3401;013D42868B339A31A73C10
-318;RidingStar;FreeTrack20;V160;;;1475;013E3919C497359826A700
-319;Rig N Roll;FreeTrack20;V160;;;9801;013FD1C9F284239CE68100
-320;Rio Tinto Resource Development;FreeTrack20;V160;;;20033;01401039831B5EC8D31900
-321;Rise of Flight;FreeTrack20;V160;V;Seborgarsen ;11401;0141AA71218335A51F5100
-322;Rise: The Vieneo Province;FreeTrack20;V160;;;6301;0142DEE3582F9837A82D00
-323;Rising Conflicts;FreeTrack20;V160;;;12101;014384818335A439B12F00
-492;RITS;FreeTrack20;V160;;;20775;01ECEE745B83DD3A0DBE00
-324;Road Legends;FreeTrack20;V160;;;1876;0144379716986369A2E600
-325;Rogue Space;FreeTrack20;V160;;;3050;014588F5872C9C30ABE900
-326;Rogue Warrior;FreeTrack20;V160;;;14202;0146432C2973D9D45A8E00
-327;ROV Sim;FreeTrack20;V160;;;20530;0147FA04BD27891D9ADD00
-328;Rowan's Battle Of Britain;FreeTrack20;V160;;;1502;014821008829A72CB4F300
-329;RSD Demo;FreeTrack20;V160;;;2050;0149BF8C4EAA5871A85D00
-330;RTMS Crane Sim;FreeTrack20;V160;;;20400;014AC93272841D91205200
-331;RTT DeltaGen Plugin;FreeTrack20;V160;;;20195;014B90B5871B8DDD7D3400
+302;Raydon Driving Simulator;FreeTrack20;V160;;;3701;012E5485D941DBE2FB5300
+304;Real Time Visual;FreeTrack20;V160;;;9901;0130B1C664862297365500
+305;RealFlight;FreeTrack20;V160;;;4001;0131AC6E87892E993A8B00
+306;Reality Manager;FreeTrack20;V160;;;20046;0132DB242B65872FA42A00
+307;RealWorld;FreeTrack20;V160;;;20215;0133B59DEFA9322A727800
+308;Red Baron 3D;FreeTrack20;V160;;;1125;0134C6371D96349CEB7A00
+309;Red Orchestra: Heroes of Stalingrad;FreeTrack20;V170;;;12602;013521F9121056CD997300
+310;Red Orchestra: Ostfront;FreeTrack20;V170;;;12601;01369A9A2BE97252BB9000
+311;Redline Monitor;FreeTrack20;V160;;;20210;01373752FBC8831A72AA00
+312;REFLEX XTR;FreeTrack20;V160;;;2150;0138054E94127D14881300
+313;Remote Presence;FreeTrack20;V160;;;20710;01399BC3BDA93229D2BB00
+314;rFactor;FreeTrack20;V160;V;V4Friend;7401;013AEF7A8F4B8AA0495200
+315;rFactor Pro;FreeTrack20;V170;;;7403;013B175198D74BE8E89600
+316;rFactor2;FreeTrack20;V170;;;7402;013CBFF3A86D34DA24C000
+317;Richard Burns Rally;FreeTrack20;V160;V;zild1221;3401;013D42868B339A31A73C10
+318;RidingStar;FreeTrack20;V160;;;1475;013E3919C497359826A700
+319;Rig N Roll;FreeTrack20;V160;;;9801;013FD1C9F284239CE68100
+320;Rio Tinto Resource Development;FreeTrack20;V160;;;20033;01401039831B5EC8D31900
+321;Rise of Flight;FreeTrack20;V160;V;Seborgarsen ;11401;0141AA71218335A51F5100
+322;Rise: The Vieneo Province;FreeTrack20;V160;;;6301;0142DEE3582F9837A82D00
+323;Rising Conflicts;FreeTrack20;V160;;;12101;014384818335A439B12F00
+492;RITS;FreeTrack20;V160;;;20775;01ECEE745B83DD3A0DBE00
+324;Road Legends;FreeTrack20;V160;;;1876;0144379716986369A2E600
+325;Rogue Space;FreeTrack20;V160;;;3050;014588F5872C9C30ABE900
+326;Rogue Warrior;FreeTrack20;V160;;;14202;0146432C2973D9D45A8E00
+327;ROV Sim;FreeTrack20;V160;;;20530;0147FA04BD27891D9ADD00
+328;Rowan's Battle Of Britain;FreeTrack20;V160;;;1502;014821008829A72CB4F300
+329;RSD Demo;FreeTrack20;V160;;;2050;0149BF8C4EAA5871A85D00
+330;RTMS Crane Sim;FreeTrack20;V160;;;20400;014AC93272841D91205200
+331;RTT DeltaGen Plugin;FreeTrack20;V160;;;20195;014B90B5871B8DDD7D3400
511;Sail;FreeTrack20;V160;;;3575;01FF2916D764159099F800
-332;Sail Simulator 5;FreeTrack20;V160;;;1975;014CE2D1D78A1D9A3B6300
-333;Sailors of the Sky;FreeTrack20;V160;;;10201;014D17BE02961FAF3AB100
-334;Santa Cruz Watermill;FreeTrack20;V160;;;20290;014E88F5881EA32FA7E900
-335;SCANeR Studio Plugin;FreeTrack20;V160;;;20445;014FA2AE4870F861E9A100
-336;SEGA Demo;FreeTrack20;V160;;;2075;015016BC08C117F1163000
-337;Seven-G;FreeTrack20;V160;;;2350;01510F00F49635B822A200
-338;SFSPC;FreeTrack20;V160;;;2801;0152F885EFA9400981B700
-339;Ship Simulator 2006;FreeTrack20;V160;;;5002;015329DFA9638AA2C66100
-340;Ship Simulator 2008;FreeTrack20;V160;V;djj3ff ;5003;01545213599339B3D52100
-341;Shiphandling Simulator;FreeTrack20;V160;;;20570;01553FD0FC9D8B37AD3700
-342;Shooting Simulator;FreeTrack20;V160;;;20047;0156F2F27A58827A63DA00
-343;SIA Games;FreeTrack20;V160;;;20015;0157926ED970685DA8D200
-344;Silent Wings;FreeTrack20;V160;;;8701;0158D615A9C96309C24A00
-345;SilverHat;FreeTrack20;V160;;;12401;0159D8175F99349F3F9600
-346;Simax Simulator;FreeTrack20;V160;;;20021;015AAC156D9736A331AD00
-347;Simball 4D;FreeTrack20;V160;;;20315;015BD6E585F99349F2AA00
-348;Simbionix;FreeTrack20;V160;;;20485;015CE7A7FAA28528AE1D00
+332;Sail Simulator 5;FreeTrack20;V160;;;1975;014CE2D1D78A1D9A3B6300
+333;Sailors of the Sky;FreeTrack20;V160;;;10201;014D17BE02961FAF3AB100
+334;Santa Cruz Watermill;FreeTrack20;V160;;;20290;014E88F5881EA32FA7E900
+335;SCANeR Studio Plugin;FreeTrack20;V160;;;20445;014FA2AE4870F861E9A100
+336;SEGA Demo;FreeTrack20;V160;;;2075;015016BC08C117F1163000
+337;Seven-G;FreeTrack20;V160;;;2350;01510F00F49635B822A200
+338;SFSPC;FreeTrack20;V160;;;2801;0152F885EFA9400981B700
+339;Ship Simulator 2006;FreeTrack20;V160;;;5002;015329DFA9638AA2C66100
+340;Ship Simulator 2008;FreeTrack20;V160;V;djj3ff ;5003;01545213599339B3D52100
+341;Shiphandling Simulator;FreeTrack20;V160;;;20570;01553FD0FC9D8B37AD3700
+342;Shooting Simulator;FreeTrack20;V160;;;20047;0156F2F27A58827A63DA00
+343;SIA Games;FreeTrack20;V160;;;20015;0157926ED970685DA8D200
+344;Silent Wings;FreeTrack20;V160;;;8701;0158D615A9C96309C24A00
+345;SilverHat;FreeTrack20;V160;;;12401;0159D8175F99349F3F9600
+346;Simax Simulator;FreeTrack20;V160;;;20021;015AAC156D9736A331AD00
+347;Simball 4D;FreeTrack20;V160;;;20315;015BD6E585F99349F2AA00
+348;Simbionix;FreeTrack20;V160;;;20485;015CE7A7FAA28528AE1D00
518;SimCraft;FreeTrack20;V160;;;3650;02065BA013963203CB1900
-349;SimCreator;FreeTrack20;V160;;;20520;015D3752FBC8935B001A00
-350;Simlog Personal Simulator;FreeTrack20;V160;;;20635;015E42868C33A435B53100
-351;SimQuest immersion system;FreeTrack20;V160;;;20023;015F6C69678C32A30FAE00
-352;SimSol;FreeTrack20;V160;;;20034;01602315187389E0FB5300
-491;Simumak;FreeTrack20;V160;;;20770;01EB119629980784DCE600
-510;Sir, You Are Being Hunted;FreeTrack20;V160;;;3550;01FEDAB345FA104ED4A100
-353;Sirocco Racing;FreeTrack20;V160;;;5801;01612BCA748925A6369A00
-354;Sky God: Military Freefall;FreeTrack20;V170;;;1526;01622C0104385FD1C44400
-355;Soft fx Demo;FreeTrack20;V160;;;2125;01632E20238A2B99335200
-356;Source Engine (Half-Life 2);FreeTrack20;V160;;;12502;0164E482F58829A739A600
-357;Space Shuttle Mission 2007;FreeTrack20;V160;V;purewhitewings ;1225;0165662B03863D912F9700
+349;SimCreator;FreeTrack20;V160;;;20520;015D3752FBC8935B001A00
+350;Simlog Personal Simulator;FreeTrack20;V160;;;20635;015E42868C33A435B53100
+351;SimQuest immersion system;FreeTrack20;V160;;;20023;015F6C69678C32A30FAE00
+352;SimSol;FreeTrack20;V160;;;20034;01602315187389E0FB5300
+491;Simumak;FreeTrack20;V160;;;20770;01EB119629980784DCE600
+510;Sir You Are Being Hunted;FreeTrack20;V160;;;3550;01FEDAB345FA104ED4A100
+353;Sirocco Racing;FreeTrack20;V160;;;5801;01612BCA748925A6369A00
+354;Sky God: Military Freefall;FreeTrack20;V170;;;1526;01622C0104385FD1C44400
+355;Soft fx Demo;FreeTrack20;V160;;;2125;01632E20238A2B99335200
+356;Source Engine (Half-Life 2);FreeTrack20;V160;;;12502;0164E482F58829A739A600
+357;Space Shuttle Mission 2007;FreeTrack20;V160;V;purewhitewings ;1225;0165662B03863D912F9700
517;Spaze;FreeTrack20;V160;;;3625;020573F9D3ED8C43B8DC00
-358;SRI;FreeTrack20;V160;;;20620;01663FD0FC9D8B218D8100
-359;Stanford University;FreeTrack20;V160;;;20004;0167CE35BAF9933A62AA00
+358;SRI;FreeTrack20;V160;;;20620;01663FD0FC9D8B218D8100
+359;Stanford University;FreeTrack20;V160;;;20004;0167CE35BAF9933A62AA00
500;Star Citizen;FreeTrack20;V170;;;3450;0D7AF4CE4E343EC6B4A200
-360;Starshatter;FreeTrack20;V160;;;6401;0168F079578A3F9A3BB600
-361;Steel Beasts 2;FreeTrack20;V160;;;11703;0169DCC441A9443A831A00
-362;Steel Beasts Pro;FreeTrack20;V160;;;11701;016A8F54A20833CAA23900
-363;Steel Beasts Pro Personal;FreeTrack20;V160;;;11702;016BF3E85B1A9443A73000
-364;Stoked Rider;FreeTrack20;V160;;;14701;016CC166C963EA32997300
-365;Storm of War: the Battle of Britain;FreeTrack20;V170;;;11001;016D8F54A68B71F25D0200
-495;STRAFT;FreeTrack20;V160;;;3375;01EF1329E014ADF98D6B00
-366;Stride;FreeTrack20;V170;;;2310;016EC784B21E4B21984400
-367;STS Driving Simulator;FreeTrack20;V160;;;20300;016FA59E688B1C89DE7600
-368;Sunaerosys;FreeTrack20;V160;;;20475;01700449831AF28973EB00
-369;Superkarting;FreeTrack20;V160;;;14903;0171DE661F6D973FA41F00
-370;SuperX Research;FreeTrack20;V160;;;15401;0172BA89D078A45A021A00
-371;SWRI Demo;FreeTrack20;V160;;;20230;01730AC6841E9512561000
-372;Syncon Robot Control;FreeTrack20;V160;;;20415;0174C1BBF9937B12DB5200
-373;Synergy Simulation;FreeTrack20;V160;;;20595;0175926ED9736B220B8200
-374;T and TS Corp.;FreeTrack20;V160;;;20005;017617BE0297DDA73CA600
-375;Take On Helicopters;FreeTrack20;V170;;;7504;0177513CB40C0623B96A00
-376;Target: Korea;FreeTrack20;V160;;;1201;0178F52E4221852FA43300
-377;Target: Rabaul;FreeTrack20;V160;;;1202;0179E9D85E4881CA736900
-378;Targeting Demo;FreeTrack20;V160;;;13002;017AAB1D58A952DAA2F900
-379;TD Demo;FreeTrack20;V160;;;1925;017BC5BEE488FE54139700
-489;TeachLive;FreeTrack20;V160;;;20765;01E905245B5AC5484FC100
-380;Telepresence;FreeTrack20;V160;;;20450;017CF478D278B33B02DA00
-381;Tenstar Simulator;FreeTrack20;V160;;;20605;017D318F88A2EA62DBA200
-382;Test Drive Unlimited;FreeTrack20;V160;;;13201;017E6F2699559730A84000
+360;Starshatter;FreeTrack20;V160;;;6401;0168F079578A3F9A3BB600
+361;Steel Beasts 2;FreeTrack20;V160;;;11703;0169DCC441A9443A831A00
+362;Steel Beasts Pro;FreeTrack20;V160;;;11701;016A8F54A20833CAA23900
+363;Steel Beasts Pro Personal;FreeTrack20;V160;;;11702;016BF3E85B1A9443A73000
+364;Stoked Rider;FreeTrack20;V160;;;14701;016CC166C963EA32997300
+365;Storm of War: the Battle of Britain;FreeTrack20;V170;;;11001;016D8F54A68B71F25D0200
+495;STRAFT;FreeTrack20;V160;;;3375;01EF1329E014ADF98D6B00
+366;Stride;FreeTrack20;V170;;;2310;016EC784B21E4B21984400
+367;STS Driving Simulator;FreeTrack20;V160;;;20300;016FA59E688B1C89DE7600
+368;Sunaerosys;FreeTrack20;V160;;;20475;01700449831AF28973EB00
+369;Superkarting;FreeTrack20;V160;;;14903;0171DE661F6D973FA41F00
+370;SuperX Research;FreeTrack20;V160;;;15401;0172BA89D078A45A021A00
+371;SWRI Demo;FreeTrack20;V160;;;20230;01730AC6841E9512561000
+372;Syncon Robot Control;FreeTrack20;V160;;;20415;0174C1BBF9937B12DB5200
+373;Synergy Simulation;FreeTrack20;V160;;;20595;0175926ED9736B220B8200
+374;T and TS Corp.;FreeTrack20;V160;;;20005;017617BE0297DDA73CA600
+375;Take On Helicopters;FreeTrack20;V170;;;7504;0177513CB40C0623B96A00
+376;Target: Korea;FreeTrack20;V160;;;1201;0178F52E4221852FA43300
+377;Target: Rabaul;FreeTrack20;V160;;;1202;0179E9D85E4881CA736900
+378;Targeting Demo;FreeTrack20;V160;;;13002;017AAB1D58A952DAA2F900
+379;TD Demo;FreeTrack20;V160;;;1925;017BC5BEE488FE54139700
+489;TeachLive;FreeTrack20;V160;;;20765;01E905245B5AC5484FC100
+380;Telepresence;FreeTrack20;V160;;;20450;017CF478D278B33B02DA00
+381;Tenstar Simulator;FreeTrack20;V160;;;20605;017D318F88A2EA62DBA200
+382;Test Drive Unlimited;FreeTrack20;V160;;;13201;017E6F2699559730A84000
509;Tetrahedral;FreeTrack20;V160;;;3525;01FDCFF1C56D6F757E8200
501;The Crew;FreeTrack20;V170;;;1009;03F1F534E94F4834D9B100
-488;The Gallery;FreeTrack20;V160;;;3350;01E8CE152EDE5FFD267700
-383;The Sky Gods;FreeTrack20;V170;;;1525;017FDFF782DCCEEA27C200
-384;theHunter;FreeTrack20;V170;;;2375;0180BFF3A86D34DA24C000
-385;thriXXX HII 3D;FreeTrack20;V160;;;13403;0181FA04BD27AB36B62700
-386;thriXXX Jenna;FreeTrack20;V160;;;13401;01829F819CA2A625AB2800
-387;ThriXXX Technology;FreeTrack20;V160;;;13402;0183F47CC378B35B526900
-388;tir2joy;FreeTrack20;V160;;;2202;018487801AB532A7FE9C00
-389;TIRF4;FreeTrack20;V160;;;2203;0185311858418870E77000
-390;TNO;FreeTrack20;V160;;;20285;01861AAF6870A853D64900
-391;ToCA Race Driver 2;FreeTrack20;V160;;;8102;0187FFE9E886F286297910
-392;Toca Race Driver 3;FreeTrack20;V160;;;8101;01884098D36972B551A900
-393;Tom Clancy's H.A.W.X.;FreeTrack20;V170;V;EmBeES ;1004;0189AA4D48E85966FBAA00
-394;Tom Clancy's H.A.W.X. 2;FreeTrack20;V170;;;1007;018A1B7583521C12406F00
-395;Torque Game Engine;FreeTrack20;V160;;;5301;018BC0AF9A2EB62CAB3300
-396;Total War;FreeTrack20;V160;;;1375;018C72456F8529AA2CA400
-397;Tower Crane Simulator;FreeTrack20;V160;;;20670;018D03FB9929B034A7D900
-398;Tower I;FreeTrack20;V160;;;1325;018E662B03873CA731A400
-399;TPL Testing;FreeTrack20;V160;;;20260;018F849F9A2083DC8C2C00
-400;trackd;FreeTrack20;V160;;;20580;019053FE1EB72DA3329D00
-401;TrackMapper2;FreeTrack20;V160;;;2175;0191CE35BAF9A31A61FA00
-402;TrainMaster;FreeTrack20;V160;;;20042;01925C1FDE852D9925B400
-403;Trainz;FreeTrack20;V160;;;4701;0193D1C9F2862C9630A100
-404;TraumTek;FreeTrack20;V160;;;20650;0194A2AE4883EA645A2100
-405;Turismo Carretera;FreeTrack20;V160;;;15801;01956F2699559740A73500
-406;UK Rally Champion;FreeTrack20;V160;;;5701;019679EC0E28B196522A00
-407;ULAN;FreeTrack20;V160;;;20645;01974ADE68E16780D97A00
-473;Underwater Navigation;FreeTrack20;V160;;;20715;01D9FE2B94FB03772DE200
-408;Unity 3D Plugin;FreeTrack20;V160;;;20430;0198D24C3F9B3B9C31BF00
-409;Untitled 10tacle;FreeTrack20;V160;;;13701;0199FFE9E886F28728AA00
-410;Untitled 3D People;FreeTrack20;V160;;;15501;019A6925968D38AD23A900
-411;Untitled Apportmedia;FreeTrack20;V160;;;6801;019B3C2C1C9728B738B700
-412;Untitled Combat Flight Sim;FreeTrack20;V160;;;13801;019CA59E688D36AA28A600
-413;Untitled Deep Silver;FreeTrack20;V160;;;14601;019D656DD68838B836AD00
-414;Untitled G5 Software;FreeTrack20;V160;;;7301;019E318F88B37AC23BA300
-415;Untitled Microsoft;FreeTrack20;V160;;;2308;019FA15F28739BA32A9300
-416;Untitled Research;FreeTrack20;V160;;;1075;01A07686E5A8B2DA924A00
-417;Untitled Ron E;FreeTrack20;V160;;;14902;01A14ADE68E38AB28B9300
-418;Untitled Sega of America;FreeTrack20;V160;;;12801;01A27A32A1A972DA528A00
-419;Untitled Simbin;FreeTrack20;V160;;;3902;01A36C69678E37AA27AD00
-420;Untitled WorkShield;FreeTrack20;V160;;;4601;01A442868E38AB32BA3600
-421;Untitled ZootFly;FreeTrack20;V160;;;12701;01A5348B1863AA527A6300
-422;UQO;FreeTrack20;V160;;;23085;01A67C822099A187FE3600
-423;UVEG Machinery Simulator;FreeTrack20;V160;;;20024;01A73118585257A0F63100
-424;VAR;FreeTrack20;V160;;;20460;01A8950F9A97FA96FD2E00
-425;VBS2;FreeTrack20;V160;;;7501;01A999BB5C990099FCBF00
-485;VBS2 2.0;FreeTrack20;V170;;;7505;1D51EB3616B3A44F05B900
-426;Vehicle Simulator (Quality Simulations);FreeTrack20;V160;;;5102;01AA0FC9FF9B1FA134A900
-478;Vehicle Simulator Direction;FreeTrack20;V160;;;20735;01DEB88CF58E570F1CEF00
-427;Vestibular Ocular Reflex;FreeTrack20;V160;;;20008;01AB3919C49B31A731A200
-428;Viper Arena;FreeTrack20;V160;;;3501;01AC6F2699559934A53100
-429;VIRTools Engine;FreeTrack20;V160;;;10801;01AD1AAF68905881EB5300
-430;Virtools Plugin;FreeTrack20;V160;;;20200;01AE03FB9B23AB43A42900
-431;Virtual Driving;FreeTrack20;V160;;;20245;01AF99BB5C9927B83FB700
-432;Virtual Heroes;FreeTrack20;V160;;;20375;01B0621E78732B732AE200
-433;Virtual RC Racing;FreeTrack20;V160;;;8201;01B16D2D1038A36A23DA00
-434;Virtual Sailor;FreeTrack20;V160;;;5201;01B25F3D95778C32B33D00
-435;Virtual Shopper;FreeTrack20;V160;;;20610;01B3B78B06EC9927B73E00
-436;Virtual Supermarket;FreeTrack20;V160;;;20280;01B4849F9C39A931AD2800
-496;VirtualiTeach;FreeTrack20;V160;;;20790;01F062AE1CAB33B52D0700
-480;Vizard;FreeTrack20;V160;;;20745;01E0C1F20A79D7C0561300
-437;VizRD;FreeTrack20;V160;;;20031;01B55485D9825BF1D8AB00
-438;Void War;FreeTrack20;V160;;;10001;01B65C1FDE872AA1206600
-477;VRPlayer;FreeTrack20;V160;;;20730;01DD6787E57245201D5000
-439;VT08;FreeTrack20;V160;;;1275;01B7B78B06EC9912750200
-440;VVVV Plugin;FreeTrack20;V160;;;20075;01B8B1C6648A138C205500
-441;VW Testing;FreeTrack20;V160;;;20275;01B9AC6E878D205822AA00
-442;Walkabout3d;FreeTrack20;V160;;;20125;01BA2822901E9E39932F00
-443;Wallbusters;FreeTrack20;V160;;;1450;01BB88F58C1EA127A83F00
-444;War Thunder;FreeTrack20;V160;;;0;01BC17BE029A1FB8ED9600
-445;WAVES;FreeTrack20;V160;;;20515;01BD05B38FFE89008B8B00
-446;Welding Simulator;FreeTrack20;V160;;;2625;01BE348B188319D229B300
-447;West Racing;FreeTrack20;V160;;;1801;01BF91D999022A33B62000
-448;Whirlwind of Vietnam;FreeTrack20;V160;;;11101;01C0054E9935A03AAF3200
-449;Wikid FJ;FreeTrack20;V160;;;20685;01C19BC3BDA98269B25A00
-450;Wings of Prey;FreeTrack20;V160;V;V4Friend;1877;01C25909438736A133AC00
-451;Wings of War;FreeTrack20;V160;;;7807;01C34B0FC38B36B42FB610
+488;The Gallery;FreeTrack20;V160;;;3350;01E8CE152EDE5FFD267700
+383;The Sky Gods;FreeTrack20;V170;;;1525;017FDFF782DCCEEA27C200
+384;theHunter;FreeTrack20;V170;;;2375;0180BFF3A86D34DA24C000
+385;thriXXX HII 3D;FreeTrack20;V160;;;13403;0181FA04BD27AB36B62700
+386;thriXXX Jenna;FreeTrack20;V160;;;13401;01829F819CA2A625AB2800
+387;ThriXXX Technology;FreeTrack20;V160;;;13402;0183F47CC378B35B526900
+388;tir2joy;FreeTrack20;V160;;;2202;018487801AB532A7FE9C00
+389;TIRF4;FreeTrack20;V160;;;2203;0185311858418870E77000
+390;TNO;FreeTrack20;V160;;;20285;01861AAF6870A853D64900
+391;ToCA Race Driver 2;FreeTrack20;V160;;;8102;0187FFE9E886F286297910
+392;Toca Race Driver 3;FreeTrack20;V160;;;8101;01884098D36972B551A900
+393;Tom Clancy's H.A.W.X.;FreeTrack20;V170;V;EmBeES ;1004;0189AA4D48E85966FBAA00
+394;Tom Clancy's H.A.W.X. 2;FreeTrack20;V170;;;1007;018A1B7583521C12406F00
+395;Torque Game Engine;FreeTrack20;V160;;;5301;018BC0AF9A2EB62CAB3300
+396;Total War;FreeTrack20;V160;;;1375;018C72456F8529AA2CA400
+397;Tower Crane Simulator;FreeTrack20;V160;;;20670;018D03FB9929B034A7D900
+398;Tower I;FreeTrack20;V160;;;1325;018E662B03873CA731A400
+399;TPL Testing;FreeTrack20;V160;;;20260;018F849F9A2083DC8C2C00
+400;trackd;FreeTrack20;V160;;;20580;019053FE1EB72DA3329D00
+401;TrackMapper2;FreeTrack20;V160;;;2175;0191CE35BAF9A31A61FA00
+402;TrainMaster;FreeTrack20;V160;;;20042;01925C1FDE852D9925B400
+403;Trainz;FreeTrack20;V160;;;4701;0193D1C9F2862C9630A100
+404;TraumTek;FreeTrack20;V160;;;20650;0194A2AE4883EA645A2100
+405;Turismo Carretera;FreeTrack20;V160;;;15801;01956F2699559740A73500
+406;UK Rally Champion;FreeTrack20;V160;;;5701;019679EC0E28B196522A00
+407;ULAN;FreeTrack20;V160;;;20645;01974ADE68E16780D97A00
+473;Underwater Navigation;FreeTrack20;V160;;;20715;01D9FE2B94FB03772DE200
+408;Unity 3D Plugin;FreeTrack20;V160;;;20430;0198D24C3F9B3B9C31BF00
+525;Unity 64-bit;FreeTrack20;V160;;;3750;020DC8AB18AF3539FA5200
+409;Untitled 10tacle;FreeTrack20;V160;;;13701;0199FFE9E886F28728AA00
+410;Untitled 3D People;FreeTrack20;V160;;;15501;019A6925968D38AD23A900
+411;Untitled Apportmedia;FreeTrack20;V160;;;6801;019B3C2C1C9728B738B700
+412;Untitled Combat Flight Sim;FreeTrack20;V160;;;13801;019CA59E688D36AA28A600
+413;Untitled Deep Silver;FreeTrack20;V160;;;14601;019D656DD68838B836AD00
+414;Untitled G5 Software;FreeTrack20;V160;;;7301;019E318F88B37AC23BA300
+415;Untitled Microsoft;FreeTrack20;V160;;;2308;019FA15F28739BA32A9300
+416;Untitled Research;FreeTrack20;V160;;;1075;01A07686E5A8B2DA924A00
+417;Untitled Ron E;FreeTrack20;V160;;;14902;01A14ADE68E38AB28B9300
+418;Untitled Sega of America;FreeTrack20;V160;;;12801;01A27A32A1A972DA528A00
+419;Untitled Simbin;FreeTrack20;V160;;;3902;01A36C69678E37AA27AD00
+420;Untitled WorkShield;FreeTrack20;V160;;;4601;01A442868E38AB32BA3600
+421;Untitled ZootFly;FreeTrack20;V160;;;12701;01A5348B1863AA527A6300
+422;UQO;FreeTrack20;V160;;;23085;01A67C822099A187FE3600
+423;UVEG Machinery Simulator;FreeTrack20;V160;;;20024;01A73118585257A0F63100
+424;VAR;FreeTrack20;V160;;;20460;01A8950F9A97FA96FD2E00
+425;VBS2;FreeTrack20;V160;;;7501;01A999BB5C990099FCBF00
+485;VBS2 2.0;FreeTrack20;V170;;;7505;1D51EB3616B3A44F05B900
+426;Vehicle Simulator (Quality Simulations);FreeTrack20;V160;;;5102;01AA0FC9FF9B1FA134A900
+478;Vehicle Simulator Direction;FreeTrack20;V160;;;20735;01DEB88CF58E570F1CEF00
+427;Vestibular Ocular Reflex;FreeTrack20;V160;;;20008;01AB3919C49B31A731A200
+428;Viper Arena;FreeTrack20;V160;;;3501;01AC6F2699559934A53100
+429;VIRTools Engine;FreeTrack20;V160;;;10801;01AD1AAF68905881EB5300
+430;Virtools Plugin;FreeTrack20;V160;;;20200;01AE03FB9B23AB43A42900
+431;Virtual Driving;FreeTrack20;V160;;;20245;01AF99BB5C9927B83FB700
+432;Virtual Heroes;FreeTrack20;V160;;;20375;01B0621E78732B732AE200
+433;Virtual RC Racing;FreeTrack20;V160;;;8201;01B16D2D1038A36A23DA00
+434;Virtual Sailor;FreeTrack20;V160;;;5201;01B25F3D95778C32B33D00
+435;Virtual Shopper;FreeTrack20;V160;;;20610;01B3B78B06EC9927B73E00
+436;Virtual Supermarket;FreeTrack20;V160;;;20280;01B4849F9C39A931AD2800
+496;VirtualiTeach;FreeTrack20;V160;;;20790;01F062AE1CAB33B52D0700
+480;Vizard;FreeTrack20;V160;;;20745;01E0C1F20A79D7C0561300
+437;VizRD;FreeTrack20;V160;;;20031;01B55485D9825BF1D8AB00
+438;Void War;FreeTrack20;V160;;;10001;01B65C1FDE872AA1206600
+477;VRPlayer;FreeTrack20;V160;;;20730;01DD6787E57245201D5000
+439;VT08;FreeTrack20;V160;;;1275;01B7B78B06EC9912750200
+440;VVVV Plugin;FreeTrack20;V160;;;20075;01B8B1C6648A138C205500
+441;VW Testing;FreeTrack20;V160;;;20275;01B9AC6E878D205822AA00
+442;Walkabout3d;FreeTrack20;V160;;;20125;01BA2822901E9E39932F00
+443;Wallbusters;FreeTrack20;V160;;;1450;01BB88F58C1EA127A83F00
+444;War Thunder;FreeTrack20;V160;;;0;01BC17BE029A1FB8ED9600
+445;WAVES;FreeTrack20;V160;;;20515;01BD05B38FFE89008B8B00
+446;Welding Simulator;FreeTrack20;V160;;;2625;01BE348B188319D229B300
+447;West Racing;FreeTrack20;V160;;;1801;01BF91D999022A33B62000
+448;Whirlwind of Vietnam;FreeTrack20;V160;;;11101;01C0054E9935A03AAF3200
+449;Wikid FJ;FreeTrack20;V160;;;20685;01C19BC3BDA98269B25A00
+450;Wings of Prey;FreeTrack20;V160;V;V4Friend;1877;01C25909438736A133AC00
+451;Wings of War;FreeTrack20;V160;;;7807;01C34B0FC38B36B42FB610
512;Wings: Over Flanders Fields;FreeTrack20;V160;;;2326;02008AE39AAA4624B33C00
-452;World Racing 2;FreeTrack20;V160;;;7201;01C41AAF68A2BA836AAE00
-453;WWII Battle Tanks: T-34 vs. Tiger;FreeTrack20;V160;;;11102;01C5432C29C257F1963100
-454;X Motor Racing;FreeTrack20;V160;;;1150;01C669259690E98629A900
-458;X-Cockpit for X-Plane;FreeTrack20;V160;;;2901;01CA1C76F8BF4852999300
-459;X-Plane (32 and 64 bit);FreeTrack20;V160;V;EmBeES ;7701;01CB3FD0FC9D90FB943300
-460;X-Plane 6DOF Plugin;FreeTrack20;V160;;;10101;01CCA15F28AF7963596300
-461;X-Plane Pilot View (32 and 64 bit);FreeTrack20;V160;V;V4Friend;11301;01CD79EC0E28EFA953CA00
-462;X-Tower for X-Plane;FreeTrack20;V160;;;3001;01CE05B390EA872AAF3200
-455;X1Alpha;FreeTrack20;V160;;;1825;01C76D2D1038CFD7135A00
-456;X2: The Threat;FreeTrack20;V160;;;5501;01C81039EF980EC8D30900
-457;X3: Albion Prelude and Reunion;FreeTrack20;V170;V;V4Friend;5502;01C97E101A708F8524E300
-463;Xyphoid;FreeTrack20;V160;;;14301;01CF656DD68B43B435A800
-464;zedasoft F-35 Demo;FreeTrack20;V160;;;20041;01D02100B01F942CB93C00
-493;ZKT;FreeTrack20;V160;;;20780;01ED2BAA723F3C097EE800
-465;Zombie AA Research;FreeTrack20;V160;;;14201;01D1AA71218B3B9F1C9A00
+452;World Racing 2;FreeTrack20;V160;;;7201;01C41AAF68A2BA836AAE00
+453;WWII Battle Tanks: T-34 vs. Tiger;FreeTrack20;V160;;;11102;01C5432C29C257F1963100
+454;X Motor Racing;FreeTrack20;V160;;;1150;01C669259690E98629A900
+526;X-Camera;FreeTrack20;V160;;;3775;020E1C4055DE39CBC03D00
+458;X-Cockpit for X-Plane;FreeTrack20;V160;;;2901;01CA1C76F8BF4852999300
+459;X-Plane (32 and 64 bit);FreeTrack20;V160;V;EmBeES ;7701;01CB3FD0FC9D90FB943300
+460;X-Plane 6DOF Plugin;FreeTrack20;V160;;;10101;01CCA15F28AF7963596300
+461;X-Plane Pilot View (32 and 64 bit);FreeTrack20;V160;V;V4Friend;11301;01CD79EC0E28EFA953CA00
+462;X-Tower for X-Plane;FreeTrack20;V160;;;3001;01CE05B390EA872AAF3200
+455;X1Alpha;FreeTrack20;V160;;;1825;01C76D2D1038CFD7135A00
+456;X2: The Threat;FreeTrack20;V160;;;5501;01C81039EF980EC8D30900
+457;X3: Albion Prelude and Reunion;FreeTrack20;V170;V;V4Friend;5502;01C97E101A708F8524E300
+463;Xyphoid;FreeTrack20;V160;;;14301;01CF656DD68B43B435A800
+464;zedasoft F-35 Demo;FreeTrack20;V160;;;20041;01D02100B01F942CB93C00
+493;ZKT;FreeTrack20;V160;;;20780;01ED2BAA723F3C097EE800
+465;Zombie AA Research;FreeTrack20;V160;;;14201;01D1AA71218B3B9F1C9A00
diff --git a/cmake/mingw-w64.cmake b/cmake/mingw-w64.cmake
new file mode 100644
index 00000000..b5c06549
--- /dev/null
+++ b/cmake/mingw-w64.cmake
@@ -0,0 +1,28 @@
+# this file only serves as toolchain file when specified so explicitly
+# when building the software. from repository's root directory:
+# mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$(pwd)/../cmake/mingw-w64.cmake
+# -sh 20140922
+
+SET(CMAKE_SYSTEM_NAME Windows)
+SET(CMAKE_SYSTEM_VERSION 1)
+
+# specify the cross compiler
+SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
+SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
+
+SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# search for programs in the host directories
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+# don't poison with system compile-time data
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -flto -march=i686 -mtune=prescott -mno-sse3 -mno-avx -frename-registers" CACHE STRING "" FORCE)
+set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} CACHE STRING "" FORCE)
+set(CMAKE_BUILD_TYPE "RELEASE" CACHE STRING "" FORCE)
+
+# these are merely for my own convenience
+set(OpenCV_DIR /home/sthalik/opentrack-win32-sdk/opencv/build)
+set(Qt5_DIR /home/sthalik/opentrack-win32-sdk/qt-install-5.3.1/lib/cmake/Qt5)
diff --git a/compat/compat.cpp b/compat/compat.cpp
index 7b695617..b5d63f2b 100644
--- a/compat/compat.cpp
+++ b/compat/compat.cpp
@@ -4,12 +4,12 @@
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*/
+
+#include <cstring>
#define IN_FTNOIR_COMPAT
#include "compat.h"
-#include <string.h>
#if defined(_WIN32)
-
PortableLockedShm::PortableLockedShm(const char* shmName, const char* mutexName, int mapSize)
{
hMutex = CreateMutexA(NULL, false, mutexName);
@@ -43,8 +43,8 @@ void PortableLockedShm::unlock()
{
(void) ReleaseMutex(hMutex);
}
-
#else
+#pragma GCC diagnostic ignored "-Wunused-result"
PortableLockedShm::PortableLockedShm(const char *shmName, const char* /*mutexName*/, int mapSize) : size(mapSize)
{
char filename[512] = {0};
@@ -57,8 +57,6 @@ PortableLockedShm::PortableLockedShm(const char *shmName, const char* /*mutexNam
PortableLockedShm::~PortableLockedShm()
{
- //(void) shm_unlink(shm_filename);
-
(void) munmap(mem, size);
(void) close(fd);
}
@@ -72,7 +70,6 @@ void PortableLockedShm::unlock()
{
flock(fd, LOCK_UN);
}
-
#endif
bool PortableLockedShm::success()
diff --git a/compat/compat.h b/compat/compat.h
index 0e488752..490d8913 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -38,12 +38,12 @@ public:
void lock();
void unlock();
bool success();
- void* mem;
+ inline void* ptr() { return mem; }
private:
+ void* mem;
#if defined(_WIN32)
HANDLE hMutex, hMapFile;
#else
int fd, size;
- //char shm_filename[NAME_MAX];
#endif
};
diff --git a/compat/qt-bug-appeasement.cpp b/compat/qt-bug-appeasement.cpp
deleted file mode 100644
index 9a86ac0a..00000000
--- a/compat/qt-bug-appeasement.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "facetracknoir/qt-moc.h"
diff --git a/dinput/dinput8.lib b/dinput/dinput8.lib
deleted file mode 100644
index 3fad62fb..00000000
--- a/dinput/dinput8.lib
+++ /dev/null
Binary files differ
diff --git a/dinput/dxguid.lib b/dinput/dxguid.lib
deleted file mode 100644
index 8397d134..00000000
--- a/dinput/dxguid.lib
+++ /dev/null
Binary files differ
diff --git a/dinput/strmiids.lib b/dinput/strmiids.lib
deleted file mode 100644
index 8d921239..00000000
--- a/dinput/strmiids.lib
+++ /dev/null
Binary files differ
diff --git a/documentation/filemapping example.doc b/documentation/filemapping example.doc
deleted file mode 100644
index 0940508c..00000000
--- a/documentation/filemapping example.doc
+++ /dev/null
Binary files differ
diff --git a/documentation/qt 4.5 with visual studio 2.pdf b/documentation/qt 4.5 with visual studio 2.pdf
deleted file mode 100644
index c23e3ac9..00000000
--- a/documentation/qt 4.5 with visual studio 2.pdf
+++ /dev/null
Binary files differ
diff --git a/documentation/setting up qt.pdf b/documentation/setting up qt.pdf
deleted file mode 100644
index addaee9a..00000000
--- a/documentation/setting up qt.pdf
+++ /dev/null
Binary files differ
diff --git a/documentation/using shared memory for freetrack server.pdf b/documentation/using shared memory for freetrack server.pdf
deleted file mode 100644
index 980a0e55..00000000
--- a/documentation/using shared memory for freetrack server.pdf
+++ /dev/null
Binary files differ
diff --git a/documentation/working with qt visual studio plugin.pdf b/documentation/working with qt visual studio plugin.pdf
deleted file mode 100644
index 5d70447e..00000000
--- a/documentation/working with qt visual studio plugin.pdf
+++ /dev/null
Binary files differ
diff --git a/facetracknoir/clientfiles/FlightGear/readme.txt b/facetracknoir/clientfiles/FlightGear/readme.txt
index 0b3d9dfe..48cee837 100644
--- a/facetracknoir/clientfiles/FlightGear/readme.txt
+++ b/facetracknoir/clientfiles/FlightGear/readme.txt
@@ -1,8 +1,8 @@
-Copy Protocol/headtracker.xml to fgdata/Protocol/headtracker.xml
-
-$ fgfs --generic=socket,in,25,localhost,5542,udp,headtracker
-
-Adjust paths as necessary.
-
-cheers,
--sh 20131008
+Copy Protocol/headtracker.xml to fgdata/Protocol/headtracker.xml
+
+$ fgfs --generic=socket,in,25,localhost,5542,udp,headtracker
+
+Adjust paths as necessary.
+
+cheers,
+-sh 20131008
diff --git a/facetracknoir/clientfiles/cute-octopus-vector-material_15-1831.jpg b/facetracknoir/clientfiles/cute-octopus-vector-material_15-1831.jpg
new file mode 100644
index 00000000..c4e5318f
--- /dev/null
+++ b/facetracknoir/clientfiles/cute-octopus-vector-material_15-1831.jpg
Binary files differ
diff --git a/facetracknoir/clientfiles/make-csv.pl b/facetracknoir/clientfiles/make-csv.pl
new file mode 100755
index 00000000..ee60364e
--- /dev/null
+++ b/facetracknoir/clientfiles/make-csv.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+
+use strict;
+use List::Util qw'reduce';
+
+sub get_games_1 {
+ my @games;
+
+ open my $fd, "<", $ARGV[1] or die "open: $!";
+ <$fd>;
+
+ while (defined(my $line = <$fd>)) {
+ chomp $line;
+ if ($line !~ /^(\d+)\s+"([^"]+)"(?:\s+\(([0-9A-F]{16})\))?$/) {
+ warn "Broken line";
+ next;
+ }
+ push @games, +{ id => $1, name => $2, key => defined $3 ? (sprintf "%04X", $1) . $3 . '00' : undef};
+ }
+
+ [@games];
+}
+
+sub get_games_2 {
+ open my $fd, "<", $ARGV[0] or die "open: $!";
+ <$fd>;
+ my @games;
+ while (defined(my $line = <$fd>)) {
+ chomp $line;
+ my @line = split/;/, $line;
+ if (@line != 8) {
+ warn "Broken line";
+ next;
+ }
+ my @cols = qw'no name proto since verified by id key';
+ push @games, +{ map { $cols[$_] => $line[$_] } 0..$#cols };
+ }
+ [@games];
+}
+
+sub merge {
+ my ($new_games, $old_games) = @_;
+ my $no = (reduce { $a->{no} > $b->{no} ? $a : $b } +{id=>0}, @$old_games)->{no} + 1;
+ my %game_hash = map { $_->{name} => $_ } @$old_games;
+ my %ids = map { $_->{id} => 1 } @$old_games;
+ for my $g (@$new_games) {
+ if (!exists $game_hash{$g->{name}} && !exists $ids{$g->{id}}) {
+ $game_hash{$g->{name}} = +{
+ no => $no++,
+ name => $g->{name},
+ proto => 'FreeTrack20',
+ since => (defined $g->{key} ? 'V170' : 'V160'),
+ verified => '',
+ by => '',
+ id => $g->{id},
+ key => $g->{key}
+ };
+ }
+ }
+ print "No;Game Name;Game protocol;Supported since;Verified;By;INTERNATIONAL_ID;FTN_ID\n";
+ for (sort { lc($a->{name}) cmp lc($b->{name}) } values %game_hash) {
+ my $g = {%$_};
+ if (!defined $g->{key}) {
+ $g->{key} = (sprintf "%04X", $g->{no}) . (join"", map { sprintf "%02X", int rand 256 } 0 .. 7) . '00';
+ }
+ my @cols = qw'no name proto since verified by id key';
+ print join";", map { $g->{$_} } @cols;
+ print "\n";
+ }
+}
+
+merge(get_games_1(), get_games_2());
diff --git a/facetracknoir/clientfiles/very-important-source-code/README-CREDIT.txt b/facetracknoir/clientfiles/very-important-source-code/README-CREDIT.txt
new file mode 100644
index 00000000..82214139
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/README-CREDIT.txt
@@ -0,0 +1,6 @@
+The contents of the directory written by one and only, uglyDwarf.
+
+Obtained at epoch time 1412397452 from the mithril-mine's shaft, where
+the elite dwarves reside.
+
+For the latest happenings, visit <https://code.google.com/p/linux-track/>
diff --git a/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.am b/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.am
new file mode 100644
index 00000000..02747edb
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.am
@@ -0,0 +1,54 @@
+noinst_SCRIPTS =
+if WINE_PLUGIN
+ noinst_SCRIPTS += ftc.exe.so
+endif #WINE_PLUGIN
+
+if DARWIN
+ LDFLAGS += -Wl,-no_arch_warnings
+else
+ LDFLAGS += -Wl,--no-warn-search-mismatch
+endif
+
+CC = winegcc
+
+CXX = wineg++
+
+SUFFIXES = .o .cpp .c .rc
+
+.cpp.o :
+ $(CXX) -c $(CXXFLAGS_PRE) $(CXXFLAGS) $(CPPFLAGS) -m32 -o $@ $<
+
+.c.o :
+ $(CC) -c $(CFLAGS_PRE) $(CFLAGS) $(CPPFLAGS) -m32 -o $@ $<
+
+.rc.o :
+ wrc -o $@ $(RCFLAGS) $<
+
+CXXFLAGS_PRE = -g -DHAVE_CONFIG_H -I../../.. -I. -I@srcdir@/../.. -I@top_builddir@
+CFLAGS_PRE = -g -I../.. -I../../.. -DHAVE_CONFIG_H -I@srcdir@/../.. -I@top_builddir@
+RCFLAGS = -I @srcdir@
+#VPATH = ../..:@srcdir@/../..:@top_builddir@:@srcdir@
+vpath %.h @srcdir@/../..
+vpath %.h @top_builddir@
+vpath %.c @srcdir@
+vpath %.c @srcdir@/../..
+
+ftc.exe.so : main.o fttester.o
+ wineg++ -g -o $@ -L. $(WINE_LIBS) $(LDFLAGS) -m32 -Wall -Wextra $^
+
+fttester.o : fttester.rc resource.h config.h
+
+main.o : main.cpp
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+distclean-local: distclean-local-check
+.PHONY: distclean-local-check
+distclean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+EXTRA_DIST = resource.h fttester.rc main.cpp
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.in b/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.in
new file mode 100644
index 00000000..d1fff34d
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/ft_tester/Makefile.in
@@ -0,0 +1,491 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@WINE_PLUGIN_TRUE@am__append_1 = ftc.exe.so
+@DARWIN_TRUE@am__append_2 = -Wl,-no_arch_warnings
+@DARWIN_FALSE@am__append_3 = -Wl,--no-warn-search-mismatch
+subdir = src/wine_bridge/ft_tester
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/fttester.rc.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = fttester.rc
+CONFIG_CLEAN_VPATH_FILES =
+SCRIPTS = $(noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BISON = @BISON@
+CC = winegcc
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = wineg++
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@ $(am__append_2) $(am__append_3)
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIB32DIR = @LIB32DIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCFLAGS = @OBJCFLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENCV_CFLAGS = @OPENCV_CFLAGS@
+OPENCV_LIBS = @OPENCV_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QMAKE_PATH = @QMAKE_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINE64_LIBS = @WINE64_LIBS@
+WINE_LIBS = @WINE_LIBS@
+XPL_CPPFLAGS = @XPL_CPPFLAGS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_OBJC = @ac_ct_OBJC@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+with_makensis = @with_makensis@
+with_wine64 = @with_wine64@
+noinst_SCRIPTS = $(am__append_1)
+SUFFIXES = .o .cpp .c .rc
+CXXFLAGS_PRE = -g -DHAVE_CONFIG_H -I../../.. -I. -I@srcdir@/../.. -I@top_builddir@
+CFLAGS_PRE = -g -I../.. -I../../.. -DHAVE_CONFIG_H -I@srcdir@/../.. -I@top_builddir@
+RCFLAGS = -I @srcdir@
+EXTRA_DIST = resource.h fttester.rc main.cpp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .o .cpp .c .rc
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps src/wine_bridge/ft_tester/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps src/wine_bridge/ft_tester/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+fttester.rc: $(top_builddir)/config.status $(srcdir)/fttester.rc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ clean-local cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distclean-local distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am
+
+
+.cpp.o :
+ $(CXX) -c $(CXXFLAGS_PRE) $(CXXFLAGS) $(CPPFLAGS) -m32 -o $@ $<
+
+.c.o :
+ $(CC) -c $(CFLAGS_PRE) $(CFLAGS) $(CPPFLAGS) -m32 -o $@ $<
+
+.rc.o :
+ wrc -o $@ $(RCFLAGS) $<
+#VPATH = ../..:@srcdir@/../..:@top_builddir@:@srcdir@
+vpath %.h @srcdir@/../..
+vpath %.h @top_builddir@
+vpath %.c @srcdir@
+vpath %.c @srcdir@/../..
+
+ftc.exe.so : main.o fttester.o
+ wineg++ -g -o $@ -L. $(WINE_LIBS) $(LDFLAGS) -m32 -Wall -Wextra $^
+
+fttester.o : fttester.rc resource.h config.h
+
+main.o : main.cpp
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+distclean-local: distclean-local-check
+.PHONY: distclean-local-check
+distclean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/facetracknoir/clientfiles/very-important-source-code/ft_tester/fttester.rc.in b/facetracknoir/clientfiles/very-important-source-code/ft_tester/fttester.rc.in
new file mode 100644
index 00000000..332f3c73
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/ft_tester/fttester.rc.in
@@ -0,0 +1,67 @@
+// Generated by ResEdit 1.5.9
+// Copyright (C) 2006-2011
+// http://www.resedit.net
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+#include "resource.h"
+
+#ifdef HAVE_CONFIG_H
+ #include "../../../config.h"
+#endif
+
+
+
+
+//
+// Dialog resources
+//
+//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+IDD_DIALOG1 DIALOGEX 0, 0, 333, 183
+STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
+CAPTION "FreeTrack client test utility v@PACKAGE_VERSION@"
+FONT 8, "Ms Shell Dlg", 400, 0, 1
+{
+ DEFPUSHBUTTON "Quit", IDQUIT, 262, 153, 50, 14
+ PUSHBUTTON "Start", IDC_START, 199, 153, 50, 14
+ EDITTEXT IDC_YAW, 38, 15, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Yaw", IDC_STATIC, 12, 17, 21, 14, SS_RIGHT
+ EDITTEXT IDC_PITCH, 38, 38, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Pitch", IDC_STATIC, 16, 40, 17, 14, SS_RIGHT
+ EDITTEXT IDC_ROLL, 38, 61, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Roll", IDC_STATIC, 20, 63, 13, 14, SS_RIGHT
+ EDITTEXT IDC_X, 38, 84, 48, 14, ES_AUTOHSCROLL
+ RTEXT "X", IDC_STATIC, 27, 86, 6, 14, SS_RIGHT
+ EDITTEXT IDC_Y, 38, 107, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Y", IDC_STATIC, 27, 109, 6, 14, SS_RIGHT
+ EDITTEXT IDC_Z, 38, 130, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Z", IDC_STATIC, 27, 132, 6, 14, SS_RIGHT
+ EDITTEXT IDC_RYAW, 137, 15, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw Yaw", IDC_STATIC, 101, 17, 32, 8, SS_RIGHT
+ EDITTEXT IDC_RPITCH, 137, 38, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw Pitch", IDC_STATIC, 99, 40, 34, 8, SS_RIGHT
+ EDITTEXT IDC_RROLL, 137, 61, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw Roll", IDC_STATIC, 103, 63, 30, 8, SS_RIGHT
+ EDITTEXT IDC_RX, 137, 84, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw X", IDC_STATIC, 111, 86, 22, 8, SS_RIGHT
+ EDITTEXT IDC_RY, 137, 107, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw Y", IDC_STATIC, 111, 109, 22, 8, SS_RIGHT
+ EDITTEXT IDC_RZ, 137, 130, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Raw Z", IDC_STATIC, 111, 132, 22, 8, SS_RIGHT
+ EDITTEXT IDC_NUM, 264, 15, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Frame Number", IDC_STATIC, 212, 17, 47, 8, SS_RIGHT
+ EDITTEXT IDC_RES, 264, 38, 48, 14, ES_AUTOHSCROLL
+ RTEXT "Camera Resolution", IDC_STATIC, 199, 40, 60, 8, SS_RIGHT
+ EDITTEXT IDC_PT0, 227, 61, 85, 14, ES_AUTOHSCROLL
+ RTEXT "Point 1", IDC_STATIC, 199, 63, 23, 8, SS_RIGHT
+ EDITTEXT IDC_PT1, 227, 84, 85, 14, ES_AUTOHSCROLL
+ RTEXT "Point 2", IDC_STATIC, 199, 86, 23, 8, SS_RIGHT
+ EDITTEXT IDC_PT2, 227, 107, 85, 14, ES_AUTOHSCROLL
+ RTEXT "Point 3", IDC_STATIC, 199, 109, 23, 8, SS_RIGHT
+ EDITTEXT IDC_PT3, 227, 130, 85, 14, ES_AUTOHSCROLL
+ RTEXT "Point 4", IDC_STATIC, 199, 132, 23, 8, SS_RIGHT
+ EDITTEXT IDC_TITLE, 38, 153, 147, 14, ES_AUTOHSCROLL
+ RTEXT "Title", IDC_STATIC, 19, 155, 14, 8, SS_RIGHT
+}
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/ft_tester/main.cpp b/facetracknoir/clientfiles/very-important-source-code/ft_tester/main.cpp
new file mode 100644
index 00000000..a737f88f
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/ft_tester/main.cpp
@@ -0,0 +1,211 @@
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <cstdio>
+#include <stdint.h>
+#include <sstream>
+#include <cstdlib>
+#include <iomanip>
+
+#include "resource.h"
+
+HINSTANCE hInst;
+UINT_PTR timer = 0;
+
+HMODULE ftclient;
+
+typedef struct
+{
+ unsigned int dataID;
+ int res_x; int res_y;
+ float yaw; // positive yaw to the left
+ float pitch;// positive pitch up
+ float roll;// positive roll to the left
+ float x;
+ float y;
+ float z;
+ // raw pose with no smoothing, sensitivity, response curve etc.
+ float ryaw;
+ float rpitch;
+ float rroll;
+ float rx;
+ float ry;
+ float rz;
+ // raw points, sorted by Y, origin top left corner
+ float x0, y0;
+ float x1, y1;
+ float x2, y2;
+ float x3, y3;
+}FreeTrackData;
+
+
+typedef bool (WINAPI *importGetData)(FreeTrackData * data);
+typedef char *(WINAPI *importGetDllVersion)(void);
+typedef void (WINAPI *importReportName)(char *name);
+typedef char *(WINAPI *importProvider)(void);
+
+importGetData getData;
+importGetDllVersion getDllVersion;
+importReportName reportName;
+importProvider provider;
+
+
+char *client_path()
+{
+ HKEY hkey = 0;
+ RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Freetrack\\FreetrackClient", 0,
+ KEY_QUERY_VALUE, &hkey);
+ if(!hkey){
+ printf("Can't open registry key\n");
+ return NULL;
+ }
+
+ BYTE path[1024];
+ DWORD buf_len = 1024;
+ LONG result = RegQueryValueEx(hkey, "Path", NULL, NULL, path, &buf_len);
+ char *full_path = (char *)malloc(2048);
+ if(result == ERROR_SUCCESS && buf_len > 0){
+ sprintf(full_path, "%s\\FreeTrackClient.dll", path);
+ }
+ RegCloseKey(hkey);
+ return full_path;
+}
+
+
+bool start(HWND hwnd)
+{
+ char *libname = client_path();
+ if(libname == NULL){
+ printf("Freetrack client not found!\n");
+ return false;
+ }
+ ftclient = LoadLibrary(libname);
+ if(ftclient == NULL){
+ printf("Couldn't load Freetrack client library '%s'!\n", libname);
+ return false;
+ }
+ printf("Freetrack client library %s loaded.\n", client_path());
+
+
+ getData = (importGetData)GetProcAddress(ftclient, "FTGetData");
+ getDllVersion = (importGetDllVersion)GetProcAddress(ftclient, "FTGetDllVersion");
+ reportName = (importReportName)GetProcAddress(ftclient, "FTReportName");
+ provider = (importProvider)GetProcAddress(ftclient, "FTProvider");
+
+ if((getData == NULL) || (getDllVersion == NULL) || (reportName == NULL) || (provider == NULL)){
+ printf("Couldn't load Freetrack client functions!\n");
+ FreeLibrary(ftclient);
+ return false;
+ }
+
+ printf("Dll version: %s\n", getDllVersion());
+ printf("Provider: %s\n", provider());
+ char title[1024];
+ GetDlgItemText(hwnd, IDC_TITLE, title, 1020);
+ reportName(title);
+ return true;
+}
+
+void reportError(std::string msg)
+{
+ MessageBoxA(0, "FreeTrack client test", msg.c_str(), 0);
+}
+VOID CALLBACK TimerProcedure(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ (void) uMsg;
+ (void) idEvent;
+ (void) dwTime;
+ FreeTrackData d;
+ getData(&d);
+ SetDlgItemInt(hwnd, IDC_PITCH, d.pitch, true);
+ SetDlgItemInt(hwnd, IDC_ROLL, d.roll, true);
+ SetDlgItemInt(hwnd, IDC_YAW, d.yaw, true);
+
+ SetDlgItemInt(hwnd, IDC_X, d.x, true);
+ SetDlgItemInt(hwnd, IDC_Y, d.y, true);
+ SetDlgItemInt(hwnd, IDC_Z, d.z, true);
+
+ SetDlgItemInt(hwnd, IDC_RPITCH, d.rpitch, true);
+ SetDlgItemInt(hwnd, IDC_RROLL, d.rroll, true);
+ SetDlgItemInt(hwnd, IDC_RYAW, d.ryaw, true);
+
+ SetDlgItemInt(hwnd, IDC_RX, d.rx, true);
+ SetDlgItemInt(hwnd, IDC_RY, d.ry, true);
+ SetDlgItemInt(hwnd, IDC_RZ, d.rz, true);
+
+ std::ostringstream s;
+ s.str(std::string());
+ s<<"("<<std::fixed<<std::setprecision(1)<<d.x0<<"; "<<d.y0<<")";
+ SetDlgItemText(hwnd, IDC_PT0, s.str().c_str());
+
+ s.str(std::string());
+ s<<"("<<std::fixed<<std::setprecision(1)<<d.x1<<"; "<<d.y1<<")";
+ SetDlgItemText(hwnd, IDC_PT1, s.str().c_str());
+
+ s.str(std::string());
+ s<<"("<<std::fixed<<std::setprecision(1)<<d.x2<<"; "<<d.y2<<")";
+ SetDlgItemText(hwnd, IDC_PT2, s.str().c_str());
+
+ s.str(std::string());
+ s<<"("<<std::fixed<<std::setprecision(1)<<d.x3<<"; "<<d.y3<<")";
+ SetDlgItemText(hwnd, IDC_PT3, s.str().c_str());
+
+ s.str(std::string());
+ s<<d.res_x<<"x"<<d.res_y;
+ SetDlgItemText(hwnd, IDC_RES, s.str().c_str());
+ SetDlgItemInt(hwnd, IDC_NUM, d.dataID, true);
+}
+
+BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ (void) lParam;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwndDlg, IDC_TITLE, "Default");
+ return TRUE;
+
+ case WM_CLOSE:
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ /*
+ * TODO: Add more control ID's, when needed.
+ */
+ case IDQUIT:
+ FreeLibrary(ftclient);
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+ case IDC_START:
+ start(hwndDlg);
+//l int ok;
+// int num = GetDlgItemInt(hwndDlg, IDC_APPID, (BOOL*)&ok, false);
+ if(timer != 0){
+ KillTimer(hwndDlg, timer);
+ timer = 0;
+ }
+ timer = SetTimer(hwndDlg, 0, 50, TimerProcedure);
+ break;
+
+ }
+ }
+
+ return FALSE;
+}
+
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ (void) hPrevInstance;
+ (void) lpCmdLine;
+ (void) nShowCmd;
+ hInst = hInstance;
+
+ // The user interface is a modal dialog box
+ return DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DialogProc);
+}
+
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/ft_tester/resource.h b/facetracknoir/clientfiles/very-important-source-code/ft_tester/resource.h
new file mode 100644
index 00000000..8bba17b4
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/ft_tester/resource.h
@@ -0,0 +1,27 @@
+#ifndef IDC_STATIC
+#define IDC_STATIC (-1)
+#endif
+
+#define IDD_DIALOG1 100
+#define IDQUIT 1002
+#define IDC_YAW 1005
+#define IDC_PITCH 1023
+#define IDC_ROLL 1024
+#define IDC_X 1025
+#define IDC_Y 1026
+#define IDC_Z 1027
+#define IDC_RYAW 1028
+#define IDC_RPITCH 1029
+#define IDC_RROLL 1030
+#define IDC_RX 1031
+#define IDC_RY 1032
+#define IDC_RZ 1033
+#define IDC_NUM 1034
+#define IDC_RES 1035
+#define IDC_PT0 1036
+#define IDC_PT1 1037
+#define IDC_PT2 1038
+#define IDC_PT3 1039
+#define IDC_START 1040
+#define IDC_TITLE 1041
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.h b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.h
new file mode 100644
index 00000000..770e1c71
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.h
@@ -0,0 +1,17 @@
+
+extern int NP_RegisterWindowHandle (HWND hwnd);
+extern int NP_UnregisterWindowHandle (void);
+extern int NP_RegisterProgramProfileID (unsigned short id);
+extern int NP_QueryVersion (unsigned short *version);
+extern int NP_RequestData (unsigned short req);
+extern int NP_GetSignature (tir_signature_t *sig);
+extern int NP_GetData (tir_data_t *data);
+extern int NP_GetParameter (void);
+extern int NP_SetParameter (void);
+extern int NP_StartCursor (void);
+extern int NP_StopCursor (void);
+extern int NP_ReCenter (void);
+extern int NP_StartDataTransmission (void);
+extern int NP_StopDataTransmission (void);
+
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.spec b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.spec
new file mode 100644
index 00000000..7fe5f1b4
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient.spec
@@ -0,0 +1,23 @@
+# Generated from NPClient.dll by winedump
+
+1 stub NPPriv_ClientNotify
+2 stub NPPriv_GetLastError
+3 stub NPPriv_SetData
+4 stub NPPriv_SetLastError
+5 stub NPPriv_SetParameter
+6 stub NPPriv_SetSignature
+7 stub NPPriv_SetVersion
+8 stdcall NP_GetData( ptr ) NPCLIENT_NP_GetData
+9 stdcall NP_GetParameter( long long) NPCLIENT_NP_GetParameter
+10 stdcall NP_GetSignature( ptr ) NPCLIENT_NP_GetSignature
+11 stdcall NP_QueryVersion( ptr ) NPCLIENT_NP_QueryVersion
+12 stdcall NP_ReCenter() NPCLIENT_NP_ReCenter
+13 stdcall NP_RegisterProgramProfileID( long ) NPCLIENT_NP_RegisterProgramProfileID
+14 stdcall NP_RegisterWindowHandle( ptr ) NPCLIENT_NP_RegisterWindowHandle
+15 stdcall NP_RequestData( long ) NPCLIENT_NP_RequestData
+16 stdcall NP_SetParameter( long long ) NPCLIENT_NP_SetParameter
+17 stdcall NP_StartCursor() NPCLIENT_NP_StartCursor
+18 stdcall NP_StartDataTransmission() NPCLIENT_NP_StartDataTransmission
+19 stdcall NP_StopCursor() NPCLIENT_NP_StopCursor
+20 stdcall NP_StopDataTransmission() NPCLIENT_NP_StopDataTransmission
+21 stdcall NP_UnregisterWindowHandle() NPCLIENT_NP_UnregisterWindowHandle
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_dll.h b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_dll.h
new file mode 100644
index 00000000..b0bab5db
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_dll.h
@@ -0,0 +1,58 @@
+/*
+ * NPClient.dll
+ *
+ * Generated from NPClient.dll by winedump.
+ *
+ * DO NOT SEND GENERATED DLLS FOR INCLUSION INTO WINE !
+ *
+ */
+#ifndef __WINE_NPCLIENT_DLL_H
+#define __WINE_NPCLIENT_DLL_H
+
+#include "windef.h"
+#include "wine/debug.h"
+#include "winbase.h"
+#include "winnt.h"
+
+#pragma pack(1)
+typedef struct tir_data{
+ short status;
+ short frame;
+ unsigned int cksum;
+ float roll, pitch, yaw;
+ float tx, ty, tz;
+ float padding[9];
+} tir_data_t;
+
+typedef struct tir_signature{
+ char DllSignature[200];
+ char AppSignature[200];
+} tir_signature_t;
+#pragma pack(0)
+
+
+/* __stdcall NPCLIENT_NPPriv_ClientNotify(); */
+/* __stdcall NPCLIENT_NPPriv_GetLastError(); */
+/* __stdcall NPCLIENT_NPPriv_SetData(); */
+/* __stdcall NPCLIENT_NPPriv_SetLastError(); */
+/* __stdcall NPCLIENT_NPPriv_SetParameter(); */
+/* __stdcall NPCLIENT_NPPriv_SetSignature(); */
+/* __stdcall NPCLIENT_NPPriv_SetVersion(); */
+int __stdcall NPCLIENT_NP_GetData(tir_data_t * data);
+int __stdcall NPCLIENT_NP_GetParameter(int arg0, int arg1);
+int __stdcall NPCLIENT_NP_GetSignature(tir_signature_t * sig);
+int __stdcall NPCLIENT_NP_QueryVersion(unsigned short * version);
+int __stdcall NPCLIENT_NP_ReCenter(void);
+int __stdcall NPCLIENT_NP_RegisterProgramProfileID(unsigned short id);
+int __stdcall NPCLIENT_NP_RegisterWindowHandle(HWND hwnd);
+int __stdcall NPCLIENT_NP_RequestData(unsigned short req);
+int __stdcall NPCLIENT_NP_SetParameter(int arg0, int arg1);
+int __stdcall NPCLIENT_NP_StartCursor(void);
+int __stdcall NPCLIENT_NP_StartDataTransmission(void);
+int __stdcall NPCLIENT_NP_StopCursor(void);
+int __stdcall NPCLIENT_NP_StopDataTransmission(void);
+int __stdcall NPCLIENT_NP_UnregisterWindowHandle(void);
+
+
+
+#endif /* __WINE_NPCLIENT_DLL_H */
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_main.c b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_main.c
new file mode 100644
index 00000000..f892f89e
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/NPClient_main.c
@@ -0,0 +1,444 @@
+/*
+ * NPClient.dll
+ *
+ * Generated from NPClient.dll by winedump.
+ *
+ * DO NOT SUBMIT GENERATED DLLS FOR INCLUSION INTO WINE!
+ *
+ */
+
+#include <linuxtrack.h>
+#include "rest.h"
+//#include "config.h"
+#define __WINESRC__
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+#include "NPClient_dll.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(NPClient);
+
+bool crypted = false;
+static unsigned char table[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static int dbg_flag;
+
+static void dbg_report(const char *msg,...)
+{
+ static FILE *f = NULL;
+ if(dbg_flag){
+ if(f == NULL){
+ f = fopen("NPClient.log", "w");
+ }
+ va_list ap;
+ va_start(ap,msg);
+ vfprintf(f, msg, ap);
+ fflush(f);
+ va_end(ap);
+ }
+}
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+ switch (fdwReason)
+ {
+ case DLL_WINE_PREATTACH:
+ return TRUE;
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ dbg_flag = getDebugFlag('w');
+ dbg_report("Attach request\n");
+ break;
+ case DLL_PROCESS_DETACH:
+ linuxtrack_shutdown();
+ break;
+ }
+
+ return TRUE;
+}
+/******************************************************************
+ * NPPriv_ClientNotify (NPCLIENT.1)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_ClientNotify()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_GetLastError (NPCLIENT.2)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_GetLastError()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_SetData (NPCLIENT.3)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_SetData()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_SetLastError (NPCLIENT.4)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_SetLastError()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_SetParameter (NPCLIENT.5)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_SetParameter()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_SetSignature (NPCLIENT.6)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_SetSignature()
+{
+ /* @stub in .spec */
+}
+#endif
+/******************************************************************
+ * NPPriv_SetVersion (NPCLIENT.7)
+ *
+ *
+ */
+#if 0
+__stdcall NPCLIENT_NPPriv_SetVersion()
+{
+ /* @stub in .spec */
+}
+#endif
+
+static float limit_num(float min, float val, float max)
+{
+ if(val < min) return min;
+ if(val > max) return max;
+ return val;
+}
+
+static unsigned int cksum(unsigned char buf[], unsigned int size)
+{
+ if((size == 0) || (buf == NULL)){
+ return 0;
+ }
+
+ int rounds = size >> 2;
+ int rem = size % 4;
+
+ int c = size;
+ int a0, a2;
+// printf("Orig: ");
+//for(a0 = 0; a0 < (int)size; ++a0)
+//{
+// printf("%02X", buf[a0]);
+//}
+//printf("\n");
+ while(rounds != 0){
+ a0 = *(short int*)buf;
+ a2 = *(short int*)(buf+2);
+ buf += 4;
+ c += a0;
+ a2 ^= (c << 5);
+ a2 <<= 11;
+ c ^= a2;
+ c += (c >> 11);
+ --rounds;
+ }
+ switch(rem){
+ case 3:
+ a0 = *(short int*)buf;
+ a2 = *(signed char*)(buf+2);
+ c += a0;
+ a2 = (a2 << 2) ^ c;
+ c ^= (a2 << 16);
+ a2 = (c >> 11);
+ break;
+ case 2:
+ a2 = *(short int*)buf;
+ c += a2;
+ c ^= (c << 11);
+ a2 = (c >> 17);
+ break;
+ case 1:
+ a2 = *(signed char*)(buf);
+ c += a2;
+ c ^= (c << 10);
+ a2 = (c >> 1);
+ break;
+ default:
+ break;
+ }
+ if(rem != 0){
+ c+=a2;
+ }
+
+ c ^= (c << 3);
+ c += (c >> 5);
+ c ^= (c << 4);
+ c += (c >> 17);
+ c ^= (c << 25);
+ c += (c >> 6);
+
+ return (unsigned int)c;
+}
+
+static void enhance(unsigned char buf[], unsigned int size,
+ unsigned char codetable[], unsigned int table_size)
+{
+ unsigned int table_ptr = 0;
+ unsigned char var = 0x88;
+ unsigned char tmp;
+ if((size <= 0) || (table_size <= 0) ||
+ (buf == NULL) || (codetable == NULL)){
+ return;
+ }
+ do{
+ tmp = buf[--size];
+ buf[size] = tmp ^ codetable[table_ptr] ^ var;
+ var += size + tmp;
+ ++table_ptr;
+ if(table_ptr >= table_size){
+ table_ptr -= table_size;
+ }
+ }while(size != 0);
+}
+
+
+/******************************************************************
+ * NP_GetData (NPCLIENT.8)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_GetData(tir_data_t * data)
+{
+ float r, p, y, tx, ty, tz;
+ unsigned int frame;
+ int res = linuxtrack_get_pose(&y, &p, &r, &tx, &ty, &tz, &frame);
+ memset((char *)data, 0, sizeof(tir_data_t));
+ data->status = (linuxtrack_get_tracking_state() == RUNNING) ? 0 : 1;
+ data->frame = frame & 0xFFFF;
+ data->cksum = 0;
+ data->roll = r / 180.0 * 16383;
+ data->pitch = -p / 180.0 * 16383;
+ data->yaw = y / 180.0 * 16383;
+ data->tx = -limit_num(-16383.0, 15 * tx, 16383);
+ data->ty = limit_num(-16383.0, 15 * ty, 16383);
+ data->tz = limit_num(-16383.0, 15 * tz, 16383);
+ data->cksum = cksum((unsigned char*)data, sizeof(tir_data_t));
+ //printf("Cksum: %04X\n", data->cksum);
+ if(crypted){
+ enhance((unsigned char*)data, sizeof(tir_data_t), table, sizeof(table));
+ }
+ return (res >= 0) ? 0: 1;
+}
+/******************************************************************
+ * NP_GetParameter (NPCLIENT.9)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_GetParameter(int arg0, int arg1)
+{
+ dbg_report("GetParameter request: %d %d\n", arg0, arg1);
+ TRACE("(void): stub\n");
+ return (int) 0;
+}
+
+/******************************************************************
+ * NP_GetSignature (NPCLIENT.10)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_GetSignature(tir_signature_t * sig)
+{
+ dbg_report("GetSignature request\n");
+ if(getSomeSeriousPoetry(sig->DllSignature, sig->AppSignature)){
+ printf("Signature result: OK\n");
+ return 0;
+ }else{
+ printf("Signature result: NOT OK!\n");
+ return 1;
+ }
+}
+/******************************************************************
+ * NP_QueryVersion (NPCLIENT.11)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_QueryVersion(unsigned short * version)
+{
+ dbg_report("QueryVersion request\n");
+ *version=0x0500;
+ return 0;
+}
+/******************************************************************
+ * NP_ReCenter (NPCLIENT.12)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_ReCenter(void)
+{
+ dbg_report("ReCenter request\n");
+ linuxtrack_recenter();
+ return 0;
+}
+
+/******************************************************************
+ * NP_RegisterProgramProfileID (NPCLIENT.13)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_RegisterProgramProfileID(unsigned short id)
+{
+ dbg_report("RegisterProgramProfileID request: %d\n", id);
+ game_desc_t gd;
+ if(game_data_get_desc(id, &gd)){
+ printf("Application ID: %d - %s!!!\n", id, gd.name);
+ if(game_data_get_desc(id, &gd)){
+ crypted = gd.encrypted;
+ if(gd.encrypted){
+ printf("Table: %02X %02X %02X %02X %02X %02X %02X %02X\n", table[0],table[1],table[2],table[3],table[4],
+ table[5], table[6], table[7]);
+ table[0] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[1] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[2] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[3] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[4] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[5] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[6] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[7] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ }
+ }
+ if(linuxtrack_init(gd.name) != 0){
+ return 1;
+ }
+ }else{
+ if(!linuxtrack_init("Default")){
+ return 1;
+ }
+ }
+ linuxtrack_suspend();
+ return 0;
+}
+/******************************************************************
+ * NP_RegisterWindowHandle (NPCLIENT.14)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_RegisterWindowHandle(HWND hwnd)
+{
+ dbg_report("RegisterWindowHandle request: 0x%X\n", hwnd);
+ TRACE("((HWND)%p): stub\n",hwnd);
+ return (int) 0;
+}
+/******************************************************************
+ * NP_RequestData (NPCLIENT.15)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_RequestData(unsigned short req)
+{
+ dbg_report("RequestData request: %d\n", req);
+ TRACE("((unsigned short)%d): stub\n",req);
+ return (int) 0;
+}
+/******************************************************************
+ * NP_SetParameter (NPCLIENT.16)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_SetParameter(int arg0, int arg1)
+{
+ dbg_report("SetParameter request: %d %d\n", arg0, arg1);
+ TRACE("(void): stub\n");
+ return (int) 0;
+}
+/******************************************************************
+ * NP_StartCursor (NPCLIENT.17)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_StartCursor(void)
+{
+ dbg_report("StartCursor request\n");
+ TRACE("(void): stub\n");
+ return (int) 0;
+}
+/******************************************************************
+ * NP_StartDataTransmission (NPCLIENT.18)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_StartDataTransmission(void)
+{
+ dbg_report("StartDataTransmission request\n");
+ linuxtrack_wakeup();
+ return 0;
+}
+/******************************************************************
+ * NP_StopCursor (NPCLIENT.19)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_StopCursor(void)
+{
+ dbg_report("StopCursor request\n");
+ TRACE("(void): stub\n");
+ return (int) 0;
+}
+/******************************************************************
+ * NP_StopDataTransmission (NPCLIENT.20)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_StopDataTransmission(void)
+{
+ dbg_report("StopDataTransmission request\n");
+ linuxtrack_suspend();
+ return 0;
+}
+/******************************************************************
+ * NP_UnregisterWindowHandle (NPCLIENT.21)
+ *
+ *
+ */
+int __stdcall NPCLIENT_NP_UnregisterWindowHandle(void)
+{
+ dbg_report("UnregisterWindowHandle request\n");
+ TRACE("(void): stub\n");
+ return (int) 0;
+}
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.c b/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.c
new file mode 100644
index 00000000..f80a7d44
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.c
@@ -0,0 +1,150 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <mxml.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <string.h>
+
+//First 5 bytes is MD5 hash of "NaturalPoint"
+static uint8_t secret_key[] = {0x0e, 0x9a, 0x63, 0x71, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static uint8_t S[256] = {0};
+
+static char *decoded = NULL;
+
+static mxml_node_t *xml = NULL;
+static mxml_node_t *tree = NULL;
+
+static void ksa(uint8_t key[], size_t len)
+{
+ unsigned int i, j;
+ for(i = 0; i < 256; ++i){
+ S[i] = i;
+ }
+ j = 0;
+ for(i = 0; i < 256; ++i){
+ j = (j + S[i] + key[i % len]) % 256;
+ uint8_t tmp = S[i];
+ S[i] = S[j];
+ S[j] = tmp;
+ }
+}
+
+static uint8_t rc4()
+{
+ static uint8_t i = 0;
+ static uint8_t j = 0;
+
+ i += 1;
+ j += S[i];
+ uint8_t tmp = S[i];
+ S[i] = S[j];
+ S[j] = tmp;
+ return S[(S[i] + S[j]) % 256];
+}
+
+static bool decrypt_file(const char *fname, bool from_update)
+{
+ uint32_t header[5];
+ size_t datlen;
+ ksa(secret_key, 16);
+ FILE *inp;
+ struct stat fst;
+
+ if((inp = fopen(fname, "rb")) == NULL){
+ printf("Can't open input file '%s'", fname);
+ return false;
+ }
+
+ if(fstat(fileno(inp), &fst) != 0){
+ fclose(inp);
+ printf("Cannot stat file '%s'\n", fname);
+ return false;
+ }
+
+ if(from_update){
+ if(fread(&header, sizeof(uint32_t), 5, inp) != 5){
+ fclose(inp);
+ printf("Can't read the header - file '%s' is less than 20 bytes long?\n", fname);
+ return false;
+ }
+ datlen = header[4];
+ }else{
+ datlen = fst.st_size;
+ }
+ if((decoded = (char *)malloc(datlen+1)) == NULL){
+ printf("malloc failed!\n");
+ return false;
+ }
+ memset(decoded, 0, datlen+1);
+ size_t i;
+ size_t len = fread(decoded, 1, datlen, inp);
+ (void) len;
+ for(i = 0; i < datlen; ++i) decoded[i] ^= rc4();
+ fclose(inp);
+
+ //inp = fopen("tmp.dump", "w");
+ //fwrite(decoded, 1, datlen, inp);
+ //fclose(inp);
+
+ return true;
+}
+
+static bool game_data_init(const char *fname, bool from_update)
+{
+ static bool initialized = false;
+ if(initialized){
+ return true;
+ }
+ if(!decrypt_file(fname, from_update)){
+ printf("Error decrypting file!\n");
+ return false;
+ }
+ xml = mxmlNewXML("1.0");
+ tree = mxmlLoadString(xml, decoded, MXML_TEXT_CALLBACK);
+ return (tree != NULL);
+}
+
+static void game_data_close()
+{
+ mxmlDelete(tree);
+ free(decoded);
+}
+
+#define ltr_int_log_message(...) fprintf(stderr, __VA_ARGS__)
+
+bool get_game_data(const char *input_fname, const char *output_fname, bool from_update)
+{
+ FILE *outfile = NULL;
+ if((outfile = (output_fname ? fopen(output_fname, "w") : stdout)) == NULL){
+ ltr_int_log_message("Can't open the output file '%s'!\n", output_fname);
+ return false;
+ }
+ if(!game_data_init(input_fname, from_update)){
+ ltr_int_log_message("Can't process the data file '%s'!\n", input_fname);
+ return false;
+ }
+
+ mxml_node_t *game;
+ const char *name;
+ const char *id;
+ for(game = mxmlFindElement(tree, tree, "Game", NULL, NULL, MXML_DESCEND);
+ game != NULL;
+ game = mxmlFindElement(game, tree, "Game", NULL, NULL, MXML_DESCEND)){
+ name = mxmlElementGetAttr(game, "Name");
+ id = mxmlElementGetAttr(game, "Id");
+
+ mxml_node_t *appid = mxmlFindElement(game, game, "ApplicationID", NULL, NULL, MXML_DESCEND);
+ if(appid == NULL){
+ fprintf(outfile, "%s \"%s\"\n", id, name);
+ }else{
+ fprintf(outfile, "%s \"%s\" (%s)\n", id, name, appid->child->value.text.string);
+ }
+ }
+ fclose(outfile);
+ game_data_close();
+ return true;
+}
+
+int main(int argc, char** argv) { return argc > 1 && get_game_data(argv[1], NULL, false); }
diff --git a/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.h b/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.h
new file mode 100644
index 00000000..b71f7a15
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/important-stuff/game_data.h
@@ -0,0 +1,17 @@
+#ifndef GAME_DATA__H
+#define GAME_DATA__H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool get_game_data(const char *input_fname, const char *output_fname, bool from_update);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.am b/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.am
new file mode 100644
index 00000000..e025209a
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.am
@@ -0,0 +1,78 @@
+noinst_SCRIPTS =
+if WINE_PLUGIN
+ noinst_SCRIPTS += Tester.exe
+if WINE64
+ noinst_SCRIPTS += Tester64.exe
+endif #WINE64
+endif #WINE_PLUGIN
+
+if DARWIN
+ LDFLAGS += -Wl,-no_arch_warnings
+else
+ LDFLAGS += -Wl,--no-warn-search-mismatch
+endif
+
+CC = winegcc
+
+CXX = wineg++
+
+SUFFIXES = .o .cpp .c .rc 64.o
+
+.cpp.o :
+ $(CXX) -c $(CXXFLAGS) -m32 -o $@ $<
+
+.c.o :
+ $(CC) -c $(CFLAGS) -m32 -o $@ $<
+
+.cpp64.o :
+ $(CXX) -c $(CXXFLAGS) -o $@ $<
+
+.c64.o :
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+.rc.o :
+ wrc -o $@ $(RCFLAGS) $<
+
+CXXFLAGS += -g -DHAVE_CONFIG_H -I../../.. -I. -I@srcdir@/../.. -I@top_builddir@
+CFLAGS += -g -I../.. -I../../.. -DHAVE_CONFIG_H -I@srcdir@/../.. -I@top_builddir@
+RCFLAGS = -I @srcdir@
+#VPATH = ../..:@srcdir@/../..:@top_builddir@:@srcdir@
+vpath %.h @srcdir@/../..
+vpath %.h @top_builddir@
+vpath %.c @srcdir@
+vpath %.c @srcdir@/../..
+
+
+Tester64.exe : main64.o rest64.o npifc64.o npview.o
+ wineg++ -g -o Tester64 -L. $(WINE64_LIBS) $(LDFLAGS) -Wall -Wextra $^
+
+Tester.exe : main.o npview.o rest.o npifc.o
+ wineg++ -g -o Tester -L. $(WINE_LIBS) $(LDFLAGS) -m32 -Wall -Wextra $^
+
+main.o : main.cpp Makefile
+
+main64.o : main.cpp Makefile
+
+npview.o : npview.rc
+
+rest.o : rest.c rest.h Makefile
+
+rest64.o : rest.c rest.h Makefile
+
+npifc.o : npifc.c npifc.h Makefile
+
+npifc64.o : CFLAGS+="-DFOR_WIN64=1"
+npifc64.o : npifc.c npifc.h Makefile
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+distclean-local: distclean-local-check
+.PHONY: distclean-local-check
+distclean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+EXTRA_DIST = main.cpp npifc.c npifc.h resource.h rest.c rest.h
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.in b/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.in
new file mode 100644
index 00000000..cc49d754
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/Makefile.in
@@ -0,0 +1,512 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@WINE_PLUGIN_TRUE@am__append_1 = Tester.exe
+@WINE64_TRUE@@WINE_PLUGIN_TRUE@am__append_2 = Tester64.exe
+@DARWIN_TRUE@am__append_3 = -Wl,-no_arch_warnings
+@DARWIN_FALSE@am__append_4 = -Wl,--no-warn-search-mismatch
+subdir = src/wine_bridge/tester
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/npview.rc.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = npview.rc
+CONFIG_CLEAN_VPATH_FILES =
+SCRIPTS = $(noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BISON = @BISON@
+CC = winegcc
+CFLAGS = @CFLAGS@ -g -I../.. -I../../.. -DHAVE_CONFIG_H \
+ -I@srcdir@/../.. -I@top_builddir@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = wineg++
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@ -g -DHAVE_CONFIG_H -I../../.. -I. \
+ -I@srcdir@/../.. -I@top_builddir@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@ $(am__append_3) $(am__append_4)
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIB32DIR = @LIB32DIR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCFLAGS = @OBJCFLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENCV_CFLAGS = @OPENCV_CFLAGS@
+OPENCV_LIBS = @OPENCV_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QMAKE_PATH = @QMAKE_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WINE64_LIBS = @WINE64_LIBS@
+WINE_LIBS = @WINE_LIBS@
+XPL_CPPFLAGS = @XPL_CPPFLAGS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_OBJC = @ac_ct_OBJC@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+with_makensis = @with_makensis@
+with_wine64 = @with_wine64@
+noinst_SCRIPTS = $(am__append_1) $(am__append_2)
+SUFFIXES = .o .cpp .c .rc 64.o
+RCFLAGS = -I @srcdir@
+EXTRA_DIST = main.cpp npifc.c npifc.h resource.h rest.c rest.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .o .cpp .c .rc 64.o
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps src/wine_bridge/tester/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps src/wine_bridge/tester/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+npview.rc: $(top_builddir)/config.status $(srcdir)/npview.rc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ clean-local cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distclean-local distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am
+
+
+.cpp.o :
+ $(CXX) -c $(CXXFLAGS) -m32 -o $@ $<
+
+.c.o :
+ $(CC) -c $(CFLAGS) -m32 -o $@ $<
+
+.cpp64.o :
+ $(CXX) -c $(CXXFLAGS) -o $@ $<
+
+.c64.o :
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+.rc.o :
+ wrc -o $@ $(RCFLAGS) $<
+#VPATH = ../..:@srcdir@/../..:@top_builddir@:@srcdir@
+vpath %.h @srcdir@/../..
+vpath %.h @top_builddir@
+vpath %.c @srcdir@
+vpath %.c @srcdir@/../..
+
+Tester64.exe : main64.o rest64.o npifc64.o npview.o
+ wineg++ -g -o Tester64 -L. $(WINE64_LIBS) $(LDFLAGS) -Wall -Wextra $^
+
+Tester.exe : main.o npview.o rest.o npifc.o
+ wineg++ -g -o Tester -L. $(WINE_LIBS) $(LDFLAGS) -m32 -Wall -Wextra $^
+
+main.o : main.cpp Makefile
+
+main64.o : main.cpp Makefile
+
+npview.o : npview.rc
+
+rest.o : rest.c rest.h Makefile
+
+rest64.o : rest.c rest.h Makefile
+
+npifc.o : npifc.c npifc.h Makefile
+
+npifc64.o : CFLAGS+="-DFOR_WIN64=1"
+npifc64.o : npifc.c npifc.h Makefile
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+distclean-local: distclean-local-check
+.PHONY: distclean-local-check
+distclean-local-check:
+ rm -f *.exe* *.dll* *.sh *.o
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/main.cpp b/facetracknoir/clientfiles/very-important-source-code/tester/main.cpp
new file mode 100644
index 00000000..95ca0d9b
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/main.cpp
@@ -0,0 +1,100 @@
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdint.h>
+#include "resource.h"
+#include "rest.h"
+#include "npifc.h"
+
+HINSTANCE hInst;
+UINT_PTR timer = 0;
+
+VOID CALLBACK TimerProcedure(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ (void) uMsg;
+ (void) idEvent;
+ (void) dwTime;
+ tir_data_t td;
+ npifc_getdata(&td);
+ SetDlgItemInt(hwnd, IDC_PITCH, td.pitch, true);
+ SetDlgItemInt(hwnd, IDC_ROLL, td.roll, true);
+ SetDlgItemInt(hwnd, IDC_YAW, td.yaw, true);
+
+ SetDlgItemInt(hwnd, IDC_X1, td.tx, true);
+ SetDlgItemInt(hwnd, IDC_Y1, td.ty, true);
+ SetDlgItemInt(hwnd, IDC_Z1, td.tz, true);
+
+ SetDlgItemInt(hwnd, IDC_X2, td.padding[0], true);
+ SetDlgItemInt(hwnd, IDC_Y2, td.padding[1], true);
+ SetDlgItemInt(hwnd, IDC_Z2, td.padding[2], true);
+ SetDlgItemInt(hwnd, IDC_X3, td.padding[3], true);
+ SetDlgItemInt(hwnd, IDC_Y3, td.padding[4], true);
+ SetDlgItemInt(hwnd, IDC_Z3, td.padding[5], true);
+ SetDlgItemInt(hwnd, IDC_S, td.status, true);
+ SetDlgItemInt(hwnd, IDC_F, td.frame, true);
+}
+
+BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ (void) lParam;
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemInt(hwndDlg, IDC_APPID, 2307, true);
+ return TRUE;
+
+ case WM_CLOSE:
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ /*
+ * TODO: Add more control ID's, when needed.
+ */
+ case IDQUIT:
+ npifc_close();
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+ case IDSTART:
+ int ok;
+ int num = GetDlgItemInt(hwndDlg, IDC_APPID, (BOOL*)&ok, false);
+ if(!ok){
+ num = 2307;
+ }
+ game_desc_t gd;
+ if(timer != 0){
+ KillTimer(hwndDlg, timer);
+ timer = 0;
+ }
+ if(game_data_get_desc(num, &gd)){
+ printf("Application ID: %d - %s\n", num, gd.name);
+ if(npifc_init(hwndDlg, num)){
+ timer = SetTimer(hwndDlg, 0, 50, TimerProcedure);
+ }
+ }else{
+ printf("Unknown Application ID: %d\n", num);
+ }
+ break;
+
+ }
+ }
+
+ return FALSE;
+}
+
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ (void) hPrevInstance;
+ (void) lpCmdLine;
+ (void) nShowCmd;
+ hInst = hInstance;
+
+ // The user interface is a modal dialog box
+ return DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DialogProc);
+}
+
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/npifc.c b/facetracknoir/clientfiles/very-important-source-code/tester/npifc.c
new file mode 100644
index 00000000..b036464e
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/npifc.c
@@ -0,0 +1,302 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "npifc.h"
+#include "rest.h"
+
+
+tir_signature_t ts;
+HMODULE npclient;
+/*
+typedef int (*NP_RegisterWindowHandle_t)(HWND hwnd);
+typedef int (*NP_UnregisterWindowHandle_t)(void);
+typedef int (*NP_RegisterProgramProfileID_t)(unsigned short id);
+typedef int (*NP_QueryVersion_t)(unsigned short *version);
+typedef int (*NP_RequestData_t)(unsigned short req);
+typedef int (*NP_GetSignature_t)(tir_signature_t *sig);
+typedef int (*NP_GetData_t)(tir_data_t *data);
+typedef int (*NP_GetParameter_t)(void);
+typedef int (*NP_SetParameter_t)(void);
+typedef int (*NP_StartCursor_t)(void);
+typedef int (*NP_StopCursor_t)(void);
+typedef int (*NP_ReCenter_t)(void);
+typedef int (*NP_StartDataTransmission_t)(void);
+typedef int (*NP_StopDataTransmission_t)(void);
+*/
+NP_RegisterWindowHandle_t NP_RegisterWindowHandle = NULL;
+NP_UnregisterWindowHandle_t NP_UnregisterWindowHandle = NULL;
+NP_RegisterProgramProfileID_t NP_RegisterProgramProfileID = NULL;
+NP_QueryVersion_t NP_QueryVersion = NULL;
+NP_RequestData_t NP_RequestData = NULL;
+NP_GetSignature_t NP_GetSignature = NULL;
+NP_GetData_t NP_GetData = NULL;
+NP_GetParameter_t NP_GetParameter = NULL;
+NP_SetParameter_t NP_SetParameter = NULL;
+NP_StartCursor_t NP_StartCursor = NULL;
+NP_StopCursor_t NP_StopCursor = NULL;
+NP_ReCenter_t NP_ReCenter = NULL;
+NP_StartDataTransmission_t NP_StartDataTransmission = NULL;
+NP_StopDataTransmission_t NP_StopDataTransmission = NULL;
+
+bool crypted = false;
+
+
+
+unsigned char table[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+char *client_path()
+{
+ HKEY hkey = 0;
+ RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", 0,
+ KEY_QUERY_VALUE, &hkey);
+ if(!hkey){
+ printf("Can't open registry key\n");
+ return NULL;
+ }
+
+ BYTE path[1024];
+ DWORD buf_len = 1024;
+ LONG result = RegQueryValueEx(hkey, "Path", NULL, NULL, path, &buf_len);
+ char *full_path = NULL;
+ int res = -1;
+ if(result == ERROR_SUCCESS && buf_len > 0){
+#ifdef FOR_WIN64
+ res = asprintf(&full_path, "%s/NPClient64.dll", path);
+#else
+ res = asprintf(&full_path, "%s/NPClient.dll", path);
+#endif
+ }
+ RegCloseKey(hkey);
+ if(res > 0){
+ return full_path;
+ }else{
+ return NULL;
+ }
+}
+
+bool initialized = false;
+
+bool npifc_init(HWND wnd, int id)
+{
+ //table[] = {0xb3, 0x16, 0x36, 0xeb, 0xb9, 0x05, 0x4f, 0xa4};
+ game_desc_t gd;
+ if(game_data_get_desc(id, &gd)){
+ crypted = gd.encrypted;
+ if(gd.encrypted){
+ table[0] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[1] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[2] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[3] = (unsigned char)(gd.key1&0xff); gd.key1 >>= 8;
+ table[4] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[5] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[6] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ table[7] = (unsigned char)(gd.key2&0xff); gd.key2 >>= 8;
+ }
+ }
+ printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ table[0], table[1], table[2], table[3],
+ table[4], table[5], table[6], table[7]);
+
+ char *client = client_path();
+ if(client == NULL){
+ printf("Couldn't obtain client path!\n");
+ return false;
+ }
+ npclient = LoadLibrary(client);
+ if(!npclient){
+ printf("Can't load client %s\n", client);
+ return false;
+ }
+
+ NP_RegisterWindowHandle = (NP_RegisterWindowHandle_t)GetProcAddress(npclient, "NP_RegisterWindowHandle");
+ NP_UnregisterWindowHandle = (NP_UnregisterWindowHandle_t)GetProcAddress(npclient, "NP_UnregisterWindowHandle");
+ NP_RegisterProgramProfileID = (NP_RegisterProgramProfileID_t)GetProcAddress(npclient, "NP_RegisterProgramProfileID");
+ NP_QueryVersion = (NP_QueryVersion_t)GetProcAddress(npclient, "NP_QueryVersion");
+ NP_RequestData = (NP_RequestData_t)GetProcAddress(npclient, "NP_RequestData");
+ NP_GetSignature = (NP_GetSignature_t)GetProcAddress(npclient, "NP_GetSignature");
+ NP_GetData = (NP_GetData_t)GetProcAddress(npclient, "NP_GetData");
+ NP_GetParameter = (NP_GetParameter_t)GetProcAddress(npclient, "NP_GetParameter");
+ NP_SetParameter = (NP_SetParameter_t)GetProcAddress(npclient, "NP_SetParameter");
+ NP_StartCursor = (NP_StartCursor_t)GetProcAddress(npclient, "NP_StartCursor");
+ NP_StopCursor = (NP_StopCursor_t)GetProcAddress(npclient, "NP_StopCursor");
+ NP_ReCenter = (NP_ReCenter_t)GetProcAddress(npclient, "NP_ReCenter");
+ NP_StartDataTransmission = (NP_StartDataTransmission_t)GetProcAddress(npclient, "NP_StartDataTransmission");
+ NP_StopDataTransmission = (NP_StopDataTransmission_t)GetProcAddress(npclient, "NP_StopDataTransmission");
+ if((NP_RegisterWindowHandle == NULL) || (NP_UnregisterWindowHandle == NULL)
+ || (NP_RegisterProgramProfileID == NULL) || (NP_QueryVersion == NULL) || (NP_RequestData == NULL)
+ || (NP_GetSignature == NULL) || (NP_GetData == NULL) || (NP_GetParameter == NULL)
+ || (NP_SetParameter == NULL) || (NP_StartCursor == NULL) || (NP_StopCursor == NULL)
+ || (NP_ReCenter == NULL) || (NP_StartDataTransmission == NULL) || (NP_StopDataTransmission == NULL)){
+ printf("Couldn't bind all necessary functions!\n");
+ return false;
+ }
+ tir_signature_t sig;
+ int res;
+ if((res = NP_GetSignature(&sig)) != 0){
+ printf("Error retrieving signature! %d\n", res);
+ return false;
+ }
+ printf("Dll Sig:%s\nApp Sig2:%s\n", sig.DllSignature, sig.AppSignature);
+ NP_RegisterWindowHandle(wnd);
+ if(NP_RegisterProgramProfileID(id) != 0){
+ printf("Couldn't register profile id!\n");
+ return false;
+ }
+ printf("Program profile registered!\n");
+ NP_RequestData(65535);
+ NP_StopCursor();
+ NP_StartDataTransmission();
+ initialized = true;
+ return true;
+}
+
+void npifc_close()
+{
+ if(initialized){
+ NP_StopDataTransmission();
+ NP_StartCursor();
+ NP_UnregisterWindowHandle();
+ }
+ initialized = false;
+}
+
+void c_encrypt(unsigned char buf[], unsigned int size,
+ unsigned char code_table[], unsigned int table_size)
+{
+ unsigned int table_ptr = 0;
+ unsigned char var = 0x88;
+ unsigned char tmp;
+ if((size <= 0) || (table_size <= 0) ||
+ (buf == NULL) || (code_table == NULL))
+ return;
+ do{
+ tmp = buf[--size];
+ buf[size] = tmp ^ code_table[table_ptr] ^ var;
+ var += size + tmp;
+ ++table_ptr;
+ if(table_ptr >= table_size){
+ table_ptr -= table_size;
+ }
+ }while(size != 0);
+}
+
+
+
+void decrypt(unsigned char buf[], unsigned int size,
+ unsigned char code_table[], unsigned int table_size)
+{
+ unsigned int table_ptr = 0;
+ unsigned char var = 0x88;
+ unsigned char tmp;
+ if((size <= 0) || (table_size <= 0) ||
+ (buf == NULL) || (code_table == NULL)){
+ return;
+ }
+ do{
+ tmp = buf[--size];
+ buf[size] = tmp ^ code_table[table_ptr] ^ var;
+ var += size + buf[size];
+ ++table_ptr;
+ if(table_ptr >= table_size){
+ table_ptr -= table_size;
+ }
+ }while(size != 0);
+}
+
+unsigned int cksum(unsigned char buf[], unsigned int size)
+{
+ if((size == 0) || (buf == NULL)){
+ return 0;
+ }
+ int rounds = size >> 2;
+ int rem = size % 4;
+
+ int c = size;
+ int a0 = 0;
+ int a2 = 0;
+
+ while(rounds != 0){
+ a0 = *(short int*)buf;
+ a2 = *(short int*)(buf+2);
+ buf += 4;
+ c += a0;
+ a2 ^= (c << 5);
+ a2 <<= 11;
+ c ^= a2;
+ c += (c >> 11);
+ --rounds;
+ }
+ switch(rem){
+ case 3:
+ a0 = *(short int*)buf;
+ a2 = *(signed char*)(buf+2);
+ c += a0;
+ a2 = (a2 << 2) ^ c;
+ c ^= (a2 << 16);
+ a2 = (c >> 11);
+ break;
+ case 2:
+ a2 = *(short int*)buf;
+ c += a2;
+ c ^= (c << 11);
+ a2 = (c >> 17);
+ break;
+ case 1:
+ a2 = *(signed char*)(buf);
+ c += a2;
+ c ^= (c << 10);
+ a2 = (c >> 1);
+ break;
+ default:
+ break;
+ }
+ if(rem != 0){
+ c+=a2;
+ }
+
+ c ^= (c << 3);
+ c += (c >> 5);
+ c ^= (c << 4);
+ c += (c >> 17);
+ c ^= (c << 25);
+ c += (c >> 6);
+
+ return (unsigned int)c;
+}
+
+int decode_frame(tir_data_t *td)
+{
+ //printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ // table[0], table[1], table[2], table[3],
+ // table[4], table[5], table[6], table[7]);
+ unsigned int csum;
+ decrypt((unsigned char*)td, sizeof(*td), table, sizeof(table));
+ csum = td->cksum;
+ td->cksum = 0;
+ if(csum != cksum((unsigned char*)td, sizeof(*td))){
+ printf("Problem with frame!\n");
+ //int a0;
+ //printf("Dec: ");
+ //for(a0 = 0; a0 < (int)sizeof(tir_data_t); ++a0)
+ //{
+ // printf("%02X", ((unsigned char *)td)[a0]);
+ //}
+ //printf("\n");
+ //printf("Cksum: %04X vs computed: %04X\n", csum, cksum((unsigned char*)td, sizeof(*td)));
+ return -1;
+ }
+ //printf("Frame OK!\n");
+ return 0;
+}
+
+int npifc_getdata(tir_data_t *data)
+{
+ int res = NP_GetData(data);
+ if(crypted){
+ decode_frame(data);
+ }
+ return res;
+}
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/npifc.h b/facetracknoir/clientfiles/very-important-source-code/tester/npifc.h
new file mode 100644
index 00000000..d580e16d
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/npifc.h
@@ -0,0 +1,66 @@
+#ifndef NPIFC__H
+#define NPIFC__H
+
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ bool npifc_init(HWND wnd, int id);
+ void npifc_close();
+
+#pragma pack(1)
+typedef struct tir_data{
+ short status;
+ short frame;
+ unsigned int cksum;
+ float roll, pitch, yaw;
+ float tx, ty, tz;
+ float padding[9];
+} tir_data_t;
+
+typedef struct tir_signature{
+ char DllSignature[200];
+ char AppSignature[200];
+} tir_signature_t;
+#pragma pack(0)
+
+int npifc_getdata(tir_data_t *data);
+
+typedef int __stdcall (*NP_RegisterWindowHandle_t)(HWND hwnd);
+typedef int __stdcall (*NP_UnregisterWindowHandle_t)(void);
+typedef int __stdcall (*NP_RegisterProgramProfileID_t)(unsigned short id);
+typedef int __stdcall (*NP_QueryVersion_t)(unsigned short *version);
+typedef int __stdcall (*NP_RequestData_t)(unsigned short req);
+typedef int __stdcall (*NP_GetSignature_t)(tir_signature_t *sig);
+typedef int __stdcall (*NP_GetData_t)(tir_data_t *data);
+typedef int __stdcall (*NP_GetParameter_t)(void);
+typedef int __stdcall (*NP_SetParameter_t)(void);
+typedef int __stdcall (*NP_StartCursor_t)(void);
+typedef int __stdcall (*NP_StopCursor_t)(void);
+typedef int __stdcall (*NP_ReCenter_t)(void);
+typedef int __stdcall (*NP_StartDataTransmission_t)(void);
+typedef int __stdcall (*NP_StopDataTransmission_t)(void);
+
+extern NP_RegisterWindowHandle_t NP_RegisterWindowHandle;
+extern NP_UnregisterWindowHandle_t NP_UnregisterWindowHandle;
+extern NP_RegisterProgramProfileID_t NP_RegisterProgramProfileID;
+extern NP_QueryVersion_t NP_QueryVersion;
+extern NP_RequestData_t NP_RequestData;
+extern NP_GetSignature_t NP_GetSignature;
+extern NP_GetData_t NP_GetData;
+extern NP_GetParameter_t NP_GetParameter;
+extern NP_SetParameter_t NP_SetParameter;
+extern NP_StartCursor_t NP_StartCursor;
+extern NP_StopCursor_t NP_StopCursor;
+extern NP_ReCenter_t NP_ReCenter;
+extern NP_StartDataTransmission_t NP_StartDataTransmission;
+extern NP_StopDataTransmission_t NP_StopDataTransmission;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/npview.rc.in b/facetracknoir/clientfiles/very-important-source-code/tester/npview.rc.in
new file mode 100644
index 00000000..231002f1
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/npview.rc.in
@@ -0,0 +1,49 @@
+// Generated by ResEdit 1.5.9
+// Copyright (C) 2006-2011
+// http://www.resedit.net
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+#include "resource.h"
+
+#ifdef HAVE_CONFIG_H
+ #include "../../../config.h"
+#endif
+
+
+
+//
+// Dialog resources
+//
+//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+IDD_DIALOG1 DIALOGEX 0, 0, 379, 124
+STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
+CAPTION "NPTest v@PACKAGE_VERSION@"
+FONT 8, "Ms Shell Dlg", 400, 0, 1
+{
+ DEFPUSHBUTTON "Quit", IDQUIT, 262, 102, 50, 14
+ DEFPUSHBUTTON "Start", IDSTART, 7, 102, 50, 14
+ EDITTEXT IDC_PITCH, 32, 32, 51, 14, ES_AUTOHSCROLL
+ LTEXT "Pitch", IDC_STATIC, 11, 34, 20, 8, SS_LEFT
+ LTEXT "Yaw", IDC_STATIC, 11, 59, 20, 8, SS_LEFT
+ EDITTEXT IDC_YAW, 32, 57, 51, 14, ES_AUTOHSCROLL
+ LTEXT "Roll", IDC_STATIC, 11, 84, 20, 8, SS_LEFT
+ EDITTEXT IDC_ROLL, 32, 82, 51, 14, ES_AUTOHSCROLL
+ LTEXT "X", IDC_STATIC, 101, 35, 6, 8, SS_LEFT
+ EDITTEXT IDC_X1, 112, 32, 51, 14, ES_AUTOHSCROLL
+ LTEXT "Y", IDC_STATIC, 101, 60, 6, 8, SS_LEFT
+ EDITTEXT IDC_Y1, 112, 57, 51, 14, ES_AUTOHSCROLL
+ LTEXT "Z", IDC_STATIC, 101, 85, 6, 8, SS_LEFT
+ EDITTEXT IDC_Z1, 112, 82, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_X2, 172, 32, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_Y2, 172, 57, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_Z2, 172, 82, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_X3, 232, 32, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_Y3, 232, 57, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_Z3, 232, 82, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_S, 292, 32, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_F, 292, 57, 51, 14, ES_AUTOHSCROLL
+ EDITTEXT IDC_APPID, 32, 12, 51, 12, ES_AUTOHSCROLL
+ LTEXT "ID", IDC_STATIC, 17, 14, 8, 8, SS_LEFT
+}
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/resource.h b/facetracknoir/clientfiles/very-important-source-code/tester/resource.h
new file mode 100644
index 00000000..328d9cb7
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/resource.h
@@ -0,0 +1,23 @@
+#ifndef IDC_STATIC
+#define IDC_STATIC (-1)
+#endif
+
+#define IDD_DIALOG1 100
+#define IDQUIT 1002
+#define IDSTART 1003
+#define IDC_APPID 1016
+#define IDC_PITCH 1017
+#define IDC_YAW 1018
+#define IDC_ROLL 1019
+#define IDC_X1 1020
+#define IDC_X2 1021
+#define IDC_X3 1022
+#define IDC_Y1 1023
+#define IDC_Y2 1024
+#define IDC_Y3 1025
+#define IDC_Z1 1026
+#define IDC_Z2 1027
+#define IDC_Z3 1028
+#define IDC_S 1029
+#define IDC_F 1030
+
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/rest.c b/facetracknoir/clientfiles/very-important-source-code/tester/rest.c
new file mode 120000
index 00000000..663c21a9
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/rest.c
@@ -0,0 +1 @@
+../client/rest.c \ No newline at end of file
diff --git a/facetracknoir/clientfiles/very-important-source-code/tester/rest.h b/facetracknoir/clientfiles/very-important-source-code/tester/rest.h
new file mode 120000
index 00000000..6dca182a
--- /dev/null
+++ b/facetracknoir/clientfiles/very-important-source-code/tester/rest.h
@@ -0,0 +1 @@
+../client/rest.h \ No newline at end of file
diff --git a/facetracknoir/curve-config.cpp b/facetracknoir/curve-config.cpp
index 2bff009a..57cea7a4 100644
--- a/facetracknoir/curve-config.cpp
+++ b/facetracknoir/curve-config.cpp
@@ -1,117 +1,94 @@
-#include "facetracknoir/facetracknoir.h"
-#include "facetracknoir/curve-config.h"
-#include <QDebug>
-#include <QCheckBox>
-CurveConfigurationDialog::CurveConfigurationDialog(FaceTrackNoIR *ftnoir, QWidget *parent) :
- QWidget( parent, Qt::Dialog ), mainApp(ftnoir)
+#include "./facetracknoir.h"
+#include "./curve-config.h"
+#include "./main-settings.hpp"
+MapWidget::MapWidget(Mappings& m, main_settings& s, QWidget *parent) :
+ QWidget(parent, Qt::Dialog),
+ m(m)
{
- ui.setupUi( this );
- setFont(qApp->font());
+ ui.setupUi( this );
+
+ // rest of mapping settings taken care of by options::value<t>
+ m.load_mappings();
+
+ {
+ struct {
+ QFunctionConfigurator* qfc;
+ Axis axis;
+ bool altp;
+ } qfcs[] =
+ {
+ { ui.rxconfig, Yaw, false },
+ { ui.ryconfig, Pitch, false},
+ { ui.rzconfig, Roll, false },
+ { ui.txconfig, TX, false },
+ { ui.tyconfig, TY, false },
+ { ui.tzconfig, TZ, false },
+
+ { ui.rxconfig_alt, Yaw, true },
+ { ui.ryconfig_alt, Pitch, true},
+ { ui.rzconfig_alt, Roll, true },
+ { ui.txconfig_alt, TX, true },
+ { ui.tyconfig_alt, TY, true },
+ { ui.tzconfig_alt, TZ, true },
+ { nullptr, Yaw, false }
+ };
+
+ for (int i = 0; qfcs[i].qfc; i++)
+ {
+ const bool altp = qfcs[i].altp;
+ Mapping& axis = m(qfcs[i].axis);
+ Map* conf = altp ? &axis.curveAlt : &axis.curve;
+ const auto& name = qfcs[i].altp ? axis.name2 : axis.name1;
+
+ qfcs[i].qfc->setConfig(conf, name);
+ }
+ }
+ setFont(qApp->font());
QPoint offsetpos(120, 30);
- this->move(parent->pos() + offsetpos);
+ this->move(parent->pos() + offsetpos);
- // Connect Qt signals to member-functions
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- tie_setting(mainApp->s.a_x.altp, ui.tx_altp);
- tie_setting(mainApp->s.a_y.altp, ui.ty_altp);
- tie_setting(mainApp->s.a_z.altp, ui.tz_altp);
- tie_setting(mainApp->s.a_yaw.altp, ui.rx_altp);
- tie_setting(mainApp->s.a_pitch.altp, ui.ry_altp);
- tie_setting(mainApp->s.a_roll.altp, ui.rz_altp);
-
- tie_setting(mainApp->s.tcomp_p, ui.tcomp_enable);
- tie_setting(mainApp->s.tcomp_tz, ui.tcomp_rz);
-
- tie_setting(mainApp->s.a_x.zero, ui.pos_tx);
- tie_setting(mainApp->s.a_y.zero, ui.pos_ty);
- tie_setting(mainApp->s.a_z.zero, ui.pos_tz);
- tie_setting(mainApp->s.a_yaw.zero, ui.pos_rx);
- tie_setting(mainApp->s.a_pitch.zero, ui.pos_ry);
- tie_setting(mainApp->s.a_roll.zero, ui.pos_rz);
-
- tie_setting(mainApp->s.a_yaw.invert, ui.chkInvertYaw);
- tie_setting(mainApp->s.a_pitch.invert, ui.chkInvertPitch);
- tie_setting(mainApp->s.a_roll.invert, ui.chkInvertRoll);
- tie_setting(mainApp->s.a_x.invert, ui.chkInvertX);
- tie_setting(mainApp->s.a_y.invert, ui.chkInvertY);
- tie_setting(mainApp->s.a_z.invert, ui.chkInvertZ);
-
- // Load the settings from the current .INI-file
- loadSettings();
-}
-
-void CurveConfigurationDialog::doOK() {
- save();
- this->close();
+ tie_setting(s.a_x.altp, ui.tx_altp);
+ tie_setting(s.a_y.altp, ui.ty_altp);
+ tie_setting(s.a_z.altp, ui.tz_altp);
+ tie_setting(s.a_yaw.altp, ui.rx_altp);
+ tie_setting(s.a_pitch.altp, ui.ry_altp);
+ tie_setting(s.a_roll.altp, ui.rz_altp);
+
+ tie_setting(s.tcomp_p, ui.tcomp_enable);
+ tie_setting(s.tcomp_tz, ui.tcomp_rz);
+
+ tie_setting(s.a_x.zero, ui.pos_tx);
+ tie_setting(s.a_y.zero, ui.pos_ty);
+ tie_setting(s.a_z.zero, ui.pos_tz);
+ tie_setting(s.a_yaw.zero, ui.pos_rx);
+ tie_setting(s.a_pitch.zero, ui.pos_ry);
+ tie_setting(s.a_roll.zero, ui.pos_rz);
+
+ tie_setting(s.a_yaw.invert, ui.invert_yaw);
+ tie_setting(s.a_pitch.invert, ui.invert_pitch);
+ tie_setting(s.a_roll.invert, ui.invert_roll);
+ tie_setting(s.a_x.invert, ui.invert_x);
+ tie_setting(s.a_y.invert, ui.invert_y);
+ tie_setting(s.a_z.invert, ui.invert_z);
+
+ tie_setting(s.a_yaw.src, ui.src_yaw);
+ tie_setting(s.a_pitch.src, ui.src_pitch);
+ tie_setting(s.a_roll.src, ui.src_roll);
+ tie_setting(s.a_x.src, ui.src_x);
+ tie_setting(s.a_y.src, ui.src_y);
+ tie_setting(s.a_z.src, ui.src_z);
}
-void CurveConfigurationDialog::doCancel() {
- mainApp->b->revert();
- loadSettings();
- close();
+void MapWidget::doOK() {
+ m.save_mappings();
+ this->close();
}
-//
-// Load the current Settings from the currently 'active' INI-file.
-//
-void CurveConfigurationDialog::loadSettings() {
- QFunctionConfigurator* configs[6] = {
- ui.txconfig,
- ui.tyconfig,
- ui.tzconfig,
- ui.rxconfig,
- ui.ryconfig,
- ui.rzconfig
- };
-
- QFunctionConfigurator* alt_configs[6] = {
- ui.txconfig_alt,
- ui.tyconfig_alt,
- ui.tzconfig_alt,
- ui.rxconfig_alt,
- ui.ryconfig_alt,
- ui.rzconfig_alt
- };
-
- QSettings settings("opentrack");
- QString currentFile = settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini" )
- .toString();
-
- for (int i = 0; i < 6; i++)
- {
- configs[i]->setConfig(&mainApp->axis(i).curve);
- alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt);
- }
-}
-
-//
-// Save the current Settings to the currently 'active' INI-file.
-//
-void CurveConfigurationDialog::save() {
-
- qDebug() << "save() says: started";
-
- QSettings settings("opentrack");
- QString currentFile =
- settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini" )
- .toString();
-
- ui.rxconfig->saveSettings(currentFile);
- ui.ryconfig->saveSettings(currentFile);
- ui.rzconfig->saveSettings(currentFile);
- ui.txconfig->saveSettings(currentFile);
- ui.tyconfig->saveSettings(currentFile);
- ui.tzconfig->saveSettings(currentFile);
-
- ui.txconfig_alt->saveSettings(currentFile);
- ui.tyconfig_alt->saveSettings(currentFile);
- ui.tzconfig_alt->saveSettings(currentFile);
- ui.rxconfig_alt->saveSettings(currentFile);
- ui.ryconfig_alt->saveSettings(currentFile);
- ui.rzconfig_alt->saveSettings(currentFile);
+void MapWidget::doCancel() {
+ m.invalidate_unsaved();
+ this->close();
}
diff --git a/facetracknoir/curve-config.h b/facetracknoir/curve-config.h
index 0949cdc4..d485c4ff 100644
--- a/facetracknoir/curve-config.h
+++ b/facetracknoir/curve-config.h
@@ -1,21 +1,16 @@
#pragma once
#include <QWidget>
-#include <QPalette>
+#include "./mappings.hpp"
#include "ui_ftnoir_curves.h"
-class FaceTrackNoIR;
-
-class CurveConfigurationDialog: public QWidget
+class MapWidget: public QWidget
{
Q_OBJECT
public:
- CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent );
- void loadSettings();
+ MapWidget(Mappings &m, main_settings &s, QWidget *parent );
private:
Ui::UICCurveConfigurationDialog ui;
- void save();
- FaceTrackNoIR *mainApp;
-
+ Mappings& m;
private slots:
void doOK();
void doCancel();
diff --git a/facetracknoir/export.hpp b/facetracknoir/export.hpp
new file mode 100644
index 00000000..8c8bdc69
--- /dev/null
+++ b/facetracknoir/export.hpp
@@ -0,0 +1,7 @@
+#pragma once
+#ifdef _WIN32
+# define OPENTRACK_LINKAGE __declspec(dllexport)
+#else
+# define OPENTRACK_LINKAGE
+#endif
+#define OPENTRACK_EXPORT __attribute__ ((visibility ("default"))) OPENTRACK_LINKAGE
diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp
index 893e79cd..f689cb5f 100644
--- a/facetracknoir/facetracknoir.cpp
+++ b/facetracknoir/facetracknoir.cpp
@@ -25,13 +25,7 @@
#include "shortcuts.h"
#include "tracker.h"
#include "curve-config.h"
-#include "opentrack-version.h"
-#include <QDebug>
-
-#if defined(_WIN32)
-# include <windows.h>
-# include <dshow.h>
-#endif
+#include <QFileDialog>
#if defined(__APPLE__)
# define SONAME "dylib"
@@ -44,15 +38,11 @@
#include <iostream>
#ifdef _MSC_VER
-# define LIB_PREFIX ""
+# error "No support for MSVC anymore"
#else
# define LIB_PREFIX "lib"
#endif
-#if defined(__unix) || defined(__linux) || defined(__APPLE__)
-# include <unistd.h>
-#endif
-
static bool get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon)
{
Metadata* meta;
@@ -64,7 +54,7 @@ static bool get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon)
return true;
}
-static void fill_combobox(const QString& filter, QList<DynamicLibrary*>& list, QComboBox* cbx, QComboBox* cbx2)
+static void fill_combobox(const QString& filter, QList<DynamicLibrary*>& list, QComboBox& cbx)
{
QDir settingsDir( QCoreApplication::applicationDirPath() );
QStringList filenames = settingsDir.entryList( QStringList() << (LIB_PREFIX + filter + SONAME), QDir::Files, QDir::Name );
@@ -81,14 +71,12 @@ static void fill_combobox(const QString& filter, QList<DynamicLibrary*>& list, Q
continue;
}
list.push_back(lib);
- cbx->addItem(icon, longName);
- if (cbx2)
- cbx2->addItem(icon, longName);
+ cbx.addItem(icon, longName);
}
}
-FaceTrackNoIR::FaceTrackNoIR(QWidget *parent) :
- QMainWindow(parent),
+FaceTrackNoIR::FaceTrackNoIR(QWidget *parent) : QMainWindow(parent),
+ tracker(nullptr),
#if defined(_WIN32)
keybindingWorker(NULL),
#else
@@ -99,30 +87,20 @@ FaceTrackNoIR::FaceTrackNoIR(QWidget *parent) :
s(b),
pose(std::vector<axis_opts*>{&s.a_x, &s.a_y, &s.a_z, &s.a_yaw, &s.a_pitch, &s.a_roll}),
timUpdateHeadPose(this),
- pTrackerDialog(NULL),
- pSecondTrackerDialog(NULL),
- pProtocolDialog(NULL),
- pFilterDialog(NULL),
+ pTrackerDialog(nullptr),
+ pProtocolDialog(nullptr),
+ pFilterDialog(nullptr),
+ shortcuts_widget(nullptr),
+ mapping_widget(nullptr),
kbd_quit(QKeySequence("Ctrl+Q"), this),
- looping(false)
-{
+ looping(0),
+ video_frame_layout(new QVBoxLayout()),
+ no_feed_pixmap(":/uielements/no-feed.png")
+{
ui.setupUi(this);
setFixedSize(size());
-
- _keyboard_shortcuts = 0;
- _curve_config = 0;
-
- tracker = 0;
-
- CurveConfigurationDialog* ccd;
-
- if (!_curve_config)
- {
- ccd = new CurveConfigurationDialog( this, this );
- _curve_config = ccd;
- } else {
- ccd = dynamic_cast<CurveConfigurationDialog*>(_curve_config);
- }
+ ui.video_frame_label->setPixmap(no_feed_pixmap);
+ updateButtonState(false, false);
QDir::setCurrent(QCoreApplication::applicationDirPath());
@@ -135,28 +113,23 @@ FaceTrackNoIR::FaceTrackNoIR(QWidget *parent) :
connect(ui.btnEditCurves, SIGNAL(clicked()), this, SLOT(showCurveConfiguration()));
connect(ui.btnShortcuts, SIGNAL(clicked()), this, SLOT(showKeyboardShortcuts()));
connect(ui.btnShowEngineControls, SIGNAL(clicked()), this, SLOT(showTrackerSettings()));
- connect(ui.btnShowSecondTrackerSettings, SIGNAL(clicked()), this, SLOT(showSecondTrackerSettings()));
connect(ui.btnShowServerControls, SIGNAL(clicked()), this, SLOT(showServerControls()));
connect(ui.btnShowFilterControls, SIGNAL(clicked()), this, SLOT(showFilterControls()));
- ui.cbxSecondTrackerSource->addItem(QIcon(), "");
dlopen_filters.push_back((DynamicLibrary*) NULL);
ui.iconcomboFilter->addItem(QIcon(), "");
- fill_combobox("opentrack-proto-*.", dlopen_protocols, ui.iconcomboProtocol, NULL);
- fill_combobox("opentrack-tracker-*.", dlopen_trackers, ui.iconcomboTrackerSource, ui.cbxSecondTrackerSource);
- fill_combobox("opentrack-filter-*.", dlopen_filters, ui.iconcomboFilter, NULL);
+ fill_combobox("opentrack-proto-*.", dlopen_protocols, *ui.iconcomboProtocol);
+ fill_combobox("opentrack-tracker-*.", dlopen_trackers, *ui.iconcomboTrackerSource);
+ fill_combobox("opentrack-filter-*.", dlopen_filters, *ui.iconcomboFilter);
tie_setting(s.tracker_dll, ui.iconcomboTrackerSource);
- tie_setting(s.tracker2_dll, ui.cbxSecondTrackerSource);
tie_setting(s.protocol_dll, ui.iconcomboProtocol);
tie_setting(s.filter_dll, ui.iconcomboFilter);
connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(startTracker()));
connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stopTracker()));
- GetCameraNameDX();
-
connect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int)));
connect(&timUpdateHeadPose, SIGNAL(timeout()), this, SLOT(showHeadPose()));
@@ -171,109 +144,53 @@ FaceTrackNoIR::FaceTrackNoIR(QWidget *parent) :
FaceTrackNoIR::~FaceTrackNoIR() {
- stopTracker();
+ stopTracker();
save();
if (Libraries)
delete Libraries;
+ delete video_frame_layout;
}
QFrame* FaceTrackNoIR::get_video_widget() {
return ui.video_frame;
}
-void FaceTrackNoIR::GetCameraNameDX() {
-#if defined(_WIN32)
- ui.cameraName->setText("No video-capturing device was found in your system: check if it's connected!");
-
- // Create the System Device Enumerator.
- HRESULT hr;
- ICreateDevEnum *pSysDevEnum = NULL;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
- if (FAILED(hr))
- {
- qDebug() << "GetWDM says: CoCreateInstance Failed!";
- return;
- }
-
- qDebug() << "GetWDM says: CoCreateInstance succeeded!";
-
- // Obtain a class enumerator for the video compressor category.
- IEnumMoniker *pEnumCat = NULL;
- hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
-
- if (hr == S_OK) {
- qDebug() << "GetWDM says: CreateClassEnumerator succeeded!";
-
- IMoniker *pMoniker = NULL;
- ULONG cFetched;
- if (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr))
- {
- QString str((QChar*)varName.bstrVal, wcslen(varName.bstrVal));
- qDebug() << "GetWDM says: Moniker found:" << str;
- ui.cameraName->setText(str);
- }
- VariantClear(&varName);
-
- pPropBag->Release();
- }
- pMoniker->Release();
- }
- pEnumCat->Release();
- }
- pSysDevEnum->Release();
-#else
- for (int i = 0; i < 16; i++) {
- char buf[128];
- sprintf(buf, "/dev/video%d", i);
- if (access(buf, R_OK | W_OK) == 0) {
- ui.cameraName->setText(QString(buf));
- break;
- }
- }
-#endif
-}
-
void FaceTrackNoIR::open() {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
-
- QString fileName = dialog.getOpenFileName(
- this,
+
+ QString fileName = dialog.getOpenFileName(
+ this,
tr("Open the settings file"),
- QCoreApplication::applicationDirPath() + "/settings/",
+ QCoreApplication::applicationDirPath() + "/settings/",
tr("Settings file (*.ini);;All Files (*)"),
NULL);
- if (! fileName.isEmpty() ) {
+ if (! fileName.isEmpty() ) {
{
QSettings settings("opentrack");
settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath());
}
- looping = true;
fill_profile_cbx();
- loadSettings();
- looping = false;
+ loadSettings();
}
}
-void FaceTrackNoIR::save() {
- b->save();
+void FaceTrackNoIR::save_mappings() {
+ pose.save_mappings();
+}
- QSettings settings("opentrack");
+#if defined(__unix) || defined(__linux) || defined(__APPLE__)
+# include <unistd.h>
+#endif
- QString currentFile =
- settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini")
- .toString();
+void FaceTrackNoIR::save() {
+ b->save();
+ save_mappings();
#if defined(__unix) || defined(__linux)
+ QSettings settings("opentrack");
+ const QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
QByteArray bytes = QFile::encodeName(currentFile);
const char* filename_as_asciiz = bytes.constData();
@@ -286,56 +203,56 @@ void FaceTrackNoIR::save() {
void FaceTrackNoIR::saveAs()
{
- looping = true;
- QSettings settings("opentrack");
- QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
+ looping++;
+ QSettings settings("opentrack");
+ QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"),
- oldFile,
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"),
+ oldFile,
tr("Settings file (*.ini);;All Files (*)"));
- if (!fileName.isEmpty()) {
+ if (!fileName.isEmpty()) {
- QFileInfo newFileInfo ( fileName );
- if ((newFileInfo.exists()) && (oldFile != fileName)) {
- QFile newFileFile ( fileName );
- newFileFile.remove();
- }
+ QFileInfo newFileInfo ( fileName );
+ if ((newFileInfo.exists()) && (oldFile != fileName)) {
+ QFile newFileFile ( fileName );
+ newFileFile.remove();
+ }
- QFileInfo oldFileInfo ( oldFile );
- if (oldFileInfo.exists()) {
- QFile oldFileFile ( oldFile );
- oldFileFile.copy( fileName );
- }
+ QFileInfo oldFileInfo ( oldFile );
+ if (oldFileInfo.exists()) {
+ QFile oldFileFile ( oldFile );
+ oldFileFile.copy( fileName );
+ }
- settings.setValue ("SettingsFile", fileName);
+ settings.setValue ("SettingsFile", fileName);
save();
}
- looping = false;
+ looping--;
fill_profile_cbx();
}
+void FaceTrackNoIR::load_mappings() {
+ pose.load_mappings();
+}
+
void FaceTrackNoIR::loadSettings() {
b->reload();
- (dynamic_cast<CurveConfigurationDialog*>(_curve_config))->loadSettings();
+ load_mappings();
}
-void FaceTrackNoIR::updateButtonState(bool running)
+void FaceTrackNoIR::updateButtonState(bool running, bool inertialp)
{
- bool e = !running;
- ui.iconcomboProfile->setEnabled ( e );
- ui.btnLoad->setEnabled ( e );
- ui.btnSaveAs->setEnabled ( e );
- ui.btnStartTracker->setEnabled ( e );
+ bool not_running = !running;
+ ui.iconcomboProfile->setEnabled ( not_running );
+ ui.btnStartTracker->setEnabled ( not_running );
ui.btnStopTracker->setEnabled ( running );
- ui.iconcomboProtocol->setEnabled ( e );
- ui.btnShowServerControls->setEnabled ( e );
- ui.iconcomboFilter->setEnabled ( e );
- ui.iconcomboTrackerSource->setEnabled(e);
- ui.cbxSecondTrackerSource->setEnabled(e);
-
- ui.btnStartTracker->setEnabled(e);
+ ui.iconcomboProtocol->setEnabled ( not_running );
+ ui.iconcomboFilter->setEnabled ( not_running );
+ ui.iconcomboTrackerSource->setEnabled(not_running);
+ ui.btnStartTracker->setEnabled(not_running);
ui.btnStopTracker->setEnabled(running);
+ ui.video_frame_label->setVisible(not_running || inertialp);
}
void FaceTrackNoIR::startTracker( ) {
@@ -353,7 +270,7 @@ void FaceTrackNoIR::startTracker( ) {
stopTracker();
return;
}
-
+
#if defined(_WIN32)
keybindingWorker = new KeybindingWorker(*this, keyCenter, keyToggle);
keybindingWorker->start();
@@ -363,34 +280,25 @@ void FaceTrackNoIR::startTracker( ) {
delete tracker;
}
- {
- QSettings settings("opentrack");
- QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings iniFile( currentFile, QSettings::IniFormat );
-
- for (int i = 0; i < 6; i++)
- {
- axis(i).curve.loadSettings(iniFile);
- axis(i).curveAlt.loadSettings(iniFile);
- }
- }
-
- tracker = new Tracker ( this, s );
+ tracker = new Tracker(s, pose);
if (pTrackerDialog && Libraries->pTracker) {
pTrackerDialog->registerTracker( Libraries->pTracker );
- }
-
+ }
+
if (pFilterDialog && Libraries->pFilter)
pFilterDialog->registerFilter(Libraries->pFilter);
-
+
tracker->start();
ui.video_frame->show();
timUpdateHeadPose.start(50);
- updateButtonState(true);
+ // NB check valid since SelectedLibraries ctor called
+ // trackers take care of layout state updates
+ const bool is_inertial = ui.video_frame->layout() == nullptr;
+ updateButtonState(true, is_inertial);
}
void FaceTrackNoIR::stopTracker( ) {
@@ -404,7 +312,7 @@ void FaceTrackNoIR::stopTracker( ) {
keybindingWorker = NULL;
}
#endif
- timUpdateHeadPose.stop();
+ timUpdateHeadPose.stop();
ui.pose_display->rotateBy(0, 0, 0);
if (pTrackerDialog) {
@@ -423,52 +331,43 @@ void FaceTrackNoIR::stopTracker( ) {
delete pFilterDialog;
pFilterDialog = nullptr;
}
- if (pSecondTrackerDialog)
- {
- pSecondTrackerDialog->unRegisterTracker();
- delete pSecondTrackerDialog;
- pSecondTrackerDialog = nullptr;
- }
if ( tracker ) {
- delete tracker;
- tracker = 0;
+ delete tracker;
+ tracker = 0;
if (Libraries) {
delete Libraries;
Libraries = NULL;
}
- }
- updateButtonState(false);
+ }
+ updateButtonState(false, false);
}
-void FaceTrackNoIR::showHeadPose() {
- double newdata[6];
-
- tracker->getHeadPose(newdata);
- ui.lcdNumX->display(newdata[TX]);
- ui.lcdNumY->display(newdata[TY]);
- ui.lcdNumZ->display(newdata[TZ]);
-
+void FaceTrackNoIR::showHeadPose()
+{
+ double mapped[6], raw[6];
- ui.lcdNumRotX->display(newdata[Yaw]);
- ui.lcdNumRotY->display(newdata[Pitch]);
- ui.lcdNumRotZ->display(newdata[Roll]);
+ tracker->get_raw_and_mapped_poses(mapped, raw);
- tracker->getOutputHeadPose(newdata);
+ ui.pose_display->rotateBy(mapped[Yaw], mapped[Roll], mapped[Pitch]);
- ui.pose_display->rotateBy(newdata[Yaw], newdata[Roll], newdata[Pitch]);
+ if (mapping_widget)
+ mapping_widget->update();
- ui.lcdNumOutputPosX->display(newdata[TX]);
- ui.lcdNumOutputPosY->display(newdata[TY]);
- ui.lcdNumOutputPosZ->display(newdata[TZ]);
+ ui.lcdNumX->display(raw[TX]);
+ ui.lcdNumY->display(raw[TY]);
+ ui.lcdNumZ->display(raw[TZ]);
+ ui.lcdNumRotX->display(raw[Yaw]);
+ ui.lcdNumRotY->display(raw[Pitch]);
+ ui.lcdNumRotZ->display(raw[Roll]);
- ui.lcdNumOutputRotX->display(newdata[Yaw]);
- ui.lcdNumOutputRotY->display(newdata[Pitch]);
- ui.lcdNumOutputRotZ->display(newdata[Roll]);
+ ui.lcdNumOutputPosX->display(mapped[TX]);
+ ui.lcdNumOutputPosY->display(mapped[TY]);
+ ui.lcdNumOutputPosZ->display(mapped[TZ]);
+ ui.lcdNumOutputRotX->display(mapped[Yaw]);
+ ui.lcdNumOutputRotY->display(mapped[Pitch]);
+ ui.lcdNumOutputRotZ->display(mapped[Roll]);
- if (_curve_config) {
- _curve_config->update();
- }
if (Libraries->pProtocol)
{
const QString name = Libraries->pProtocol->getGameName();
@@ -476,11 +375,12 @@ void FaceTrackNoIR::showHeadPose() {
}
}
-void FaceTrackNoIR::showTrackerSettings() {
- if (pTrackerDialog) {
- delete pTrackerDialog;
- pTrackerDialog = NULL;
- }
+void FaceTrackNoIR::showTrackerSettings()
+{
+ if (pTrackerDialog) {
+ delete pTrackerDialog;
+ pTrackerDialog = NULL;
+ }
DynamicLibrary* lib = dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL);
@@ -496,26 +396,6 @@ void FaceTrackNoIR::showTrackerSettings() {
}
}
-void FaceTrackNoIR::showSecondTrackerSettings() {
- if (pSecondTrackerDialog) {
- delete pSecondTrackerDialog;
- pSecondTrackerDialog = NULL;
- }
-
- DynamicLibrary* lib = dlopen_trackers.value(ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL);
-
- if (lib) {
- pSecondTrackerDialog = (ITrackerDialog*) lib->Dialog();
- if (pSecondTrackerDialog) {
- auto foo = dynamic_cast<QWidget*>(pSecondTrackerDialog);
- foo->setFixedSize(foo->size());
- if (Libraries && Libraries->pSecondTracker)
- pSecondTrackerDialog->registerTracker(Libraries->pSecondTracker);
- dynamic_cast<QWidget*>(pSecondTrackerDialog)->show();
- }
- }
-}
-
void FaceTrackNoIR::showServerControls() {
if (pProtocolDialog) {
delete pProtocolDialog;
@@ -555,60 +435,58 @@ void FaceTrackNoIR::showFilterControls() {
}
void FaceTrackNoIR::showKeyboardShortcuts() {
- if (!_keyboard_shortcuts)
+ if (!shortcuts_widget)
{
- _keyboard_shortcuts = new KeyboardShortcutDialog( this, this );
+ shortcuts_widget = new KeyboardShortcutDialog( this, this );
}
- _keyboard_shortcuts->show();
- _keyboard_shortcuts->raise();
+ shortcuts_widget->show();
+ shortcuts_widget->raise();
}
void FaceTrackNoIR::showCurveConfiguration() {
+ if (mapping_widget)
+ delete mapping_widget;
+
+ mapping_widget = new MapWidget(pose, s, this);
- if (!_curve_config)
- {
- _curve_config = new CurveConfigurationDialog( this, this );
- }
-
- if (_curve_config) {
- _curve_config->show();
- _curve_config->raise();
- }
+ mapping_widget->show();
+ mapping_widget->raise();
}
void FaceTrackNoIR::exit() {
- QCoreApplication::exit(0);
+ QCoreApplication::exit(0);
}
+extern "C" volatile const char* opentrack_version;
+
void FaceTrackNoIR::fill_profile_cbx()
{
if (looping)
return;
+ looping++;
QSettings settings("opentrack");
QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
qDebug() << "Config file now" << currentFile;
QFileInfo pathInfo ( currentFile );
- setWindowTitle(QString( OPENTRACK_VERSION " :: ") + pathInfo.fileName());
+ setWindowTitle(QString( const_cast<const char*>(opentrack_version) + QStringLiteral(" :: ")) + pathInfo.fileName());
QDir settingsDir( pathInfo.dir() );
QStringList filters;
filters << "*.ini";
auto iniFileList = settingsDir.entryList( filters, QDir::Files, QDir::Name );
ui.iconcomboProfile->clear();
- for ( int i = 0; i < iniFileList.size(); i++) {
+ for ( int i = 0; i < iniFileList.size(); i++)
ui.iconcomboProfile->addItem(QIcon(":/images/settings16.png"), iniFileList.at(i));
- if (iniFileList.at(i) == pathInfo.fileName()) {
- ui.iconcomboProfile->setCurrentIndex( i );
- }
- }
+ ui.iconcomboProfile->setCurrentText(pathInfo.fileName());
+ looping--;
}
void FaceTrackNoIR::profileSelected(int index)
{
- QSettings settings("opentrack");
- QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
+ QSettings settings("opentrack");
+ QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
QFileInfo pathInfo ( currentFile );
settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + ui.iconcomboProfile->itemText(index));
- loadSettings();
+ loadSettings();
}
#if !defined(_WIN32)
@@ -631,8 +509,8 @@ void FaceTrackNoIR::bind_keyboard_shortcut(QxtGlobalShortcut& key, key_opts& k)
key.setShortcut(QKeySequence::fromString(seq, QKeySequence::PortableText));
key.setEnabled();
} else {
- key.setDisabled();
- }
+ key.setDisabled();
+ }
}
}
#else
@@ -679,20 +557,18 @@ void FaceTrackNoIR::bindKeyboardShortcuts()
void FaceTrackNoIR::shortcutRecentered()
{
+ qDebug() << "Center";
if (s.dingp)
QApplication::beep();
-
- qDebug() << "Center";
if (tracker)
- tracker->do_center = true;
+ tracker->center();
}
void FaceTrackNoIR::shortcutToggled()
{
+ qDebug() << "Toggle";
if (s.dingp)
QApplication::beep();
-
- qDebug() << "Toggle";
if (tracker)
- tracker->enabled = !tracker->enabled;
+ tracker->toggle_enabled();
}
diff --git a/facetracknoir/facetracknoir.h b/facetracknoir/facetracknoir.h
index 50a6e0ec..d4c3a369 100644
--- a/facetracknoir/facetracknoir.h
+++ b/facetracknoir/facetracknoir.h
@@ -22,86 +22,66 @@
* with this program; if not, see <http://www.gnu.org/licenses/>. *
*********************************************************************************/
-#ifndef FaceTrackNoIR_H
-#define FaceTrackNoIR_H
+#pragma once
#include <QMainWindow>
#include <QApplication>
-#include <QFileDialog>
-#include <QListView>
-#include <QPainter>
#include <QWidget>
#include <QDialog>
#include <QUrl>
#include <QList>
#include <QKeySequence>
-#include <QtGui>
-#include <QString>
-#include <QByteArray>
#include <QShortcut>
-#include <vector>
+#include <QLayout>
+#include <QPixmap>
+#include <QLabel>
+#include <QTimer>
#if !defined(_WIN32)
# include "qxt-mini/QxtGlobalShortcut"
#else
# include <windows.h>
#endif
-#include <QThread>
-#include <QDebug>
#include "ui_facetracknoir.h"
-#include "facetracknoir/options.h"
-using namespace options;
-
-#include "facetracknoir/main-settings.hpp"
-
-#include "global-settings.h"
-#include "tracker.h"
-#include "facetracknoir/shortcuts.h"
-
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
-
-#include "opentrack-version.h"
-
-class Tracker; // pre-define class to avoid circular includes
-class FaceTrackNoIR;
+#include "./options.h"
+#include "./main-settings.hpp"
+#include "./plugin-support.h"
+#include "./tracker.h"
+#include "./shortcuts.h"
+#include "./curve-config.h"
-class KeybindingWorker;
+using namespace options;
class FaceTrackNoIR : public QMainWindow, IDynamicLibraryProvider
{
- Q_OBJECT
+ Q_OBJECT
public:
FaceTrackNoIR(QWidget *parent = 0);
- ~FaceTrackNoIR();
+ ~FaceTrackNoIR();
- QFrame *get_video_widget(); // Get a pointer to the video-widget, to use in the DLL
+ QFrame *get_video_widget();
Tracker *tracker;
void bindKeyboardShortcuts();
- DynamicLibrary* current_tracker1() {
+
+ // XXX this shit stinks -sh 20141004
+ // TODO move to separate class representing running tracker state
+ DynamicLibrary* current_tracker1() override {
return dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL);
}
- DynamicLibrary* current_tracker2() {
- return dlopen_trackers.value(ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL);
- }
- DynamicLibrary* current_protocol() {
+ DynamicLibrary* current_protocol() override {
return dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL);
}
- DynamicLibrary* current_filter() {
+ DynamicLibrary* current_filter() override {
return dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL);
}
- THeadPoseDOF& axis(int idx) {
- return *pose.axes[idx];
- }
#if defined(_WIN32)
Key keyCenter;
Key keyToggle;
KeybindingWorker* keybindingWorker;
-#else
+#else
QxtGlobalShortcut keyCenter;
QxtGlobalShortcut keyToggle;
#endif
@@ -110,56 +90,55 @@ public:
public slots:
void shortcutRecentered();
void shortcutToggled();
-
private:
- HeadPoseData pose;
+ Mappings pose;
Ui::OpentrackUI ui;
- QTimer timUpdateHeadPose; // Timer to display headpose
-
- ITrackerDialog* pTrackerDialog; // Pointer to Tracker dialog instance (in DLL)
- ITrackerDialog* pSecondTrackerDialog; // Pointer to the second Tracker dialog instance (in DLL)
- IProtocolDialog* pProtocolDialog; // Pointer to Protocol dialog instance (in DLL)
- IFilterDialog* pFilterDialog; // Pointer to Filter dialog instance (in DLL)
+ QTimer timUpdateHeadPose;
- QWidget *_keyboard_shortcuts;
- QWidget *_curve_config;
+ ITrackerDialog* pTrackerDialog;
+ IProtocolDialog* pProtocolDialog;
+ IFilterDialog* pFilterDialog;
- void createIconGroupBox();
+ QWidget *shortcuts_widget;
+ MapWidget* mapping_widget;
- void GetCameraNameDX();
- void loadSettings();
- void updateButtonState(bool);
+ void createIconGroupBox();
+ void loadSettings();
+ void updateButtonState(bool running, bool inertialp);
QList<DynamicLibrary*> dlopen_filters;
QList<DynamicLibrary*> dlopen_trackers;
QList<DynamicLibrary*> dlopen_protocols;
QShortcut kbd_quit;
+ int looping;
+ QLayout* video_frame_layout;
+ QPixmap no_feed_pixmap;
#ifndef _WIN32
void bind_keyboard_shortcut(QxtGlobalShortcut&, key_opts& k);
#endif
void fill_profile_cbx();
- bool looping;
-
+
private slots:
void open();
void save();
void saveAs();
void exit();
void profileSelected(int index);
-
+
void showTrackerSettings();
- void showSecondTrackerSettings();
-
+
void showServerControls();
void showFilterControls();
void showKeyboardShortcuts();
void showCurveConfiguration();
-
+
void showHeadPose();
-
+
void startTracker();
void stopTracker();
-};
-#endif // FaceTrackNoIR_H
+public:
+ void save_mappings();
+ void load_mappings();
+};
diff --git a/facetracknoir/facetracknoir.ui b/facetracknoir/facetracknoir.ui
index b257ae30..ad968030 100644
--- a/facetracknoir/facetracknoir.ui
+++ b/facetracknoir/facetracknoir.ui
@@ -1,1727 +1,1108 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <author>WVR</author>
- <class>OpentrackUI</class>
- <widget class="QMainWindow" name="OpentrackUI">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>790</width>
- <height>500</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="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="contextMenuPolicy">
- <enum>Qt::DefaultContextMenu</enum>
- </property>
- <property name="windowTitle">
- <string>opentrack</string>
- </property>
- <property name="windowIcon">
- <iconset resource="main-facetracknoir.qrc">
- <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset>
- </property>
- <property name="toolTip">
- <string/>
- </property>
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonIconOnly</enum>
- </property>
- <property name="animated">
- <bool>true</bool>
- </property>
- <property name="unifiedTitleAndToolBarOnMac">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="centralWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65535</width>
- <height>65535</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <widget class="QFrame" name="video_frame">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>130</y>
- <width>320</width>
- <height>240</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>250</width>
- <height>187</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <widget class="QWidget" name="widget4video" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>320</width>
- <height>240</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- </widget>
- </widget>
- <widget class="QGroupBox" name="groupBox4logo">
- <property name="geometry">
- <rect>
- <x>100</x>
- <y>10</y>
- <width>229</width>
- <height>121</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="title">
- <string notr="true"/>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_8">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinimumSize</enum>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <property name="horizontalSpacing">
- <number>10</number>
- </property>
- <item row="2" column="0">
- <widget class="QLabel" name="lblZ">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>TZ</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLCDNumber" name="lcdNumOutputRotX">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="lblX">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>TX</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLCDNumber" name="lcdNumOutputPosX">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="lblRotX">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>yaw</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLCDNumber" name="lcdNumOutputPosY">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLCDNumber" name="lcdNumOutputPosZ">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="lblRotZ">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>roll</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="lblY">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>TY</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="lblRotY">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>pitch</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLCDNumber" name="lcdNumOutputRotY">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLCDNumber" name="lcdNumOutputRotZ">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>13</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>5</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="GLWidget" name="pose_display" native="true">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>20</y>
- <width>81</width>
- <height>100</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="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- </widget>
- <widget class="QGroupBox" name="groupGameProtocol">
- <property name="geometry">
- <rect>
- <x>350</x>
- <y>270</y>
- <width>191</width>
- <height>91</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>180</width>
- <height>80</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="title">
- <string>Game protocol</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_6" rowstretch="6,6" columnstretch="6" rowminimumheight="6,6" columnminimumwidth="6">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="0" column="0">
- <widget class="QComboBox" name="iconcomboProtocol">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="currentIndex">
- <number>-1</number>
- </property>
- <property name="maxVisibleItems">
- <number>7</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="btnShowServerControls">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Change game protocol settings</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QPushButton" name="btnEditCurves">
- <property name="geometry">
- <rect>
- <x>580</x>
- <y>390</y>
- <width>171</width>
- <height>38</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>62</width>
- <height>38</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="cursor">
- <cursorShape>PointingHandCursor</cursorShape>
- </property>
- <property name="toolTip">
- <string>Edit the Curve settings</string>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>Mapping</string>
- </property>
- <property name="icon">
- <iconset resource="main-facetracknoir.qrc">
- <normaloff>:/uielements/curves.png</normaloff>:/uielements/curves.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>98</width>
- <height>24</height>
- </size>
- </property>
- </widget>
- <widget class="QLabel" name="game_name">
- <property name="geometry">
- <rect>
- <x>370</x>
- <y>40</y>
- <width>411</width>
- <height>20</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>Not connected</string>
- </property>
- </widget>
- <widget class="QGroupBox" name="groupFilter">
- <property name="geometry">
- <rect>
- <x>580</x>
- <y>210</y>
- <width>171</width>
- <height>91</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="title">
- <string>Filter</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item row="0" column="0">
- <widget class="QComboBox" name="iconcomboFilter">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="currentIndex">
- <number>-1</number>
- </property>
- <property name="maxVisibleItems">
- <number>7</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="btnShowFilterControls">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Change game protocol settings</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QGroupBox" name="groupTrackerSource">
- <property name="geometry">
- <rect>
- <x>350</x>
- <y>60</y>
- <width>191</width>
- <height>91</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="title">
- <string>Main tracker</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QComboBox" name="iconcomboTrackerSource">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="currentIndex">
- <number>-1</number>
- </property>
- <property name="maxVisibleItems">
- <number>42</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnShowEngineControls">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Change tracker settings</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QLabel" name="cameraName">
- <property name="geometry">
- <rect>
- <x>370</x>
- <y>10</y>
- <width>411</width>
- <height>25</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="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="geometry">
- <rect>
- <x>350</x>
- <y>160</y>
- <width>191</width>
- <height>91</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="title">
- <string>Auxiliary tracker</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QComboBox" name="cbxSecondTrackerSource">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="currentIndex">
- <number>-1</number>
- </property>
- <property name="maxVisibleItems">
- <number>42</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnShowSecondTrackerSettings">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Change tracker settings</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QGroupBox" name="groupStartStop">
- <property name="geometry">
- <rect>
- <x>350</x>
- <y>400</y>
- <width>190</width>
- <height>65</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="title">
- <string>GO!</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_9" rowstretch="0" columnstretch="0,0" rowminimumheight="0" columnminimumwidth="0,0">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinimumSize</enum>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="0" column="0">
- <widget class="QPushButton" name="btnStartTracker">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Start the Tracker</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Start</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="btnStopTracker">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Stop the Tracker</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Stop</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QPushButton" name="btnShortcuts">
- <property name="geometry">
- <rect>
- <x>580</x>
- <y>340</y>
- <width>171</width>
- <height>38</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>62</width>
- <height>38</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="cursor">
- <cursorShape>PointingHandCursor</cursorShape>
- </property>
- <property name="toolTip">
- <string>Edit the Keyboard and mouse shortcuts</string>
- </property>
- <property name="text">
- <string>Keys</string>
- </property>
- <property name="icon">
- <iconset resource="main-facetracknoir.qrc">
- <normaloff>:/uielements/tools.png</normaloff>:/uielements/tools.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>98</width>
- <height>24</height>
- </size>
- </property>
- </widget>
- <widget class="QGroupBox" name="groupProfile">
- <property name="geometry">
- <rect>
- <x>550</x>
- <y>60</y>
- <width>231</width>
- <height>123</height>
- </rect>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="title">
- <string>Profile</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_5" rowstretch="6,6,6" columnstretch="6,6" rowminimumheight="6,6,6" columnminimumwidth="6,6">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="0" column="0" colspan="2">
- <widget class="QComboBox" name="iconcomboProfile">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="currentIndex">
- <number>-1</number>
- </property>
- <property name="maxVisibleItems">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="btnLoad">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Load an INI-file from a folder</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Load</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPushButton" name="btnSave">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Save the current INI-file</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Save</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QPushButton" name="btnSaveAs">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Save the INI-file under another name</string>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Save As ...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QGroupBox" name="groupBox">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>380</y>
- <width>141</width>
- <height>106</height>
- </rect>
- </property>
- <property name="title">
- <string>Raw translation</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignBottom|Qt::AlignHCenter</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMaximumSize</enum>
- </property>
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::FieldsStayAtSizeHint</enum>
- </property>
- <property name="rowWrapPolicy">
- <enum>QFormLayout::DontWrapRows</enum>
- </property>
- <property name="labelAlignment">
- <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
- </property>
- <property name="formAlignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>TX</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLCDNumber" name="lcdNumX">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>TY</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLCDNumber" name="lcdNumY">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>TZ</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLCDNumber" name="lcdNumZ">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="geometry">
- <rect>
- <x>160</x>
- <y>380</y>
- <width>161</width>
- <height>111</height>
- </rect>
- </property>
- <property name="title">
- <string>Raw rotation</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignBottom|Qt::AlignHCenter</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetMaximumSize</enum>
- </property>
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::FieldsStayAtSizeHint</enum>
- </property>
- <property name="rowWrapPolicy">
- <enum>QFormLayout::DontWrapRows</enum>
- </property>
- <property name="labelAlignment">
- <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
- </property>
- <property name="formAlignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_9">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>yaw</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLCDNumber" name="lcdNumRotX">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_8">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>pitch</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLCDNumber" name="lcdNumRotY">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_7">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="text">
- <string>roll</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLCDNumber" name="lcdNumRotZ">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="lineWidth">
- <number>0</number>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- </layout>
- <zorder>lcdNumRotZ</zorder>
- <zorder>label_8</zorder>
- <zorder>label_7</zorder>
- <zorder>lcdNumRotY</zorder>
- <zorder>lcdNumRotX</zorder>
- <zorder>label_9</zorder>
- </widget>
- </widget>
- </widget>
- <layoutdefault spacing="0" margin="0"/>
- <customwidgets>
- <customwidget>
- <class>GLWidget</class>
- <extends>QWidget</extends>
- <header>glwidget.h</header>
- </customwidget>
- </customwidgets>
- <resources>
- <include location="main-facetracknoir.qrc"/>
- </resources>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <author>WVR</author>
+ <class>OpentrackUI</class>
+ <widget class="QMainWindow" name="OpentrackUI">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>956</width>
+ <height>740</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="main-facetracknoir.qrc">
+ <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">#headpose, #video_frame_label, #controls, #video_frame { border: 0; }
+#video_frame { margin: 0; padding: 0; }
+</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QGridLayout" name="gridLayout_11">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="octopus">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Tracking preview</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="GLWidget" name="pose_display" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>120</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QGroupBox" name="headpose">
+ <property name="title">
+ <string/>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="box_raw_headpose">
+ <property name="title">
+ <string notr="true">Raw pose</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_8">
+ <item row="1" column="1">
+ <widget class="QLCDNumber" name="lcdNumY">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLCDNumber" name="lcdNumRotX">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="lblRotY_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="lblX_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>TX</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLCDNumber" name="lcdNumZ">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLCDNumber" name="lcdNumX">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="lblZ_3">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>TZ</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lblY_3">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>TY</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLCDNumber" name="lcdNumRotY">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="lblRotX_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="lblRotZ_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLCDNumber" name="lcdNumRotZ">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Outline</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="box_mapped_headpose">
+ <property name="title">
+ <string notr="true">Game data</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_10">
+ <item row="0" column="0">
+ <widget class="QLabel" name="lblX_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>TX</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLCDNumber" name="lcdNumOutputPosX">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLCDNumber" name="lcdNumOutputPosY">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="lblRotY_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLCDNumber" name="lcdNumOutputRotY">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="lblZ_2">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>TZ</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLCDNumber" name="lcdNumOutputRotX">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lblY_2">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>TY</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="lblRotX_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLCDNumber" name="lcdNumOutputPosZ">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="lblRotZ_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="text">
+ <string>roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLCDNumber" name="lcdNumOutputRotZ">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>true</bool>
+ </property>
+ <property name="digitCount">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>QLCDNumber::Flat</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="video_feed">
+ <property name="title">
+ <string>Video preview</string>
+ </property>
+ <layout class="QFormLayout">
+ <property name="horizontalSpacing">
+ <number>0</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QFrame" name="video_frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>640</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>640</width>
+ <height>480</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="video_frame_label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>640</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>640</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QGroupBox" name="controls">
+ <property name="title">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Connected game</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_9">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="game_name">
+ <property name="text">
+ <string>Not connected</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupProfile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Profile</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_7">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="btnSave">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="btnLoad">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Load</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QComboBox" name="iconcomboProfile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxVisibleItems">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="btnSaveAs">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Save As ...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupTrackerSource">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Tracker</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QComboBox" name="iconcomboTrackerSource">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="btnShowEngineControls">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupFilter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Filter</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QComboBox" name="iconcomboFilter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="btnShowFilterControls">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupGameProtocol">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Protocol</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="btnShowServerControls">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QComboBox" name="iconcomboProtocol">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupWindows">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QPushButton" name="btnEditCurves">
+ <property name="text">
+ <string>Mapping</string>
+ </property>
+ <property name="icon">
+ <iconset resource="main-facetracknoir.qrc">
+ <normaloff>:/uielements/curves.png</normaloff>:/uielements/curves.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>91</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="btnShortcuts">
+ <property name="text">
+ <string>Keys</string>
+ </property>
+ <property name="icon">
+ <iconset resource="main-facetracknoir.qrc">
+ <normaloff>:/uielements/tools.png</normaloff>:/uielements/tools.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>98</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupStartStop">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>65536</width>
+ <height>65536</height>
+ </size>
+ </property>
+ <property name="title">
+ <string notr="true">Controls</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>3</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="btnStopTracker">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QPushButton" name="btnStartTracker">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Start</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>GLWidget</class>
+ <extends>QWidget</extends>
+ <header>glwidget.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="main-facetracknoir.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui
index 33421b40..07e7b6ca 100644
--- a/facetracknoir/ftnoir_curves.ui
+++ b/facetracknoir/ftnoir_curves.ui
@@ -1,976 +1,1039 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICCurveConfigurationDialog</class>
- <widget class="QWidget" name="UICCurveConfigurationDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>970</width>
- <height>655</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>Mapping properties</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: #ccc;</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="styleSheet">
- <string notr="true">background-color: #ccc;</string>
- </property>
- <property name="tabPosition">
- <enum>QTabWidget::North</enum>
- </property>
- <property name="currentIndex">
- <number>6</number>
- </property>
- <widget class="QWidget" name="tabWidgetPage1">
- <attribute name="title">
- <string>Yaw</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="rxconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>5</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="rx_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>260</y>
- <width>166</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="rxconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>5</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage2">
- <attribute name="title">
- <string>Pitch</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="ryconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>90</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>90</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>10</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>255</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="ry_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>260</y>
- <width>199</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="ryconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>90</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>90</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>10</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>255</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage3">
- <attribute name="title">
- <string>Roll</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="rzconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>5</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>1</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>0</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="rz_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>260</y>
- <width>271</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="rzconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>180</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>5</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>1</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>0</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage4">
- <attribute name="title">
- <string>X</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="txconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>0</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="tx_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>270</y>
- <width>228</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="txconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>0</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage5">
- <attribute name="title">
- <string>Y</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="tyconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>255</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="ty_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>270</y>
- <width>229</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="tyconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>255</red>
- <green>255</green>
- <blue>0</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage6">
- <attribute name="title">
- <string>Z</string>
- </attribute>
- <widget class="QFunctionConfigurator" name="tzconfig" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- <widget class="QCheckBox" name="tz_altp">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>270</y>
- <width>263</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Asymmetric mapping below</string>
- </property>
- </widget>
- <widget class="QFunctionConfigurator" name="tzconfig_alt" native="true">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>300</y>
- <width>930</width>
- <height>260</height>
- </rect>
- </property>
- <property name="maxInputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="maxOutputEGU" stdset="0">
- <number>100</number>
- </property>
- <property name="pixPerEGU_Input" stdset="0">
- <number>28</number>
- </property>
- <property name="pixPerEGU_Output" stdset="0">
- <number>2</number>
- </property>
- <property name="colorBezier" stdset="0">
- <color>
- <red>0</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="colorBackground" stdset="0">
- <color>
- <red>240</red>
- <green>240</green>
- <blue>240</blue>
- </color>
- </property>
- </widget>
- </widget>
- <widget class="QWidget" name="tabWidgetPage7">
- <attribute name="title">
- <string>Options</string>
- </attribute>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Center pose</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>RX</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QDoubleSpinBox" name="pos_rx">
- <property name="suffix">
- <string> deg.</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-180.000000000000000</double>
- </property>
- <property name="maximum">
- <double>180.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>TX</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QDoubleSpinBox" name="pos_tx">
- <property name="suffix">
- <string> cm</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-100.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>RY</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="pos_ry">
- <property name="suffix">
- <string> deg.</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-180.000000000000000</double>
- </property>
- <property name="maximum">
- <double>180.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>TY</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QDoubleSpinBox" name="pos_ty">
- <property name="suffix">
- <string> cm</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-100.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>TZ</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>RZ</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QDoubleSpinBox" name="pos_rz">
- <property name="suffix">
- <string> deg.</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-180.000000000000000</double>
- </property>
- <property name="maximum">
- <double>180.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QDoubleSpinBox" name="pos_tz">
- <property name="suffix">
- <string> cm</string>
- </property>
- <property name="decimals">
- <number>3</number>
- </property>
- <property name="minimum">
- <double>-100.000000000000000</double>
- </property>
- <property name="maximum">
- <double>100.000000000000000</double>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="title">
- <string>Translation compensation</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QCheckBox" name="tcomp_enable">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Enable</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="tcomp_rz">
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string>Disable Z axis compensation</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QGroupBox" name="groupBox_4">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="font">
- <font>
- <kerning>true</kerning>
- </font>
- </property>
- <property name="title">
- <string>Axis inversion</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_4" rowstretch="6,6,6" columnstretch="6,6" rowminimumheight="6,6,6" columnminimumwidth="6,6">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinAndMaxSize</enum>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="chkInvertYaw">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>Yaw</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkInvertX">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>TX</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="chkInvertPitch">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>Pitch</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkInvertY">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>TY</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QCheckBox" name="chkInvertRoll">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>Roll</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkInvertZ">
- <property name="maximumSize">
- <size>
- <width>65536</width>
- <height>65536</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="styleSheet">
- <string notr="true">background:none;</string>
- </property>
- <property name="text">
- <string>TZ</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>QFunctionConfigurator</class>
- <extends>QWidget</extends>
- <header>qfunctionconfigurator.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>pos_rx</tabstop>
- <tabstop>pos_ry</tabstop>
- <tabstop>pos_rz</tabstop>
- <tabstop>ry_altp</tabstop>
- <tabstop>rz_altp</tabstop>
- <tabstop>tx_altp</tabstop>
- <tabstop>ty_altp</tabstop>
- <tabstop>tz_altp</tabstop>
- <tabstop>tcomp_enable</tabstop>
- <tabstop>tabWidget</tabstop>
- <tabstop>pos_tx</tabstop>
- <tabstop>buttonBox</tabstop>
- <tabstop>pos_ty</tabstop>
- <tabstop>rx_altp</tabstop>
- <tabstop>pos_tz</tabstop>
- </tabstops>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICCurveConfigurationDialog</class>
+ <widget class="QWidget" name="UICCurveConfigurationDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>970</width>
+ <height>655</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Mapping properties</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-color: #ccc;</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="tabPosition">
+ <enum>QTabWidget::North</enum>
+ </property>
+ <property name="currentIndex">
+ <number>6</number>
+ </property>
+ <widget class="QWidget" name="tabWidgetPage1">
+ <attribute name="title">
+ <string>Yaw</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="rxconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="rx_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>166</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="rxconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage2">
+ <attribute name="title">
+ <string>Pitch</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="ryconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="ry_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>199</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="ryconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage3">
+ <attribute name="title">
+ <string>Roll</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="rzconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="rz_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>271</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="rzconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage4">
+ <attribute name="title">
+ <string>X</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="txconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="tx_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>270</y>
+ <width>228</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="txconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage5">
+ <attribute name="title">
+ <string>Y</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="tyconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="ty_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>270</y>
+ <width>229</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="tyconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage6">
+ <attribute name="title">
+ <string>Z</string>
+ </attribute>
+ <widget class="QFunctionConfigurator" name="tzconfig" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QCheckBox" name="tz_altp">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>270</y>
+ <width>263</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Asymmetric mapping below</string>
+ </property>
+ </widget>
+ <widget class="QFunctionConfigurator" name="tzconfig_alt" native="true">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>300</y>
+ <width>930</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property name="colorBezier" stdset="0">
+ <color>
+ <red>0</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="colorBackground" stdset="0">
+ <color>
+ <red>240</red>
+ <green>240</green>
+ <blue>240</blue>
+ </color>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="tabWidgetPage7">
+ <attribute name="title">
+ <string>Options</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Center pose</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="pos_rz">
+ <property name="suffix">
+ <string> deg.</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-180.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>180.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QDoubleSpinBox" name="pos_tz">
+ <property name="suffix">
+ <string> cm</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-100.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>TX</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QDoubleSpinBox" name="pos_tx">
+ <property name="suffix">
+ <string> cm</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-100.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>RY</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>TY</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="pos_ry">
+ <property name="suffix">
+ <string> deg.</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-180.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>180.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>TZ</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>RZ</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QDoubleSpinBox" name="pos_ty">
+ <property name="suffix">
+ <string> cm</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-100.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>RX</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="pos_rx">
+ <property name="suffix">
+ <string> deg.</string>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="minimum">
+ <double>-180.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>180.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="maximumSize">
+ <size>
+ <width>65536</width>
+ <height>65536</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <kerning>true</kerning>
+ </font>
+ </property>
+ <property name="title">
+ <string>Output remap</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4" rowstretch="0,0,0,0,0,0,0" columnstretch="0,0,0">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinAndMaxSize</enum>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>X</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="invert_yaw">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QCheckBox" name="invert_pitch">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QCheckBox" name="invert_x">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QCheckBox" name="invert_roll">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QCheckBox" name="invert_y">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QCheckBox" name="invert_z">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="src_yaw">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="src_pitch">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="src_roll">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="src_x">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="src_y">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="src_z">
+ <item>
+ <property name="text">
+ <string>X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Source</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Invert</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Destination</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="title">
+ <string>Translation compensation</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="tcomp_enable">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Enable</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="tcomp_rz">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Disable Z axis compensation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QFunctionConfigurator</class>
+ <extends>QWidget</extends>
+ <header>qfunctionconfigurator.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>pos_rx</tabstop>
+ <tabstop>pos_ry</tabstop>
+ <tabstop>pos_rz</tabstop>
+ <tabstop>ry_altp</tabstop>
+ <tabstop>rz_altp</tabstop>
+ <tabstop>tx_altp</tabstop>
+ <tabstop>ty_altp</tabstop>
+ <tabstop>tz_altp</tabstop>
+ <tabstop>tcomp_enable</tabstop>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>pos_tx</tabstop>
+ <tabstop>buttonBox</tabstop>
+ <tabstop>pos_ty</tabstop>
+ <tabstop>rx_altp</tabstop>
+ <tabstop>pos_tz</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/facetracknoir/ftnoir_keyboardshortcuts.ui b/facetracknoir/ftnoir_keyboardshortcuts.ui
index 5bdc3334..245b503a 100644
--- a/facetracknoir/ftnoir_keyboardshortcuts.ui
+++ b/facetracknoir/ftnoir_keyboardshortcuts.ui
@@ -1,217 +1,217 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICKeyboardShortcutDialog</class>
- <widget class="QWidget" name="UICKeyboardShortcutDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>371</width>
- <height>125</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>Keyboard shortcuts</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkToggleShift">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Shift</string>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QComboBox" name="cbxToggleKey">
- <property name="minimumSize">
- <size>
- <width>90</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="textLabel2_5">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Toggle</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QCheckBox" name="chkCenterAlt">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Alt</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QCheckBox" name="chkCenterCtrl">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Ctrl</string>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QComboBox" name="cbxCenterKey">
- <property name="minimumSize">
- <size>
- <width>90</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QLabel" name="textLabel2_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Keyboard</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="3" colspan="2">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QCheckBox" name="chkToggleCtrl">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Ctrl</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="textLabel2_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Center</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QCheckBox" name="chkToggleAlt">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Alt</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkCenterShift">
- <property name="maximumSize">
- <size>
- <width>50</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Shift</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="2">
- <widget class="QCheckBox" name="ding">
- <property name="text">
- <string>Ding!</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICKeyboardShortcutDialog</class>
+ <widget class="QWidget" name="UICKeyboardShortcutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>371</width>
+ <height>125</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Keyboard shortcuts</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>images/facetracknoir.png</normaloff>images/facetracknoir.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="chkToggleShift">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Shift</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QComboBox" name="cbxToggleKey">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Select Number</string>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAlphabetically</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel2_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Toggle</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QCheckBox" name="chkCenterAlt">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Alt</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="chkCenterCtrl">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Ctrl</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QComboBox" name="cbxCenterKey">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Select Number</string>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAlphabetically</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="textLabel2_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Keyboard</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QCheckBox" name="chkToggleCtrl">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Ctrl</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel2_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QCheckBox" name="chkToggleAlt">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Alt</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="chkCenterShift">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Shift</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QCheckBox" name="ding">
+ <property name="text">
+ <string>Ding!</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/facetracknoir/gain-control.hpp b/facetracknoir/gain-control.hpp
new file mode 100644
index 00000000..081d4b6f
--- /dev/null
+++ b/facetracknoir/gain-control.hpp
@@ -0,0 +1,198 @@
+#pragma once
+
+/* still WIP, not usable yet! -sh 20141012 */
+
+#include <algorithm>
+#undef NDEBUG
+#include <cassert>
+#include <iterator>
+#include <tuple>
+#include <deque>
+#include <vector>
+
+#include <cstdio>
+
+#include "timer.hpp"
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+#include <QDebug>
+
+namespace detail {
+ template<typename t1, typename t2, typename t, typename m = t>
+ class zip_iterator : public std::iterator<std::forward_iterator_tag, t>
+ {
+ private:
+ using self = zip_iterator<t1, t2, t, m>;
+ t1 x1, z1;
+ t2 x2, z2;
+ void maybe_end() { if (x1 == z1 || x2 == z2) *this = end(); }
+ public:
+ zip_iterator(const t1& it1, const t1& end1, const t2& it2, const t2& end2)
+ : x1(it1), z1(end1), x2(it2), z2(end2) { maybe_end(); }
+ constexpr zip_iterator() {}
+
+ static constexpr self end() { return self(); }
+
+ self operator++() { x1++; x2++; self tmp = *this; maybe_end(); return tmp; }
+ self operator++(int) { self tmp(*this); x1++; x2++; maybe_end(); return tmp; }
+ bool operator==(const self& rhs) const { return x1 == rhs.x1 && x2 == rhs.x2; }
+ bool operator!=(const self& rhs) const { return !this->operator ==(rhs); }
+ t operator*() { return m(*x1, *x2); }
+ };
+}
+
+class Gain {
+private:
+ static constexpr bool use_box_filter = true;
+ static constexpr int box_size = 16 / 640.;
+ static constexpr double control_upper_bound = 1.0; // XXX FIXME implement for logitech crapola
+ static constexpr int GAIN_HISTORY_COUNT = 50, GAIN_HISTORY_EVERY_MS = 998;
+
+ using t_frame = cv::Mat_<unsigned char>;
+
+ int control;
+ double step, eps;
+
+ t_frame last_frame;
+ std::deque<double> means_history;
+ Timer debug_timer, history_timer;
+
+ typedef unsigned char px;
+ template<typename t1, typename t2, typename t, typename m = t>
+ using zip_iterator = detail::zip_iterator<t1, t2, t, m>;
+
+ static double mean(const cv::Mat& frame)
+ {
+ // grayscale only
+ assert(frame.channels() == 1);
+ assert(frame.elemSize() == 1);
+ assert(!frame.empty());
+
+ return std::accumulate(frame.begin<px>(), frame.end<px>(), 0.) / (frame.rows * frame.cols);
+ }
+
+ static double get_variance(const cv::Mat& frame, double mean)
+ {
+ struct variance {
+ private:
+ double mu;
+ public:
+ variance(double mu) : mu(mu) {}
+ double operator()(double seed, px p)
+ {
+ double tmp = p - mu;
+ return seed + tmp * tmp;
+ }
+ } logic(mean);
+
+ return std::accumulate(frame.begin<unsigned char>(), frame.end<unsigned char>(), 0., logic) / (frame.rows * frame.cols);
+ }
+
+ static double get_covariance(const cv::Mat& frame, const cv::Mat& old_frame)
+ {
+ double mean_0 = mean(frame), mean_1 = mean(old_frame);
+
+ struct covariance {
+ public:
+ using pair = std::tuple<px, px>;
+ private:
+ double mu_0, mu_1;
+
+ inline double Cov(double seed, const pair& t)
+ {
+ px p0 = std::get<0>(t);
+ px p1 = std::get<1>(t);
+ return seed + (p0 - mu_0) * (p1 - mu_1);
+ }
+ public:
+ covariance(double mu_0, double mu_1) : mu_0(mu_0), mu_1(mu_1) {}
+
+ double operator()(double seed, const pair& t)
+ {
+ return Cov(seed, t);
+ }
+ } logic(mean_0, mean_1);
+
+ const double N = frame.rows * frame.cols;
+
+ using zipper = zip_iterator<cv::MatConstIterator_<px>,
+ cv::MatConstIterator_<px>,
+ std::tuple<px, px>>;
+
+ zipper zip(frame.begin<px>(),
+ frame.end<px>(),
+ old_frame.begin<px>(),
+ old_frame.end<px>());
+ std::vector<covariance::pair> values(zip, zipper::end());
+
+ return std::accumulate(values.begin(), values.end(), 0., logic) / N;
+ }
+
+#pragma GCC diagnostic ignored "-Wsign-compare"
+
+public:
+ Gain(int control = CV_CAP_PROP_GAIN, double step = 0.3, double eps = 0.02) :
+ control(control), step(step), eps(eps)
+ {
+ }
+
+ void tick(cv::VideoCapture&, const cv::Mat& frame_)
+ {
+ cv::Mat frame;
+
+ if (use_box_filter)
+ {
+ cv::Mat tmp(frame_);
+ static constexpr int min_box = 3;
+ static constexpr int box = 2 * box_size;
+ cv::blur(frame_, tmp, cv::Size(min_box + box * frame_.cols, min_box + box * frame_.rows));
+ frame = tmp;
+ }
+ else
+ frame = frame_;
+
+ if (last_frame.rows != frame.rows || last_frame.cols != frame.cols)
+ last_frame = t_frame();
+
+ if (last_frame.empty())
+ {
+ last_frame = frame.clone();
+ //return;
+ }
+
+ if (history_timer.elapsed_ms() > GAIN_HISTORY_EVERY_MS)
+ {
+ //const double cov = get_covariance(frame, last_frame);
+ history_timer.start();
+ last_frame = frame.clone();
+
+ if (means_history.size() == GAIN_HISTORY_COUNT)
+ means_history.pop_back();
+ }
+
+ if (debug_timer.elapsed_ms() > 1000)
+ {
+ const double mu = mean(frame);
+ // XXX move to HSL/HSV color space for it to work! -sh 20141012
+ const double var = get_variance(frame, mu);
+
+ debug_timer.start();
+ qDebug() << "---- gain:" << "mean" << mu << "variance" << var;
+
+ const int sz = means_history.size();
+
+ if (sz)
+ {
+ fprintf(stderr, "covs{%d}: ", sz);
+
+ for (int i = 0; i < sz; i++)
+ fprintf(stderr, "%f ", means_history[i]);
+
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+};
diff --git a/facetracknoir/global-settings.cpp b/facetracknoir/global-settings.cpp
deleted file mode 100644
index 3b627860..00000000
--- a/facetracknoir/global-settings.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "global-settings.h"
-
-#if !(defined(_WIN32))
-# include <dlfcn.h>
-#endif
-
-SelectedLibraries* Libraries = NULL;
-
-SelectedLibraries::~SelectedLibraries()
-{
- if (pTracker) {
- delete pTracker;
- pTracker = NULL;
- }
-
- if (pSecondTracker) {
- delete pSecondTracker;
- pSecondTracker = NULL;
- }
-
- if (pFilter)
- delete pFilter;
-
- if (pProtocol)
- delete pProtocol;
-}
-
-SelectedLibraries::SelectedLibraries(IDynamicLibraryProvider* mainApp) :
- pTracker(NULL), pSecondTracker(NULL), pFilter(NULL), pProtocol(NULL)
-{
- correct = false;
- if (!mainApp)
- return;
- NULLARY_DYNAMIC_FUNCTION ptr;
- DynamicLibrary* lib;
-
- lib = mainApp->current_tracker1();
-
- if (lib && lib->Constructor) {
- ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor;
- pTracker = (ITracker*) ptr();
- }
-
- lib = mainApp->current_tracker2();
-
- if (lib && lib->Constructor) {
- ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor;
- pSecondTracker = (ITracker*) ptr();
- }
-
- lib = mainApp->current_protocol();
-
- if (lib && lib->Constructor) {
- ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor;
- pProtocol = (IProtocol*) ptr();
- }
-
- lib = mainApp->current_filter();
-
- if (lib && lib->Constructor) {
- ptr = (NULLARY_DYNAMIC_FUNCTION) lib->Constructor;
- pFilter = (IFilter*) ptr();
- }
-
- // Check if the Protocol-server files were installed OK.
- // Some servers also create a memory-mapping, for Inter Process Communication.
- // The handle of the MainWindow is sent to 'The Game', so it can send a message back.
-
- if (pProtocol)
- if(!pProtocol->checkServerInstallationOK())
- return;
-
- // retrieve pointers to the User Interface and the main Application
- if (pTracker) {
- pTracker->StartTracker( mainApp->get_video_widget() );
- }
- if (pSecondTracker) {
- pSecondTracker->StartTracker( mainApp->get_video_widget() );
- }
-
- correct = true;
-}
-
-DynamicLibrary::DynamicLibrary(const QString& filename)
-{
- this->filename = filename;
-#if defined(_WIN32)
- QString fullPath = QCoreApplication::applicationDirPath() + "/" + this->filename;
- handle = new QLibrary(fullPath);
- Dialog = (SETTINGS_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetDialog" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION);
- Constructor = (NULLARY_DYNAMIC_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetConstructor" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION);
- Metadata = (METADATA_FUNCTION) handle->resolve(MAYBE_STDCALL_UNDERSCORE "GetMetadata" CALLING_CONVENTION_SUFFIX_VOID_FUNCTION);
-#else
- QByteArray latin1 = QFile::encodeName(filename);
- handle = dlopen(latin1.constData(), RTLD_NOW |
-# ifdef __linux
- RTLD_DEEPBIND
-# elif defined(__APPLE__)
- RTLD_LOCAL|RTLD_FIRST|RTLD_NOW
-# else
- 0
-# endif
- );
- if (handle)
- {
- fprintf(stderr, "Error, if any: %s\n", dlerror());
- fflush(stderr);
- Dialog = (SETTINGS_FUNCTION) dlsym(handle, "GetDialog");
- fprintf(stderr, "Error, if any: %s\n", dlerror());
- fflush(stderr);
- Constructor = (NULLARY_DYNAMIC_FUNCTION) dlsym(handle, "GetConstructor");
- fprintf(stderr, "Error, if any: %s\n", dlerror());
- fflush(stderr);
- Metadata = (METADATA_FUNCTION) dlsym(handle, "GetMetadata");
- fprintf(stderr, "Error, if any: %s\n", dlerror());
- fflush(stderr);
- } else {
- fprintf(stderr, "Error, if any: %s\n", dlerror());
- fflush(stderr);
- }
-#endif
-}
-
-DynamicLibrary::~DynamicLibrary()
-{
-#if defined(_WIN32)
- handle->unload();
-#else
- if (handle)
- (void) dlclose(handle);
-#endif
-}
diff --git a/facetracknoir/global-settings.h b/facetracknoir/global-settings.h
deleted file mode 100644
index 6b04b73b..00000000
--- a/facetracknoir/global-settings.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#pragma once
-
-#if defined(_WIN32)
-# define CALLING_CONVENTION_SUFFIX_VOID_FUNCTION "@0"
-# ifdef _MSC_VER
-# define MAYBE_STDCALL_UNDERSCORE "_"
-#else
-# define MAYBE_STDCALL_UNDERSCORE ""
-# endif
-#else
-# define CALLING_CONVENTION_SUFFIX_VOID_FUNCTION ""
-# define MAYBE_STDCALL_UNDERSCORE ""
-#endif
-
-#ifdef _MSC_VER
-# define virt_override
-#else
-# define virt_override override
-#endif
-
-#include <cstdio>
-
-#include <QWidget>
-#include <QDebug>
-#include <QString>
-#include <QLibrary>
-#include <QFrame>
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
-
-#if defined(_WIN32)
-# define CALLING_CONVENTION __stdcall
-#else
-# define CALLING_CONVENTION
-#endif
-
-class IDynamicLibraryProvider;
-
-struct SelectedLibraries {
-public:
- ITracker* pTracker;
- ITracker* pSecondTracker;
- IFilter* pFilter;
- IProtocol* pProtocol;
- SelectedLibraries(IDynamicLibraryProvider* main = NULL);
- ~SelectedLibraries();
- bool correct;
-};
-
-extern SelectedLibraries* Libraries;
-
-struct Metadata;
-
-extern "C" typedef void* (CALLING_CONVENTION * NULLARY_DYNAMIC_FUNCTION)(void);
-extern "C" typedef Metadata* (CALLING_CONVENTION* METADATA_FUNCTION)(void);
-extern "C" typedef void* (CALLING_CONVENTION* SETTINGS_FUNCTION)(void);
-
-class DynamicLibrary {
-public:
- DynamicLibrary(const QString& filename);
- virtual ~DynamicLibrary();
- SETTINGS_FUNCTION Dialog;
- NULLARY_DYNAMIC_FUNCTION Constructor;
- METADATA_FUNCTION Metadata;
- QString filename;
-private:
-#if defined(_WIN32)
- QLibrary* handle;
-#else
- void* handle;
-#endif
-};
-
-struct Metadata
-{
- Metadata() {}
- virtual ~Metadata() {}
-
- virtual void getFullName(QString *strToBeFilled) = 0;
- virtual void getShortName(QString *strToBeFilled) = 0;
- virtual void getDescription(QString *strToBeFilled) = 0;
- virtual void getIcon(QIcon *icon) = 0;
-};
-
-class IDynamicLibraryProvider {
-public:
- virtual DynamicLibrary* current_tracker1() = 0;
- virtual DynamicLibrary* current_tracker2() = 0;
- virtual DynamicLibrary* current_protocol() = 0;
- virtual DynamicLibrary* current_filter() = 0;
- virtual QFrame* get_video_widget() = 0;
-};
diff --git a/facetracknoir/global-shortcuts.cpp b/facetracknoir/global-shortcuts.cpp
index 1c10b160..9b6591a7 100644
--- a/facetracknoir/global-shortcuts.cpp
+++ b/facetracknoir/global-shortcuts.cpp
@@ -1,4 +1,5 @@
-#include "facetracknoir/facetracknoir.h"
+# include <QList>
+# include <QString>
#if defined(_WIN32)
# ifndef DIRECTINPUT_VERSION
diff --git a/facetracknoir/lerp.hpp b/facetracknoir/lerp.hpp
deleted file mode 100644
index 0123832a..00000000
--- a/facetracknoir/lerp.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include "facetracknoir/timer.hpp"
-#include <algorithm>
-#include <cmath>
-
-class lerp {
-private:
- static const constexpr double eps = 1e-2;
- double last[2][6], cam[6], dt;
- Timer t;
-public:
- lerp() :
- last { {0,0,0,0,0,0}, {0,0,0,0,0,0} }, cam {0,0,0,0,0,0}, dt(1)
- {
- }
- bool idempotentp(const double* input)
- {
- for (int i = 0; i < 6; i++)
- {
- double diff = fabs(cam[i] - input[i]);
- if (diff > eps)
- return false;
- }
- return true;
- }
-
- void write(const double* cam_, const double* input, double* output)
- {
- const double q = t.elapsed();
- const double d = q/dt;
-
- bool idem = idempotentp(cam_);
-
- if (!idem)
- {
- dt = q;
- t.start();
- }
-
- const double c = std::max(std::min(1.0, d), 0.0);
-
- if (!idem)
- for (int i = 0; i < 6; i++)
- {
- last[1][i] = last[0][i];
- last[0][i] = input[i];
- cam[i] = cam_[i];
- }
-
- for (int i = 0; i < 6; i++)
- output[i] = last[1][i] + (last[0][i] - last[1][i]) * c;
- }
-
- void get_state(double* state)
- {
- for (int i = 0; i < 6; i++)
- state[i] = last[0][i];
- }
-};
diff --git a/facetracknoir/main-facetracknoir.qrc b/facetracknoir/main-facetracknoir.qrc
index 6cb2e300..e37c2529 100644
--- a/facetracknoir/main-facetracknoir.qrc
+++ b/facetracknoir/main-facetracknoir.qrc
@@ -4,5 +4,6 @@
<file>images/settings16.png</file>
<file>uielements/curves.png</file>
<file>images/facetracknoir.png</file>
+ <file>uielements/no-feed.png</file>
</qresource>
</RCC>
diff --git a/facetracknoir/main-settings.hpp b/facetracknoir/main-settings.hpp
index 8e93bd24..0a1fb968 100644
--- a/facetracknoir/main-settings.hpp
+++ b/facetracknoir/main-settings.hpp
@@ -18,10 +18,12 @@ struct key_opts {
struct axis_opts {
value<double> zero;
value<bool> invert, altp;
- axis_opts(pbundle b, QString pfx) :
+ value<int> src;
+ axis_opts(pbundle b, QString pfx, int idx) :
zero(b, n(pfx, "zero-pos"), 0),
invert(b, n(pfx, "invert-axis"), false),
- altp(b, n(pfx, "alt-axis-sign"), false)
+ altp(b, n(pfx, "alt-axis-sign"), false),
+ src(b, n(pfx, "source-index"), idx)
{}
private:
static inline QString n(QString pfx, QString name) {
@@ -44,12 +46,12 @@ struct main_settings {
tracker2_dll(b, "tracker2-dll", ""),
filter_dll(b, "filter-dll", ""),
protocol_dll(b, "protocol-dll", ""),
- a_x(b, "x"),
- a_y(b, "y"),
- a_z(b, "z"),
- a_yaw(b, "yaw"),
- a_pitch(b, "pitch"),
- a_roll(b, "roll"),
+ a_x(b, "x", TX),
+ a_y(b, "y", TY),
+ a_z(b, "z", TZ),
+ a_yaw(b, "yaw", Yaw),
+ a_pitch(b, "pitch", Pitch),
+ a_roll(b, "roll", Roll),
tcomp_p(b, "compensate-translation", true),
tcomp_tz(b, "compensate-translation-disable-z-axis", false),
dingp(b, "ding", true)
diff --git a/facetracknoir/main.cpp b/facetracknoir/main.cpp
index 3143a093..aa33522d 100644
--- a/facetracknoir/main.cpp
+++ b/facetracknoir/main.cpp
@@ -1,72 +1,37 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of the some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2010 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-*********************************************************************************/
-
#include "facetracknoir.h"
-#include "tracker.h"
#include <QApplication>
-#include <QDesktopWidget>
-#include <QDebug>
-#include <QList>
-#include <QDir>
+#include <QStyleFactory>
#include <QStringList>
#include <memory>
-#if defined(_WIN32) && defined(_MSC_VER)
-# include <windows.h>
-# ifdef OPENTRACK_BREAKPAD
-# include <exception_handler.h>
-using namespace google_breakpad;
-bool dumpCallback(const wchar_t* dump_path,
- const wchar_t* minidump_id,
- void* context,
- EXCEPTION_POINTERS* exinfo,
- MDRawAssertionInfo* assertion,
- bool succeeded)
-{
- MessageBoxA(GetDesktopWindow(),
- "Generating crash dump!\r\n"
- "Please send the .dmp file to <sthalik@misaki.pl> to help us improve the code.",
- "opentrack crashed :(",
- MB_OK | MB_ICONERROR);
- return succeeded;
-}
-
-# endif
-#endif
-
int main(int argc, char** argv)
{
-#if defined(OPENTRACK_BREAKPAD) && defined(_MSC_VER)
- auto handler = new ExceptionHandler(L".", nullptr, dumpCallback, nullptr, -1);
+ // workaround QTBUG-38598
+ QCoreApplication::addLibraryPath(".");
+
+ // qt5 designer-made controls look like shit on 'doze -sh 20140921
+#ifdef _WIN32
+ {
+ const QStringList preferred { "fusion", "windowsvista", "jazzbands'-marijuana", "macintosh", "windowsxp" };
+ for (const auto& style_name : preferred)
+ {
+ QStyle* s = QStyleFactory::create(style_name);
+ if (s)
+ {
+ QApplication::setStyle(s);
+ break;
+ }
+ }
+ }
#endif
+
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
QApplication app(argc, argv);
+
auto w = std::make_shared<FaceTrackNoIR>();
w->show();
app.exec();
- return 0;
+ return 0;
}
-
diff --git a/facetracknoir/mappings.hpp b/facetracknoir/mappings.hpp
new file mode 100644
index 00000000..5953ed1e
--- /dev/null
+++ b/facetracknoir/mappings.hpp
@@ -0,0 +1,88 @@
+#pragma once
+
+#include <QSettings>
+#include "options.h"
+using namespace options;
+#include "../qfunctionconfigurator/functionconfig.h"
+#include "main-settings.hpp"
+
+class Mapping {
+public:
+ Mapping(QString primary,
+ QString secondary,
+ int maxInput1,
+ int maxOutput1,
+ int maxInput2,
+ int maxOutput2,
+ axis_opts& opts) :
+ curve(maxInput1, maxOutput1),
+ curveAlt(maxInput2, maxOutput2),
+ opts(opts),
+ name1(primary),
+ name2(secondary)
+ {
+ // XXX TODO move all this qsettings boilerplate into a single header -sh 20141004
+ QSettings settings("opentrack");
+ QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
+ QSettings iniFile(currentFile, QSettings::IniFormat);
+ curve.loadSettings(iniFile, primary);
+ curveAlt.loadSettings(iniFile, secondary);
+ }
+ Map curve;
+ Map curveAlt;
+ axis_opts& opts;
+ QString name1, name2;
+};
+
+class Mappings {
+private:
+ Mapping axes[6];
+public:
+ Mappings(std::vector<axis_opts*> opts) :
+ axes {
+ Mapping("tx","tx_alt", 100, 100, 100, 100, *opts[TX]),
+ Mapping("ty","ty_alt", 100, 100, 100, 100, *opts[TY]),
+ Mapping("tz","tz_alt", 100, 100, 100, 100, *opts[TZ]),
+ Mapping("rx", "rx_alt", 180, 180, 180, 180, *opts[Yaw]),
+ Mapping("ry", "ry_alt", 180, 180, 180, 180, *opts[Pitch]),
+ Mapping("rz", "rz_alt", 180, 180, 180, 180, *opts[Roll])
+ }
+ {}
+
+ inline Mapping& operator()(int i) { return axes[i]; }
+ inline const Mapping& operator()(int i) const { return axes[i]; }
+
+ void load_mappings()
+ {
+ QSettings settings("opentrack");
+ QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat );
+
+ for (int i = 0; i < 6; i++)
+ {
+ axes[i].curve.loadSettings(iniFile, axes[i].name1);
+ axes[i].curveAlt.loadSettings(iniFile, axes[i].name2);
+ }
+ }
+ void save_mappings()
+ {
+ QSettings settings("opentrack");
+ QString currentFile = settings.value("SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini").toString();
+ QSettings iniFile(currentFile, QSettings::IniFormat);
+
+ for (int i = 0; i < 6; i++)
+ {
+ axes[i].curve.saveSettings(iniFile, axes[i].name1);
+ axes[i].curveAlt.saveSettings(iniFile, axes[i].name2);
+ }
+ }
+
+ void invalidate_unsaved()
+ {
+ for (int i = 0; i < 6; i++)
+ {
+ axes[i].curve.invalidate_unsaved_settings();
+ axes[i].curveAlt.invalidate_unsaved_settings();
+ }
+ }
+};
diff --git a/facetracknoir/options.h b/facetracknoir/options.h
index 3fd0e767..7833ea41 100644
--- a/facetracknoir/options.h
+++ b/facetracknoir/options.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 Stanislaw Halik
+/* Copyright (c) 2013-2014 Stanislaw Halik
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -7,15 +7,17 @@
#pragma once
+#include <memory>
+#include <tuple>
+#include <map>
+#include <string>
+
#include <QObject>
#include <QSettings>
-#include <QMap>
#include <QString>
#include <QVariant>
#include <QMutex>
#include <QMutexLocker>
-#include <memory>
-#include <cassert>
#include <QWidget>
#include <QComboBox>
#include <QCheckBox>
@@ -26,17 +28,19 @@
#include <QLabel>
#include <QCoreApplication>
-#ifdef __GNUC__
-# define ov override
-#else
-# define ov
-#endif
+#include <cinttypes>
#include <QDebug>
namespace options {
- template<typename T>
- inline T qcruft_to_t (const QVariant& t);
+ template<typename k, typename v>
+ using map = std::map<k, v>;
+ using std::string;
+
+ template<typename t>
+ // don't elide usages of the function, qvariant default implicit
+ // conversion results in nonsensical runtime behavior -sh
+ inline t qcruft_to_t (const QVariant& datum);
template<>
inline int qcruft_to_t<int>(const QVariant& t)
@@ -71,60 +75,72 @@ namespace options {
// snapshot of qsettings group at given time
class group {
private:
- QMap<QString, QVariant> map;
- QString name;
- public:
- group(const QString& name) : name(name)
+ map<string, QVariant> map;
+ string name;
+ static const QString ini_pathname()
{
QSettings settings(group::org);
- QString currentFile =
- settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings iniFile(currentFile, QSettings::IniFormat);
- iniFile.beginGroup(name);
- for (auto& k : iniFile.childKeys())
- map[k] = iniFile.value(k);
- iniFile.endGroup();
+ return settings.value("SettingsFile",
+ QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
+ }
+ public:
+ group(const string& name) : name(name)
+ {
+ QSettings conf(ini_pathname(), QSettings::IniFormat);
+ auto q_name = QString::fromStdString(name);
+ conf.beginGroup(q_name);
+ for (auto& k_ : conf.childKeys())
+ {
+ auto tmp = k_.toUtf8();
+ string k(tmp);
+ map[k] = conf.value(k_);
+ }
+ conf.endGroup();
}
static constexpr const char* org = "opentrack";
- void save() {
- QSettings settings(group::org);
- QString currentFile =
- settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings s(currentFile, QSettings::IniFormat);
- s.beginGroup(name);
- for (auto& k : map.keys())
- s.setValue(k, map[k]);
+
+ void save()
+ {
+ QSettings s(ini_pathname(), QSettings::IniFormat);
+ auto q_name = QString::fromStdString(name);
+ s.beginGroup(q_name);
+ for (auto& i : map)
+ {
+ auto k = QString::fromStdString(i.first);
+ s.setValue(k, i.second);
+ }
s.endGroup();
}
- template<typename T>
- T get(const QString& k) {
- return qcruft_to_t<T>(map.value(k));
+
+ template<typename t>
+ t get(const string& k)
+ {
+ return qcruft_to_t<t>(map[k]);
}
-
- void put(const QString& s, const QVariant& d)
+
+ void put(const string& s, const QVariant& d)
{
map[s] = d;
}
- bool contains(const QString& s)
+
+ bool contains(const string& s)
{
- return map.contains(s);
+ return map.count(s) != 0;
}
};
class impl_bundle : public QObject {
Q_OBJECT
- private:
+ protected:
QMutex mtx;
- const QString group_name;
+ const string group_name;
group saved;
group transient;
+ bool modified;
impl_bundle(const impl_bundle&) = delete;
impl_bundle& operator=(const impl_bundle&) = delete;
- bool modified;
public:
- impl_bundle(const QString& group_name) :
+ impl_bundle(const string& group_name) :
mtx(QMutex::Recursive),
group_name(group_name),
saved(group_name),
@@ -132,37 +148,39 @@ namespace options {
modified(false)
{
}
+
+ string name() { return group_name; }
+
void reload() {
QMutexLocker l(&mtx);
saved = group(group_name);
transient = saved;
- emit reloaded();
- }
-
- std::shared_ptr<impl_bundle> make(const QString& name) {
- return std::make_shared<impl_bundle>(name);
+ modified = false;
}
- void store(const QString& name, const QVariant& datum)
+
+ bool store_kv(const string& name, const QVariant& datum)
{
QMutexLocker l(&mtx);
- if (!transient.contains(name) || datum != transient.get<QVariant>(name))
+
+ auto old = transient.get<QVariant>(name);
+ if (!transient.contains(name) || datum != old)
{
- if (!modified)
- qDebug() << name << transient.get<QVariant>(name) << datum;
modified = true;
transient.put(name, datum);
- emit bundleChanged();
+ return true;
}
+ return false;
}
- bool contains(const QString& name)
+ bool contains(const string& name)
{
QMutexLocker l(&mtx);
return transient.contains(name);
}
- template<typename T>
- T get(const QString& name) {
+ template<typename t>
+ t get(const string& name)
+ {
QMutexLocker l(&mtx);
- return transient.get<T>(name);
+ return transient.get<t>(name);
}
void save()
{
@@ -171,90 +189,139 @@ namespace options {
saved = transient;
transient.save();
}
- void revert()
- {
- QMutexLocker l(&mtx);
- modified = false;
- transient = saved;
- emit bundleChanged();
- }
bool modifiedp() {
QMutexLocker l(&mtx);
return modified;
}
- signals:
- void bundleChanged();
- void reloaded();
};
-
- typedef std::shared_ptr<impl_bundle> pbundle;
+
+ class opt_bundle;
+
+ namespace
+ {
+ template<typename k, typename v, typename cnt = int>
+ struct opt_singleton
+ {
+ public:
+ using pbundle = std::shared_ptr<v>;
+ using tt = std::tuple<cnt, pbundle>;
+ private:
+ QMutex implsgl_mtx;
+ map<k, tt> implsgl_data;
+ public:
+ opt_singleton() : implsgl_mtx(QMutex::Recursive) {}
+
+ pbundle bundle(const k& key)
+ {
+ QMutexLocker l(&implsgl_mtx);
+
+ if (implsgl_data.count(key) != 0)
+ return std::get<1>(implsgl_data[key]);
+
+ auto shr = std::make_shared<v>(key);
+ implsgl_data[key] = tt(cnt(1), shr);
+ return shr;
+ }
+
+ void bundle_decf(const k& key)
+ {
+ QMutexLocker l(&implsgl_mtx);
+
+ if (--std::get<0>(implsgl_data[key]) == 0)
+ implsgl_data.erase(key);
+ }
+
+ ~opt_singleton() { implsgl_data.clear(); }
+ };
+
+ using pbundle = std::shared_ptr<opt_bundle>;
+ using t_fact = opt_singleton<string, opt_bundle>;
+ static t_fact* opt_factory = new t_fact;
+ }
+
+ static inline t_fact::pbundle bundle(const string name) { return opt_factory->bundle(name); }
+
+ class opt_bundle : public impl_bundle
+ {
+ public:
+ opt_bundle() : impl_bundle("i-have-no-name") {}
+ opt_bundle(const string& group_name) : impl_bundle(group_name) {}
+
+ ~opt_bundle()
+ {
+ opt_factory->bundle_decf(this->group_name);
+ }
+ };
class base_value : public QObject {
Q_OBJECT
+#define DEFINE_SLOT(t) void setValue(t datum) { store(datum); }
+#define DEFINE_SIGNAL(t) void valueChanged(const t&)
public:
- base_value(pbundle b, const QString& name) : b(b), self_name(name) {
- connect(b.get(), SIGNAL(reloaded()), this, SLOT(reread_value()));
- }
+ base_value(pbundle b, const string& name) : b(b), self_name(name) {}
protected:
- virtual QVariant operator=(const QVariant& datum) = 0;
pbundle b;
- QString self_name;
- public slots:
- void reread_value()
+ string self_name;
+
+ template<typename t>
+ void store(const t& datum)
{
- this->operator=(b->get<QVariant>(self_name));
+ if (b->store_kv(self_name, datum))
+ emit valueChanged(datum);
}
public slots:
-#define DEFINE_SLOT(t) void setValue(t datum) { this->operator=(qVariantFromValue(datum)); }
DEFINE_SLOT(double)
DEFINE_SLOT(int)
DEFINE_SLOT(QString)
DEFINE_SLOT(bool)
signals:
-#define DEFINE_SIGNAL(t) void valueChanged(t);
- DEFINE_SIGNAL(double)
- DEFINE_SIGNAL(int)
- DEFINE_SIGNAL(QString)
- DEFINE_SIGNAL(bool)
+ DEFINE_SIGNAL(double);
+ DEFINE_SIGNAL(int);
+ DEFINE_SIGNAL(bool);
+ DEFINE_SIGNAL(QString);
};
+
+ static inline string string_from_qstring(const QString& datum)
+ {
+ auto tmp = datum.toUtf8();
+ return string(tmp.constData());
+ }
- template<typename T>
+ template<typename t>
class value : public base_value {
- protected:
- QVariant operator=(const QVariant& datum) {
- auto foo = qcruft_to_t<T>(datum);
- b->store(self_name, qVariantFromValue<T>(foo));
- emit valueChanged(foo);
+ public:
+ t operator=(const t datum)
+ {
+ store(datum);
return datum;
}
- public:
- static constexpr const Qt::ConnectionType QT_CONNTYPE = Qt::UniqueConnection;
- static constexpr const Qt::ConnectionType OPT_CONNTYPE = Qt::UniqueConnection;
- value(pbundle b, const QString& name, T def) :
- base_value(b, name)
+ static constexpr const Qt::ConnectionType DIRECT_CONNTYPE = Qt::DirectConnection;
+ static constexpr const Qt::ConnectionType SAFE_CONNTYPE = Qt::UniqueConnection;
+ value(pbundle b, const string& name, t def) : base_value(b, name)
{
if (!b->contains(name) || b->get<QVariant>(name).type() == QVariant::Invalid)
- {
- this->operator=(qVariantFromValue<T>(def));
- }
+ *this = def;
}
- operator T() { return b->get<T>(self_name); }
- QVariant operator=(const T& datum)
+ value(pbundle b, const QString& name, t def) : value(b, string_from_qstring(name), def) {}
+ value(pbundle b, const char* name, t def) : value(b, string(name), def) {}
+
+ operator t()
{
- return this->operator =(qVariantFromValue<T>(datum));
+ return b->get<t>(self_name);
}
};
- template<typename T, typename Q>
- inline void tie_setting(value<T>&, Q*);
+ template<typename t, typename q>
+ inline void tie_setting(value<t>&, q*);
template<>
inline void tie_setting(value<int>& v, QComboBox* cb)
{
cb->setCurrentIndex(v);
- base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)), v.OPT_CONNTYPE);
+ v = cb->currentIndex();
+ base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)), v.SAFE_CONNTYPE);
}
template<>
@@ -262,58 +329,55 @@ namespace options {
{
cb->setCurrentText(v);
v = cb->currentText();
- base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)), v.OPT_CONNTYPE);
+ base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<bool>& v, QCheckBox* cb)
{
cb->setChecked(v);
- base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.OPT_CONNTYPE);
+ base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<double>& v, QDoubleSpinBox* dsb)
{
dsb->setValue(v);
- base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)), v.OPT_CONNTYPE);
+ base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<int>& v, QSpinBox* sb)
{
sb->setValue(v);
- base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)), v.OPT_CONNTYPE);
+ base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<int>& v, QSlider* sl)
{
sl->setValue(v);
- base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)), v.OPT_CONNTYPE);
+ v = sl->value();
+ base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<QString>& v, QLineEdit* le)
{
le->setText(v);
- base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)), v.QT_CONNTYPE);
- base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)), v.OPT_CONNTYPE);
+ base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)), v.SAFE_CONNTYPE);
}
template<>
inline void tie_setting(value<QString>& v, QLabel* lb)
{
lb->setText(v);
- base_value::connect(&v, SIGNAL(valueChanged(QString)), lb, SLOT(setText(QString)), v.OPT_CONNTYPE);
- }
-
- inline pbundle bundle(const QString& group) {
- return std::make_shared<impl_bundle>(group);
+ base_value::connect(&v, SIGNAL(valueChanged(QString)), lb, SLOT(setText(QString)), v.SAFE_CONNTYPE);
}
}
diff --git a/facetracknoir/plugin-api.hpp b/facetracknoir/plugin-api.hpp
new file mode 100644
index 00000000..f352a6a9
--- /dev/null
+++ b/facetracknoir/plugin-api.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "facetracknoir/export.hpp"
+
+enum Axis {
+ TX = 0, TY, TZ, Yaw, Pitch, Roll
+};
+
+#ifndef OPENTRACK_CROSS_ONLY
+# include "facetracknoir/plugin-qt-api.hpp"
+#endif \ No newline at end of file
diff --git a/facetracknoir/plugin-qt-api.hpp b/facetracknoir/plugin-qt-api.hpp
new file mode 100644
index 00000000..1697d8e7
--- /dev/null
+++ b/facetracknoir/plugin-qt-api.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+#include <QString>
+#include <QFrame>
+
+struct Metadata
+{
+ Metadata() {}
+ virtual ~Metadata() {}
+
+ virtual void getFullName(QString *strToBeFilled) = 0;
+ virtual void getShortName(QString *strToBeFilled) = 0;
+ virtual void getDescription(QString *strToBeFilled) = 0;
+ virtual void getIcon(QIcon *icon) = 0;
+};
+
+// XXX TODO get rid of QString/QFrame to fix ABI woes
+// will lead plugins from different C++ runtimes working -sh 20141004
+
+// XXX TODO make virtual public the mess -sh 20141004
+
+struct IFilter
+{
+ virtual ~IFilter() = 0;
+ virtual void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position) = 0;
+};
+inline IFilter::~IFilter() {}
+
+struct IFilterDialog
+{
+ virtual ~IFilterDialog() = 0;
+ virtual void registerFilter(IFilter* tracker) = 0;
+ virtual void unregisterFilter() = 0;
+};
+inline IFilterDialog::~IFilterDialog() {}
+
+struct IProtocol
+{
+ virtual ~IProtocol() = 0;
+ virtual bool checkServerInstallationOK() = 0;
+ virtual void sendHeadposeToGame( const double* headpose ) = 0;
+ virtual QString getGameName() = 0;
+};
+inline IProtocol::~IProtocol() {}
+
+struct IProtocolDialog
+{
+ virtual ~IProtocolDialog() = 0;
+ virtual void registerProtocol(IProtocol *protocol) = 0;
+ virtual void unRegisterProtocol() = 0;
+};
+inline IProtocolDialog::~IProtocolDialog() {}
+
+struct ITracker
+{
+ virtual ~ITracker() = 0;
+ virtual void StartTracker( QFrame* frame ) = 0;
+ virtual void GetHeadPoseData(double *data) = 0;
+};
+inline ITracker::~ITracker() {}
+
+struct ITrackerDialog
+{
+ virtual ~ITrackerDialog() = 0;
+ virtual void registerTracker(ITracker *tracker) = 0;
+ virtual void unRegisterTracker() = 0;
+};
+inline ITrackerDialog::~ITrackerDialog() {}
diff --git a/facetracknoir/plugin-support.cpp b/facetracknoir/plugin-support.cpp
new file mode 100644
index 00000000..e9154bb7
--- /dev/null
+++ b/facetracknoir/plugin-support.cpp
@@ -0,0 +1,158 @@
+#include <cstdio>
+#include "plugin-support.h"
+#include <QCoreApplication>
+#include <QFile>
+
+#ifndef _WIN32
+# include <dlfcn.h>
+#endif
+
+SelectedLibraries* Libraries = NULL;
+
+SelectedLibraries::~SelectedLibraries()
+{
+ if (pTracker) {
+ delete pTracker;
+ pTracker = NULL;
+ }
+
+ if (pFilter)
+ delete pFilter;
+
+ if (pProtocol)
+ delete pProtocol;
+}
+
+SelectedLibraries::SelectedLibraries(IDynamicLibraryProvider* mainApp) :
+ pTracker(NULL), pFilter(NULL), pProtocol(NULL)
+{
+ correct = false;
+ if (!mainApp)
+ return;
+ CTOR_FUNPTR ptr;
+ DynamicLibrary* lib;
+
+ lib = mainApp->current_tracker1();
+
+ if (lib && lib->Constructor) {
+ ptr = (CTOR_FUNPTR) lib->Constructor;
+ pTracker = (ITracker*) ptr();
+ }
+
+ lib = mainApp->current_protocol();
+
+ if (lib && lib->Constructor) {
+ ptr = (CTOR_FUNPTR) lib->Constructor;
+ pProtocol = (IProtocol*) ptr();
+ }
+
+ lib = mainApp->current_filter();
+
+ if (lib && lib->Constructor) {
+ ptr = (CTOR_FUNPTR) lib->Constructor;
+ pFilter = (IFilter*) ptr();
+ }
+
+ if (pProtocol)
+ if(!pProtocol->checkServerInstallationOK())
+ return;
+ if (pTracker) {
+ pTracker->StartTracker( mainApp->get_video_widget() );
+ }
+
+ correct = true;
+}
+
+DynamicLibrary::DynamicLibrary(const QString& filename) :
+ Dialog(nullptr),
+ Constructor(nullptr),
+ Metadata(nullptr)
+{
+ this->filename = filename;
+#if defined(_WIN32)
+ QString fullPath = QCoreApplication::applicationDirPath() + "/" + this->filename;
+ handle = new QLibrary(fullPath);
+
+ struct _foo {
+ static bool die(QLibrary*& l, bool failp)
+ {
+ if (failp)
+ {
+ qDebug() << "failed" << l->errorString();
+ delete l;
+ l = nullptr;
+ }
+ return failp;
+ }
+ };
+
+ if (_foo::die(handle, !handle->load()))
+ return;
+
+ Dialog = (DIALOG_FUNPTR) handle->resolve("GetDialog");
+ if (_foo::die(handle, !Dialog))
+ return;
+
+ Constructor = (CTOR_FUNPTR) handle->resolve("GetConstructor");
+ if (_foo::die(handle, !Constructor))
+ return;
+
+ Metadata = (METADATA_FUNPTR) handle->resolve("GetMetadata");
+ if (_foo::die(handle, !Metadata))
+ return;
+#else
+ QByteArray latin1 = QFile::encodeName(filename);
+ handle = dlopen(latin1.constData(), RTLD_NOW |
+# ifdef __linux
+ RTLD_DEEPBIND
+# elif defined(__APPLE__)
+ RTLD_LOCAL|RTLD_FIRST|RTLD_NOW
+# else
+ 0
+# endif
+ );
+
+ struct _foo {
+ static bool err(void*& handle)
+ {
+ const char* err = dlerror();
+ if (err)
+ {
+ fprintf(stderr, "Error, ignoring: %s\n", err);
+ fflush(stderr);
+ dlclose(handle);
+ handle = nullptr;
+ return true;
+ }
+ return false;
+ }
+ };
+
+ if (handle)
+ {
+ if (_foo::err(handle))
+ return;
+ Dialog = (DIALOG_FUNPTR) dlsym(handle, "GetDialog");
+ if (_foo::err(handle))
+ return;
+ Constructor = (CTOR_FUNPTR) dlsym(handle, "GetConstructor");
+ if (_foo::err(handle))
+ return;
+ Metadata = (METADATA_FUNPTR) dlsym(handle, "GetMetadata");
+ if (_foo::err(handle))
+ return;
+ } else {
+ (void) _foo::err(handle);
+ }
+#endif
+}
+
+DynamicLibrary::~DynamicLibrary()
+{
+#if defined(_WIN32)
+ handle->unload();
+#else
+ if (handle)
+ (void) dlclose(handle);
+#endif
+}
diff --git a/facetracknoir/plugin-support.h b/facetracknoir/plugin-support.h
new file mode 100644
index 00000000..b539d152
--- /dev/null
+++ b/facetracknoir/plugin-support.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "facetracknoir/plugin-api.hpp"
+
+#include <QWidget>
+#include <QDebug>
+#include <QString>
+#include <QLibrary>
+#include <QFrame>
+
+class IDynamicLibraryProvider;
+
+struct SelectedLibraries {
+public:
+ ITracker* pTracker;
+ IFilter* pFilter;
+ IProtocol* pProtocol;
+ SelectedLibraries(IDynamicLibraryProvider* main = NULL);
+ ~SelectedLibraries();
+ bool correct;
+};
+
+extern SelectedLibraries* Libraries;
+
+struct Metadata;
+
+extern "C" typedef void* (*CTOR_FUNPTR)(void);
+extern "C" typedef Metadata* (*METADATA_FUNPTR)(void);
+extern "C" typedef void* (*DIALOG_FUNPTR)(void);
+
+class DynamicLibrary {
+public:
+ DynamicLibrary(const QString& filename);
+ ~DynamicLibrary();
+ DIALOG_FUNPTR Dialog;
+ CTOR_FUNPTR Constructor;
+ METADATA_FUNPTR Metadata;
+ QString filename;
+private:
+#if defined(_WIN32)
+ QLibrary* handle;
+#else
+ void* handle;
+#endif
+};
+
+
+// XXX TODO it can die if running tracker state separated into class -sh 20141004
+class IDynamicLibraryProvider {
+public:
+ virtual DynamicLibrary* current_tracker1() = 0;
+ virtual DynamicLibrary* current_protocol() = 0;
+ virtual DynamicLibrary* current_filter() = 0;
+ virtual QFrame* get_video_widget() = 0;
+};
diff --git a/facetracknoir/pose.hpp b/facetracknoir/pose.hpp
new file mode 100644
index 00000000..41e984f5
--- /dev/null
+++ b/facetracknoir/pose.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <utility>
+#include <algorithm>
+#include "./quat.hpp"
+#include "./plugin-api.hpp"
+
+class Pose {
+private:
+ static constexpr double pi = 3.141592653;
+ static constexpr double d2r = pi/180.0;
+ static constexpr double r2d = 180./pi;
+
+ double axes[6];
+public:
+ Pose() : axes {0,0,0, 0,0,0 } {}
+
+ inline operator double*() { return axes; }
+ inline operator const double*() const { return axes; }
+
+ inline double& operator()(int i) { return axes[i]; }
+ inline double operator()(int i) const { return axes[i]; }
+
+ Quat quat() const
+ {
+ return Quat(axes[Yaw]*d2r, axes[Pitch]*d2r, axes[Roll]*d2r);
+ }
+
+ static Pose fromQuat(const Quat& q)
+ {
+ Pose ret;
+ q.to_euler_degrees(ret(Yaw), ret(Pitch), ret(Roll));
+ return ret;
+ }
+
+ Pose operator&(const Pose& B) const
+ {
+ const Quat q = quat() * B.quat().inv();
+ Pose ret = fromQuat(q);
+ for (int i = TX; i < TX + 3; i++)
+ ret(i) = axes[i] - B.axes[i];
+ return ret;
+ }
+};
diff --git a/facetracknoir/qcopyable-mutex.hpp b/facetracknoir/qcopyable-mutex.hpp
new file mode 100644
index 00000000..f7f36f93
--- /dev/null
+++ b/facetracknoir/qcopyable-mutex.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <QMutex>
+
+class MyMutex {
+private:
+ QMutex inner;
+
+public:
+ QMutex* operator->() { return &inner; }
+ QMutex* operator->() const { return &const_cast<MyMutex*>(this)->inner; }
+
+ MyMutex operator=(const MyMutex& datum)
+ {
+ auto mode =
+ datum->isRecursive()
+ ? QMutex::Recursive
+ : QMutex::NonRecursive;
+
+ return MyMutex(mode);
+ }
+
+ MyMutex(const MyMutex& datum)
+ {
+ *this = datum;
+ }
+
+ MyMutex(QMutex::RecursionMode mode = QMutex::NonRecursive) :
+ inner(mode)
+ {
+ }
+
+ QMutex* operator&()
+ {
+ return &inner;
+ }
+};
diff --git a/facetracknoir/qt-moc.h b/facetracknoir/qt-moc.h
deleted file mode 100644
index 8ccfffe8..00000000
--- a/facetracknoir/qt-moc.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <QObject>
-
-// this file exists only such that cmake qt automoc is appeased
-
-class AutomocMe : public QObject {
- Q_OBJECT
-private:
- virtual void foo() = 0;
- AutomocMe() {}
-};
diff --git a/facetracknoir/quat.hpp b/facetracknoir/quat.hpp
new file mode 100644
index 00000000..6d777b28
--- /dev/null
+++ b/facetracknoir/quat.hpp
@@ -0,0 +1,66 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 <cmath>
+
+class Quat {
+private:
+ static constexpr double pi = 3.141592653;
+ static constexpr double r2d = 180./pi;
+ double a,b,c,d; // quaternion coefficients
+public:
+ Quat() : a(1.),b(0.),c(0.),d(0.) {}
+ Quat(double yaw, double pitch, double roll) { from_euler_rads(yaw, pitch, roll); }
+ Quat(double a, double b, double c, double d) : a(a),b(b),c(c),d(d) {}
+
+ Quat inv(){
+ return Quat(a,-b,-c, -d);
+ }
+
+ // conversions
+ // see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
+ void from_euler_rads(double yaw, double pitch, double roll)
+ {
+
+ const double sin_phi = sin(roll/2.);
+ const double cos_phi = cos(roll/2.);
+ const double sin_the = sin(pitch/2.);
+ const double cos_the = cos(pitch/2.);
+ const double sin_psi = sin(yaw/2.);
+ const double cos_psi = cos(yaw/2.);
+
+ a = cos_phi*cos_the*cos_psi + sin_phi*sin_the*sin_psi;
+ b = sin_phi*cos_the*cos_psi - cos_phi*sin_the*sin_psi;
+ c = cos_phi*sin_the*cos_psi + sin_phi*cos_the*sin_psi;
+ d = cos_phi*cos_the*sin_psi - sin_phi*sin_the*cos_psi;
+ }
+
+ void to_euler_rads(double& yaw, double& pitch, double& roll) const
+ {
+ roll = atan2(2.*(a*b + c*d), 1. - 2.*(b*b + c*c));
+ pitch = asin(2.*(a*c - b*d));
+ yaw = atan2(2.*(a*d + b*c), 1. - 2.*(c*c + d*d));
+ }
+
+ void to_euler_degrees(double& yaw, double& pitch, double& roll) const
+ {
+ to_euler_rads(yaw, pitch, roll);
+ yaw *= r2d;
+ pitch *= r2d;
+ roll *= r2d;
+ }
+
+ const Quat operator*(const Quat& B) const
+ {
+ const Quat& A = *this;
+ return Quat(A.a*B.a - A.b*B.b - A.c*B.c - A.d*B.d, // quaternion multiplication
+ A.a*B.b + A.b*B.a + A.c*B.d - A.d*B.c,
+ A.a*B.c - A.b*B.d + A.c*B.a + A.d*B.b,
+ A.a*B.d + A.b*B.c - A.c*B.b + A.d*B.a);
+ }
+};
diff --git a/facetracknoir/rotation.h b/facetracknoir/rotation.h
deleted file mode 100644
index 22f35abb..00000000
--- a/facetracknoir/rotation.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef ROTATION_H
-#define ROTATION_H
-#include <cmath>
-// ----------------------------------------------------------------------------
-class RotationType {
-
-public:
- RotationType() : a(1.0),b(0.0),c(0.0),d(0.0) {}
- RotationType(double yaw, double pitch, double roll) { fromEuler(yaw, pitch, roll); }
- RotationType(double a, double b, double c, double d) : a(a),b(b),c(c),d(d) {}
-
- RotationType inv(){ // inverse
- return RotationType(a,-b,-c, -d);
- }
-
-
- // conversions
- // see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
- void fromEuler(double yaw, double pitch, double roll)
- {
-
- double sin_phi = sin(roll/2.0);
- double cos_phi = cos(roll/2.0);
- double sin_the = sin(pitch/2.0);
- double cos_the = cos(pitch/2.0);
- double sin_psi = sin(yaw/2.0);
- double cos_psi = cos(yaw/2.0);
-
- a = cos_phi*cos_the*cos_psi + sin_phi*sin_the*sin_psi;
- b = sin_phi*cos_the*cos_psi - cos_phi*sin_the*sin_psi;
- c = cos_phi*sin_the*cos_psi + sin_phi*cos_the*sin_psi;
- d = cos_phi*cos_the*sin_psi - sin_phi*sin_the*cos_psi;
- }
-
- void toEuler(double& yaw, double& pitch, double& roll) const
- {
- roll = atan2(2.0*(a*b + c*d), 1.0 - 2.0*(b*b + c*c));
- pitch = asin(2.0*(a*c - b*d));
- yaw = atan2(2.0*(a*d + b*c), 1.0 - 2.0*(c*c + d*d));
- }
-
- const RotationType operator*(const RotationType& B) const
- {
- const RotationType& A = *this;
- return RotationType(A.a*B.a - A.b*B.b - A.c*B.c - A.d*B.d, // quaternion multiplication
- A.a*B.b + A.b*B.a + A.c*B.d - A.d*B.c,
- A.a*B.c - A.b*B.d + A.c*B.a + A.d*B.b,
- A.a*B.d + A.b*B.c - A.c*B.b + A.d*B.a);
- }
-
-protected:
- double a,b,c,d; // quaternion coefficients
-};
-
-
-
-#endif //ROTATION_H
diff --git a/facetracknoir/shortcuts.cpp b/facetracknoir/shortcuts.cpp
index 601bbcc6..94c46376 100644
--- a/facetracknoir/shortcuts.cpp
+++ b/facetracknoir/shortcuts.cpp
@@ -9,9 +9,8 @@ KeyboardShortcutDialog::KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *
QPoint offsetpos(100, 100);
this->move(parent->pos() + offsetpos);
- mainApp = ftnoir; // Preserve a pointer to FTNoIR
+ mainApp = ftnoir;
- // Connect Qt signals to member-functions
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
@@ -33,9 +32,6 @@ KeyboardShortcutDialog::KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *
tie_setting(mainApp->s.dingp, ui.ding);
}
-//
-// OK clicked on server-dialog
-//
void KeyboardShortcutDialog::doOK() {
mainApp->b->save();
this->close();
@@ -44,7 +40,7 @@ void KeyboardShortcutDialog::doOK() {
}
void KeyboardShortcutDialog::doCancel() {
- mainApp->b->revert();
+ mainApp->s.b->reload();
close();
}
@@ -112,16 +108,10 @@ static bool isKeyPressed( const Key *key, const BYTE *keystate ) {
ctrl = ( (keystate[DIK_LCONTROL] & 0x80) || (keystate[DIK_RCONTROL] & 0x80) );
alt = ( (keystate[DIK_LALT] & 0x80) || (keystate[DIK_RALT] & 0x80) );
- //
- // If one of the modifiers is needed and not pressed, return false.
- //
if (key->shift && !shift) return false;
if (key->ctrl && !ctrl) return false;
if (key->alt && !alt) return false;
- //
- // All is well!
- //
return true;
}
return false;
diff --git a/facetracknoir/timer.hpp b/facetracknoir/timer.hpp
index e3fa38de..35ccd4cc 100644
--- a/facetracknoir/timer.hpp
+++ b/facetracknoir/timer.hpp
@@ -1,9 +1,8 @@
#pragma once
-#include <time.h>
+#include <ctime>
#if defined (_WIN32)
# include <windows.h>
-# define CLOCK_MONOTONIC 0
-static inline void clock_gettime(int, struct timespec* ts)
+static inline void opentrack_clock_gettime(int, struct timespec* ts)
{
static LARGE_INTEGER freq;
@@ -20,7 +19,7 @@ static inline void clock_gettime(int, struct timespec* ts)
ts->tv_sec = d.QuadPart / 1000000000L;
ts->tv_nsec = d.QuadPart % 1000000000L;
}
-
+# define clock_gettime opentrack_clock_gettime
#else
# if defined(__MACH__)
# define CLOCK_MONOTONIC 0
@@ -54,8 +53,8 @@ public:
long start() {
struct timespec cur;
(void) clock_gettime(CLOCK_MONOTONIC, &cur);
- int ret = conv(cur);
state = cur;
+ int ret = conv(cur);
return ret;
}
long elapsed() {
@@ -63,4 +62,7 @@ public:
(void) clock_gettime(CLOCK_MONOTONIC, &cur);
return conv(cur);
}
+ long elapsed_ms() {
+ return elapsed() / 1000000L;
+ }
};
diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp
index 094264ff..4a80c722 100644
--- a/facetracknoir/tracker.cpp
+++ b/facetracknoir/tracker.cpp
@@ -1,195 +1,167 @@
-/* Copyright (c) 2012-2013 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.
- */
-
-/*
- * this file appeared originally in facetracknoir, was rewritten completely
- * following opentrack fork.
- *
- * originally written by Wim Vriend.
- */
-
-#include "tracker.h"
-#include "facetracknoir.h"
-#include <opencv2/core/core.hpp>
-#include <cmath>
-#include <algorithm>
-
-#if defined(_WIN32)
-# include <windows.h>
-#endif
-
-Tracker::Tracker(FaceTrackNoIR *parent , main_settings& s) :
- mainApp(parent),
- s(s),
- should_quit(false),
- do_center(false),
- enabled(true)
-{
-}
-
-Tracker::~Tracker()
-{
- should_quit = true;
- wait();
-}
-
-static void get_curve(double pos, double& out, THeadPoseDOF& axis) {
- bool altp = (pos < 0) && axis.opts.altp;
- if (altp) {
- out = (axis.opts.invert ? -1 : 1) * axis.curveAlt.getValue(pos);
- axis.curve.setTrackingActive( false );
- axis.curveAlt.setTrackingActive( true );
- }
- else {
- out = (axis.opts.invert ? -1 : 1) * axis.curve.getValue(pos);
- axis.curve.setTrackingActive( true );
- axis.curveAlt.setTrackingActive( false );
- }
- out += axis.opts.zero;
-}
-
-static void t_compensate(double* input, double* output, bool rz)
-{
- const auto H = input[Yaw] * M_PI / -180;
- const auto P = input[Pitch] * M_PI / -180;
- const auto B = input[Roll] * M_PI / 180;
-
- const auto cosH = cos(H);
- const auto sinH = sin(H);
- const auto cosP = cos(P);
- const auto sinP = sin(P);
- const auto cosB = cos(B);
- const auto sinB = sin(B);
-
- double foo[] = {
- cosH * cosB - sinH * sinP * sinB,
- - sinB * cosP,
- sinH * cosB + cosH * sinP * sinB,
- cosH * sinB + sinH * sinP * cosB,
- cosB * cosP,
- sinB * sinH - cosH * sinP * cosB,
- - sinH * cosP,
- - sinP,
- cosH * cosP,
- };
-
- cv::Mat rmat(3, 3, CV_64F, foo);
- const cv::Mat tvec(3, 1, CV_64F, input);
- cv::Mat ret = rmat * tvec;
-
- const int max = !rz ? 3 : 2;
-
- for (int i = 0; i < max; i++)
- output[i] = ret.at<double>(i);
-}
-
-/** QThread run method @override **/
-void Tracker::run() {
- T6DOF offset_camera;
-
- double newpose[6] = {0};
- int sleep_ms = 15;
-
- if (Libraries->pTracker)
- sleep_ms = std::min(sleep_ms, 1000 / Libraries->pTracker->preferredHz());
-
- if (Libraries->pSecondTracker)
- sleep_ms = std::min(sleep_ms, 1000 / Libraries->pSecondTracker->preferredHz());
-
- qDebug() << "tracker Hz:" << 1000 / sleep_ms;
-
-#if defined(_WIN32)
- (void) timeBeginPeriod(1);
-#endif
-
- for (;;)
- {
- t.start();
-
- if (should_quit)
- break;
-
- if (Libraries->pSecondTracker) {
- Libraries->pSecondTracker->GetHeadPoseData(newpose);
- }
-
- if (Libraries->pTracker) {
- Libraries->pTracker->GetHeadPoseData(newpose);
- }
-
- {
- QMutexLocker foo(&mtx);
-
- for (int i = 0; i < 6; i++)
- mainApp->axis(i).headPos = newpose[i];
-
- if (do_center) {
- for (int i = 0; i < 6; i++)
- offset_camera.axes[i] = mainApp->axis(i).headPos;
-
- do_center = false;
-
- if (Libraries->pFilter)
- Libraries->pFilter->reset();
- }
-
- T6DOF target_camera, target_camera2, new_camera;
-
- if (enabled)
- {
- for (int i = 0; i < 6; i++)
- target_camera.axes[i] = mainApp->axis(i).headPos;
-
- target_camera2 = target_camera - offset_camera;
- }
-
- if (Libraries->pFilter) {
- Libraries->pFilter->FilterHeadPoseData(target_camera2.axes, new_camera.axes);
- } else {
- new_camera = target_camera2;
- }
-
- for (int i = 0; i < 6; i++) {
- get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i));
- }
-
- if (mainApp->s.tcomp_p)
- t_compensate(output_camera.axes, output_camera.axes, mainApp->s.tcomp_tz);
-
- if (Libraries->pProtocol) {
- Libraries->pProtocol->sendHeadposeToGame( output_camera.axes ); // degrees & centimeters
- }
- }
-
- const long q = std::max(0L, sleep_ms * 1000L - std::max(0L, t.elapsed()));
-
- usleep(q);
- }
-#if defined(_WIN32)
- (void) timeEndPeriod(1);
-#endif
-
- for (int i = 0; i < 6; i++)
- {
- mainApp->axis(i).curve.setTrackingActive(false);
- mainApp->axis(i).curveAlt.setTrackingActive(false);
- }
-}
-
-void Tracker::getHeadPose( double *data ) {
- QMutexLocker foo(&mtx);
- for (int i = 0; i < 6; i++)
- {
- data[i] = mainApp->axis(i).headPos;
- }
-}
-
-void Tracker::getOutputHeadPose( double *data ) {
- QMutexLocker foo(&mtx);
- for (int i = 0; i < 6; i++)
- data[i] = output_camera.axes[i];
-}
+/* Copyright (c) 2012-2013 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.
+ */
+
+/*
+ * this file appeared originally in facetracknoir, was rewritten completely
+ * following opentrack fork.
+ *
+ * originally written by Wim Vriend.
+ */
+
+#include "./tracker.h"
+#include <opencv2/core/core.hpp>
+#include <cmath>
+#include <algorithm>
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+Tracker::Tracker(main_settings& s, Mappings &m) :
+ s(s),
+ m(m),
+ centerp(false),
+ enabledp(true),
+ should_quit(false)
+{
+}
+
+Tracker::~Tracker()
+{
+ should_quit = true;
+ wait();
+}
+
+void Tracker::get_curve(double pos, double& out, Mapping& axis) {
+ bool altp = (pos < 0) && axis.opts.altp;
+ axis.curve.setTrackingActive( !altp );
+ axis.curveAlt.setTrackingActive( altp );
+ auto& fc = altp ? axis.curveAlt : axis.curve;
+ out = (axis.opts.invert ? -1 : 1) * fc.getValue(pos);
+
+ out += axis.opts.zero;
+}
+
+void Tracker::t_compensate(const double* input, double* output, bool rz)
+{
+ static constexpr double pi = 3.141592653;
+ const auto H = input[Yaw] * pi / -180;
+ const auto P = input[Pitch] * pi / -180;
+ const auto B = input[Roll] * pi / 180;
+
+ const auto cosH = cos(H);
+ const auto sinH = sin(H);
+ const auto cosP = cos(P);
+ const auto sinP = sin(P);
+ const auto cosB = cos(B);
+ const auto sinB = sin(B);
+
+ double foo[] = {
+ cosH * cosB - sinH * sinP * sinB,
+ - sinB * cosP,
+ sinH * cosB + cosH * sinP * sinB,
+ cosH * sinB + sinH * sinP * cosB,
+ cosB * cosP,
+ sinB * sinH - cosH * sinP * cosB,
+ - sinH * cosP,
+ - sinP,
+ cosH * cosP,
+ };
+
+ const cv::Matx33d rmat(foo);
+ const cv::Vec3d tvec(input);
+ const cv::Vec3d ret = rmat * tvec;
+
+ const int max = !rz ? 3 : 2;
+
+ for (int i = 0; i < max; i++)
+ output[i] = ret(i);
+}
+
+void Tracker::run() {
+ Pose pose_offset, unstopped_pose;
+
+ double newpose[6] = {0};
+ const int sleep_ms = 3;
+
+#if defined(_WIN32)
+ (void) timeBeginPeriod(1);
+#endif
+
+ while (!should_quit)
+ {
+ t.start();
+
+ Libraries->pTracker->GetHeadPoseData(newpose);
+
+ Pose final_raw, filtered;
+
+ for (int i = 0; i < 6; i++)
+ {
+ auto& axis = m(i);
+ int k = axis.opts.src;
+ if (k < 0 || k >= 6)
+ continue;
+ // not really raw, after axis remap -sh
+ final_raw(i) = newpose[k];
+ }
+
+ {
+ if (enabledp)
+ unstopped_pose = final_raw;
+
+ if (Libraries->pFilter)
+ Libraries->pFilter->FilterHeadPoseData(unstopped_pose, filtered);
+ else
+ filtered = unstopped_pose;
+
+ if (centerp) {
+ centerp = false;
+ pose_offset = filtered;
+ }
+
+ filtered = filtered & pose_offset;
+
+ for (int i = 0; i < 6; i++)
+ get_curve(filtered(i), filtered(i), m(i));
+ }
+
+ if (s.tcomp_p)
+ t_compensate(filtered, filtered, s.tcomp_tz);
+
+ Libraries->pProtocol->sendHeadposeToGame(filtered);
+
+ {
+ QMutexLocker foo(&mtx);
+ output_pose = filtered;
+ raw_6dof = final_raw;
+ }
+
+ const long q = 1000L * std::max(0L, sleep_ms - t.elapsed_ms());
+ usleep(q);
+ }
+
+#if defined(_WIN32)
+ (void) timeEndPeriod(1);
+#endif
+
+ for (int i = 0; i < 6; i++)
+ {
+ m(i).curve.setTrackingActive(false);
+ m(i).curveAlt.setTrackingActive(false);
+ }
+}
+
+void Tracker::get_raw_and_mapped_poses(double* mapped, double* raw) const {
+ QMutexLocker foo(&const_cast<Tracker&>(*this).mtx);
+ for (int i = 0; i < 6; i++)
+ {
+ raw[i] = raw_6dof(i);
+ mapped[i] = output_pose(i);
+ }
+}
+
diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h
index 46440c32..d65e1cf1 100644
--- a/facetracknoir/tracker.h
+++ b/facetracknoir/tracker.h
@@ -1,102 +1,43 @@
-#ifndef __TRACKER_H__
-#define __TRACKER_H__
+#pragma once
-#include <QThread>
-#include <QMessageBox>
-#include <QLineEdit>
-#include <QPoint>
-#include <QWaitCondition>
-#include <QList>
-#include <QPainterPath>
-#include <QDebug>
-#include <QMutex>
-#include "global-settings.h"
-#include <ftnoir_tracker_base/ftnoir_tracker_types.h>
+#include <atomic>
#include <vector>
-#include <qfunctionconfigurator/functionconfig.h>
-#include "tracker_types.h"
-#include "facetracknoir/main-settings.hpp"
-#include "facetracknoir/options.h"
-#include "facetracknoir/timer.hpp"
-using namespace options;
+#include "./timer.hpp"
+#include "./plugin-support.h"
+#include "./mappings.hpp"
+#include "./pose.hpp"
-class FaceTrackNoIR; // pre-define parent-class to avoid circular includes
+#include "../qfunctionconfigurator/functionconfig.h"
+#include "./main-settings.hpp"
+#include "./options.h"
-class THeadPoseDOF {
-private:
- THeadPoseDOF(const THeadPoseDOF &) = delete;
- THeadPoseDOF& operator=(const THeadPoseDOF&) = delete;
-public:
- THeadPoseDOF(QString primary,
- QString secondary,
- int maxInput1,
- int maxOutput1,
- int maxInput2,
- int maxOutput2,
- axis_opts* opts) :
- headPos(0),
- curve(primary, maxInput1, maxOutput1),
- curveAlt(secondary, maxInput2, maxOutput2),
- opts(*opts)
- {
- QSettings settings("opentrack");
- QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings iniFile( currentFile, QSettings::IniFormat );
- curve.loadSettings(iniFile);
- curveAlt.loadSettings(iniFile);
- }
- volatile double headPos;
- FunctionConfig curve;
- FunctionConfig curveAlt;
- axis_opts& opts;
-};
+#include <QMutex>
+#include <QThread>
class Tracker : protected QThread {
- Q_OBJECT
-
+ Q_OBJECT
private:
- FaceTrackNoIR *mainApp;
QMutex mtx;
main_settings& s;
- volatile bool should_quit;
+ // XXX can be const-cast when functionconfig const-correct -sh 20141004
+ Mappings& m;
Timer t;
-protected:
- void run();
+ Pose output_pose, raw_6dof;
+ std::atomic<bool> centerp;
+ std::atomic<bool> enabledp;
+ std::atomic<bool> should_quit;
+ static void get_curve(double pos, double& out, Mapping& axis);
+ static void t_compensate(const double* input, double* output, bool rz);
+protected:
+ void run() override;
public:
- Tracker( FaceTrackNoIR *parent, main_settings& s);
+ Tracker(main_settings& s, Mappings& m);
~Tracker();
- void getHeadPose(double *data);
- void getOutputHeadPose(double *data);
- volatile bool do_center;
- volatile bool enabled;
-
- T6DOF output_camera;
-
+ void get_raw_and_mapped_poses(double* mapped, double* raw) const;
void start() { QThread::start(); }
+ void toggle_enabled() { enabledp.store(!enabledp.load()); }
+ void center() { centerp.store(!centerp.load()); }
};
-
-class HeadPoseData {
-public:
- THeadPoseDOF* axes[6];
- HeadPoseData(std::vector<axis_opts*> opts)
- {
- axes[TX] = new THeadPoseDOF("tx","tx_alt", 100, 100, 100, 100, opts[TX]);
- axes[TY] = new THeadPoseDOF("ty","ty_alt", 100, 100, 100, 100, opts[TY]);
- axes[TZ] = new THeadPoseDOF("tz","tz_alt", 100, 100, 100, 100, opts[TZ]);
- axes[Yaw] = new THeadPoseDOF("rx", "rx_alt", 180, 180, 180, 180, opts[Yaw]);
- axes[Pitch] = new THeadPoseDOF("ry", "ry_alt", 90, 90, 90, 90, opts[Pitch]);
- axes[Roll] = new THeadPoseDOF("rz", "rz_alt", 180, 180, 180, 180, opts[Roll]);
- }
- ~HeadPoseData()
- {
- for (int i = 0; i < 6; i++)
- {
- delete axes[i];
- }
- }
-};
-
-#endif
diff --git a/facetracknoir/tracker_types.cpp b/facetracknoir/tracker_types.cpp
deleted file mode 100644
index dec4ff81..00000000
--- a/facetracknoir/tracker_types.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "tracker_types.h"
-#include "rotation.h"
-
-#define PI 3.14159265358979323846264
-#define D2R PI/180.0
-#define R2D 180.0/PI
-
-T6DOF operator-(const T6DOF& A, const T6DOF& B)
-{
- RotationType R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R);
- RotationType R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R);
- RotationType R_C = R_A * R_B.inv();
-
- T6DOF C;
- R_C.toEuler(C.axes[Yaw], C.axes[Pitch], C.axes[Roll]);
- C.axes[Yaw] *= R2D;
- C.axes[Pitch] *= R2D;
- C.axes[Roll] *= R2D;
-
- C.axes[TX] = A.axes[TX] - B.axes[TX];
- C.axes[TY] = A.axes[TY] - B.axes[TY];
- C.axes[TZ] = A.axes[TZ] - B.axes[TZ];
- //C.frame_number?
- return C;
-}
-
-T6DOF operator+(const T6DOF& A, const T6DOF& B)
-{
- RotationType R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R);
- RotationType R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R);
- RotationType R_C = R_A * R_B;
-
- T6DOF C;
- R_C.toEuler(C.axes[Yaw], C.axes[Pitch], C.axes[Roll]);
- C.axes[Yaw] *= R2D;
- C.axes[Pitch] *= R2D;
- C.axes[Roll] *= R2D;
-
- C.axes[TX] = A.axes[TX] + B.axes[TX];
- C.axes[TY] = A.axes[TY] + B.axes[TY];
- C.axes[TZ] = A.axes[TZ] + B.axes[TZ];
- //C.frame_number?
- return C;
-}
diff --git a/facetracknoir/tracker_types.h b/facetracknoir/tracker_types.h
deleted file mode 100644
index a367371e..00000000
--- a/facetracknoir/tracker_types.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __TRACKER_TYPES_H__
-#define __TRACKER_TYPES_H__
-
-#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
-
-struct T6DOF {
-public:
- double axes[6];
-
- T6DOF() {
- for (int i = 0; i < 6; i++)
- axes[i] = 0;
- }
-};
-
-T6DOF operator-(const T6DOF& A, const T6DOF& B); // get new pose with respect to reference pose B
-T6DOF operator+(const T6DOF& A, const T6DOF& B); // get new pose with respect to reference pose B^-1
-
-#endif //__TRACKER_TYPES_H__
diff --git a/facetracknoir/uielements/curves.png b/facetracknoir/uielements/curves.png
index fe21fa15..3f953a0a 100644
--- a/facetracknoir/uielements/curves.png
+++ b/facetracknoir/uielements/curves.png
Binary files differ
diff --git a/facetracknoir/uielements/no-feed.png b/facetracknoir/uielements/no-feed.png
new file mode 100644
index 00000000..6494e9c6
--- /dev/null
+++ b/facetracknoir/uielements/no-feed.png
Binary files differ
diff --git a/facetracknoir/version.c b/facetracknoir/version.c
new file mode 100644
index 00000000..0ef4ec14
--- /dev/null
+++ b/facetracknoir/version.c
@@ -0,0 +1,5 @@
+#ifdef IN_VERSION_UNIT
+# define IN_CRAPOLA_COMPILE_UNIT
+volatile const char* opentrack_version = OPENTRACK_VERSION;
+#else
+#endif
diff --git a/freetrackclient/build-msvc.sh b/freetrackclient/build-msvc.sh
new file mode 100644
index 00000000..4fd303a0
--- /dev/null
+++ b/freetrackclient/build-msvc.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+export PATH="/bin:/usr/bin:$PATH"
+
+case "$(uname -s 2>/dev/null)" in
+*CYG*|*MING*|'') wrap= ;;
+*) wrap=wine ;;
+esac
+
+c_src=".\\freetrackclient.c"
+c_bin="..\\facetracknoir\\clientfiles\\freetrackclient.dll"
+opt_link="-nologo -LTCG -SAFESEH:NO -OPT:REF,ICF"
+opt_cl="
+-nologo -arch:SSE2 -fp:fast -EHc -EH- -GL -GR- -GS- -Gw -LD -MT -O1
+-Ob2 -Og -Oi -Ot -Oy -QIfist -volatile:iso -Ze -Fe\"${c_bin}\"
+"
+
+MSVC="VS140COMNTOOLS"
+
+test -z "$MSVC" && {
+ echo "uh-oh, no MSVC" >&2
+ exit 1
+}
+
+sep="\&"
+
+cd "$(dirname "$0")"
+
+$wrap cmd.exe /C $(echo "
+ del /F /Q $c_bin $sep
+ call %${MSVC}%/vsvars32.bat 2>nul >nul $sep
+ cl $opt_cl $c_src -link $opt_link
+ " | tr '\n' ' ')
diff --git a/freetrackclient/freetrackclient.c b/freetrackclient/freetrackclient.c
new file mode 100644
index 00000000..4bc39d67
--- /dev/null
+++ b/freetrackclient/freetrackclient.c
@@ -0,0 +1,114 @@
+/***********************************************************************************
+ * * FTTypes FTTypes contains the specific type definitions for the *
+ * * FreeTrack protocol. *
+ * * It was loosely translated from FTTypes.pas *
+ * * which was created by the FreeTrack-team. *
+ * * *
+ * * Wim Vriend (Developing) *
+ * * Ron Hendriks (Testing and Research) *
+ * * *
+ * * Homepage <http://facetracknoir.sourceforge.net/home/default.htm> *
+ * * *
+ * * This program is distributed in the hope that it will be useful, but *
+ * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+ * * or FITNESS FOR A PARTICULAR PURPOSE. *
+ * * *
+ * * *
+ * * The FreeTrackClient sources were translated from the original Delphi sources *
+ * * created by the FreeTrack developers. *
+ */
+
+#ifndef _MSC_VER
+# warning "expect misnamed symbols"
+#endif
+
+#pragma GCC diagnostic ignored "-Wvariadic-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+#define NP_AXIS_MAX 16383
+
+#include <stdbool.h>
+#include <string.h>
+#include <windows.h>
+
+#include "../ftnoir_protocol_ft/fttypes.h"
+
+#define FT_EXPORT(t) __declspec(dllexport) t __stdcall
+
+#if 0
+# include <stdio.h>
+static FILE *debug_stream = fopen("c:\\FreeTrackClient.log", "a");
+# define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); }
+#else
+#define dbg_report(...) ((void)0)
+#endif
+
+static HANDLE hFTMemMap = 0;
+static FTHeap* ipc_heap = 0;
+static HANDLE ipc_mutex = 0;
+static const char* dllVersion = "1.0.0.0";
+static const char* dllProvider = "FreeTrack";
+
+static bool impl_create_mapping(void)
+{
+ if (ipc_heap != NULL)
+ return true;
+
+ hFTMemMap = CreateFileMappingA(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ sizeof(FTHeap),
+ (LPCSTR) FREETRACK_HEAP);
+
+ if (hFTMemMap == NULL)
+ return (ipc_heap = NULL), false;
+
+ ipc_heap = (FTHeap*) MapViewOfFile(hFTMemMap, FILE_MAP_WRITE, 0, 0, sizeof(FTHeap));
+ ipc_mutex = CreateMutexA(NULL, false, FREETRACK_MUTEX);
+
+ return true;
+}
+
+#pragma comment (linker, "/export:FTGetData")
+FT_EXPORT(bool) FTGetData(FTData* data)
+{
+ if (impl_create_mapping() == false)
+ return false;
+
+ if (ipc_mutex && WaitForSingleObject(ipc_mutex, 16) == WAIT_OBJECT_0) {
+ if (ipc_heap) {
+ if (ipc_heap->data.DataID > (1 << 29))
+ ipc_heap->data.DataID = 0;
+ data->DataID = ipc_heap->data.DataID;
+ }
+ ReleaseMutex(ipc_mutex);
+ }
+ return true;
+}
+
+/*
+// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument.
+// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing).
+// Thanks guys!
+*/
+#pragma comment (linker, "/export:FTReportName")
+FT_EXPORT(void) FTReportName( int name )
+{
+ dbg_report("FTReportName request (ID = %d).\n", name);
+}
+
+#pragma comment (linker, "/export:FTGetDllVersion")
+FT_EXPORT(const char*) FTGetDllVersion(void)
+{
+ dbg_report("FTGetDllVersion request.\n");
+ return dllVersion;
+}
+
+#pragma comment (linker, "/export:FTProvider")
+FT_EXPORT(const char*) FTProvider(void)
+{
+ dbg_report("FTProvider request.\n");
+ return dllProvider;
+}
+
diff --git a/freetrackclient/freetrackclient.cpp b/freetrackclient/freetrackclient.cpp
deleted file mode 100644
index 395f017d..00000000
--- a/freetrackclient/freetrackclient.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/***********************************************************************************
- * * FTTypes FTTypes contains the specific type definitions for the *
- * * FreeTrack protocol. *
- * * It was loosely translated from FTTypes.pas *
- * * which was created by the FreeTrack-team. *
- * * *
- * * Wim Vriend (Developing) *
- * * Ron Hendriks (Testing and Research) *
- * * *
- * * Homepage <http://facetracknoir.sourceforge.net/home/default.htm> *
- * * *
- * * This program is distributed in the hope that it will be useful, but *
- * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
- * * or FITNESS FOR A PARTICULAR PURPOSE. *
- * * *
- * * *
- * * The FreeTrackClient sources were translated from the original Delphi sources *
- * * created by the FreeTrack developers. *
- */
-#define NP_AXIS_MAX 16383
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <windows.h>
-//#include <tchar.h>
-
-#include "ftnoir_protocol_ft/fttypes.h"
-
-#define FT_EXPORT(t) extern "C" __declspec(dllexport) t __stdcall
-
-//
-// Functions to create/open the file-mapping
-// and to destroy it again.
-//
-static float scale2AnalogLimits( float x, float min_x, float max_x );
-static float getDegreesFromRads ( float rads );
-FT_EXPORT(bool) FTCreateMapping(void);
-
-#if 0
-static FILE *debug_stream = fopen("c:\\FreeTrackClient.log", "a");
-#define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); }
-#else
-#define dbg_report(...)
-#endif
-
-//
-// Handles to 'handle' the memory mapping
-//
-static HANDLE hFTMemMap = 0;
-static FTMemMap *pMemData = 0;
-static HANDLE hFTMutex = 0;
-static const char* dllVersion = "1.0.0.0";
-static const char* dllProvider = "FreeTrack";
-
-static unsigned short gameid = 0;
-
-//
-// DllMain gets called, when the DLL is (un)loaded or a process attaches.
-//
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
-#ifdef WIN64
- dbg_report("\n= WIN64 =========================================================================================\n");
-#else
- dbg_report("\n= WIN32 =========================================================================================\n");
-#endif
- dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
- dbg_report("DllMain: Attach request\n");
- DisableThreadLibraryCalls(hinstDLL);
- break;
-
- case DLL_PROCESS_DETACH:
- dbg_report("DllMain: Detach\n");
- dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
- dbg_report("==========================================================================================\n");
- break;
- }
- return TRUE;
-}
-
-/******************************************************************
- * FTGetData (FreeTrackClient.1)
- */
-
-#pragma comment(linker, "/export:FTGetData@4=FTGetData")
-FT_EXPORT(bool) FTGetData(PFreetrackData data)
-{
- static int prevDataID = 0;
- static int dlyTrackingOff = 0;
-
-
-// dbg_report("NP_GetData called.");
- if (FTCreateMapping() == false) return false;
-
- if (hFTMutex && WaitForSingleObject(hFTMutex, 5) == WAIT_OBJECT_0) {
- if (pMemData) {
-
- //
- // When FaceTrackNoIR does not update frames (any more), don't update the data.
- //
- if (prevDataID != pMemData->data.DataID) {
- memcpy(data, &pMemData->data, sizeof(TFreeTrackData));
- dlyTrackingOff = 0;
- }
- else {
- dlyTrackingOff++;
- if (dlyTrackingOff > 20) {
- dlyTrackingOff = 100;
- }
- }
- prevDataID = pMemData->data.DataID;
-
- //
- // Limit the range of DataID
- //
- if (pMemData->data.DataID > 1000) {
- pMemData->data.DataID = 0;
- }
- data->DataID = pMemData->data.DataID;
-
- //
- // Send the ID to FaceTrackNoIR, so it can display the game-name.
- // This could be a FreeTrack-specific ID
- //
- pMemData->GameID = gameid;
- }
- ReleaseMutex(hFTMutex);
- }
- return true;
-}
-
-/******************************************************************
- * FTReportName (FreeTrackClient.2)
- */
-#pragma comment(linker, "/export:FTReportName@4=FTReportName")
-//
-// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument.
-// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing).
-// Thanks guys!
-//
-FT_EXPORT(void) FTReportName( int name )
-{
- dbg_report("FTReportName request (ID = %d).\n", name);
- gameid = name; // They might have really passed the name here... but they didn't!
- return;
-}
-
-/******************************************************************
- * FTGetDllVersion (FreeTrackClient.3)
- */
-#pragma comment(linker, "/export:FTGetDllVersion@0=FTGetDllVersion")
-FT_EXPORT(const char*) FTGetDllVersion(void)
-{
- dbg_report("FTGetDllVersion request.\n");
-
- return dllVersion;
-}
-
-/******************************************************************
- * FTProvider (FreeTrackClient.4)
- */
-#pragma comment(linker, "/export:FTProvider@0=FTProvider")
-FT_EXPORT(const char*) FTProvider(void)
-{
- dbg_report("FTProvider request.\n");
-
- return dllProvider;
-}
-
-//
-// Create a memory-mapping to the Freetrack data.
-// It contains the tracking data, a handle to the main-window and the program-name of the Game!
-//
-//
-FT_EXPORT(bool) FTCreateMapping(void)
-{
- //
- // Memory-mapping already exists!
- //
- if ( pMemData != NULL ) {
- return true;
- }
-
- dbg_report("FTCreateMapping request (pMemData == NULL).\n");
-
- //
- // A FileMapping is used to create 'shared memory' between the FTClient and the FTServer.
- //
- // Try to create a FileMapping to the Shared Memory. This is done to check if it's already there (what
- // may mean the face-tracker program is already running).
- //
- // If one already exists: close it and open the file-mapping to the existing one.
- //
- hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 ,
- sizeof( FTMemMap ),
- (LPCSTR) FT_MM_DATA );
-
- if ( ( hFTMemMap != 0 ) && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) {
- dbg_report("FTCreateMapping: Mapping already exists.\n");
- CloseHandle( hFTMemMap );
- hFTMemMap = 0;
- }
-
- //
- // Create a new FileMapping, Read/Write access
- //
- hFTMemMap = OpenFileMappingA( FILE_MAP_WRITE , false , (LPCSTR) FT_MM_DATA );
- if ( ( hFTMemMap != 0 ) ) {
- dbg_report("FTCreateMapping: Mapping opened.\n");
- pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_WRITE, 0, 0, sizeof( FTMemMap ) );
- hFTMutex = CreateMutexA(NULL, false, FREETRACK_MUTEX);
- }
- else {
- return false;
- }
- return true;
-}
-
-//
-// Destory the FileMapping to the shared memory
-//
-FT_EXPORT(void) FTDestroyMapping(void)
-{
- if ( pMemData != NULL ) {
- UnmapViewOfFile ( pMemData );
- }
-
- CloseHandle( hFTMutex );
- CloseHandle( hFTMemMap );
- pMemData = 0;
- hFTMemMap = 0;
-}
-
-//
-// 4 convenience
-//
-static float getDegreesFromRads ( float rads ) {
- return (rads * 57.295781f);
-}
-
-//
-// Scale the measured value to the TIR values
-//
-static float scale2AnalogLimits( float x, float min_x, float max_x ) {
-double y;
-double local_x;
-
- local_x = x;
- if (local_x > max_x) {
- local_x = max_x;
- }
- if (local_x < min_x) {
- local_x = min_x;
- }
- y = ( NP_AXIS_MAX * local_x ) / max_x;
-
- return (float) y;
-}
diff --git a/freetrackclient/freetrackclient.def b/freetrackclient/freetrackclient.def
deleted file mode 100644
index 155648dd..00000000
--- a/freetrackclient/freetrackclient.def
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBRARY freetrackclient.dll
-EXPORTS
-FTGetData@4 = FTGetData
-FTReportName@4 = FTReportName
-FTGetDllVersion@0 = FTGetDllVersion
-FTProvider@0 = FTProvider
diff --git a/ftnoir_csv/csv.cpp b/ftnoir_csv/csv.cpp
index 66823d24..b59b5083 100644
--- a/ftnoir_csv/csv.cpp
+++ b/ftnoir_csv/csv.cpp
@@ -25,9 +25,9 @@
#define INSIDE_CSV
#include "csv.h"
#include <QTextDecoder>
-#include <QDebug>
#include <QFile>
#include <QCoreApplication>
+#include <QDebug>
CSV::CSV(QIODevice * device)
{
@@ -46,12 +46,10 @@ CSV::CSV(QString &string){
CSV::~CSV()
{
- //delete m_codec;
}
void CSV::setCodec(const char* codecName){
- //delete m_codec;
m_codec = QTextCodec::codecForName(codecName);
}
@@ -59,7 +57,6 @@ QString CSV::readLine(){
QString line;
if(m_string.isNull()){
- //READ DATA FROM DEVICE
if(m_device && m_device->isReadable()){
QTextDecoder dec(m_codec);
m_string = dec.toUnicode(m_device->readAll());
@@ -67,8 +64,6 @@ QString CSV::readLine(){
return QString();
}
}
-
- //PARSE
if((m_pos = m_rx.indexIn(m_string,m_pos)) != -1) {
line = m_rx.cap(1);
m_pos += m_rx.matchedLength();
@@ -111,12 +106,9 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename)
QStringList gameLine;
qDebug() << "getGameData, ID = " << gameID;
- //
- // Open the supported games list, to get the Name.
- //
QFile file(QCoreApplication::applicationDirPath() + "/settings/facetracknoir supported games.csv");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
- return;
+ return;
}
CSV csv(&file);
gameLine = csv.parseLine();
@@ -131,9 +123,6 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename)
//qDebug() << "Column 6: " << gameLine.at(6); // International ID
//qDebug() << "Column 7: " << gameLine.at(7); // FaceTrackNoIR ID
- //
- // If the gameID was found, fill the shared memory
- //
if (gameLine.count() > 6) {
if (gameLine.at(6).compare( gameID, Qt::CaseInsensitive ) == 0) {
QByteArray id = gameLine.at(7).toLatin1();
@@ -172,9 +161,6 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename)
gameLine = csv.parseLine();
}
- //
- // If the gameID was NOT found, fill only the name "Unknown game connected"
- //
qDebug() << "Unknown game connected" << gameID;
file.close();
}
diff --git a/ftnoir_csv/csv.h b/ftnoir_csv/csv.h
index bfbece58..79e1351e 100644
--- a/ftnoir_csv/csv.h
+++ b/ftnoir_csv/csv.h
@@ -1,11 +1,4 @@
-/*dummy CSV reader for QT4*/
-/*version 0.1*/
-/*11.1.2009*/
-#ifndef CSV_H
-#define CSV_H
-
-//#include "myclass_api.h"
-
+#pragma once
#include <QObject>
#include <QStringList>
#include <QIODevice>
@@ -41,5 +34,3 @@ private:
CSV(QIODevice * device);
CSV(QString &string);
};
-
-#endif // CSV_H
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp
index b07290e2..9b7b2cb2 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp
+++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp
@@ -1,72 +1,67 @@
-/* Copyright (c) 2012-2013 Stanislaw Halik
- *
- * 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_filter_accela/ftnoir_filter_accela.h"
-#include <algorithm>
-#include <cmath>
-#include <QDebug>
-#include <QMutexLocker>
-#include "facetracknoir/global-settings.h"
-using namespace std;
-
-FTNoIR_Filter::FTNoIR_Filter() : first_run(true)
-{
-}
-
-static inline double parabola(const double a, const double x, const double dz, const double expt)
-{
- const double sign = x > 0 ? 1 : -1;
- const double a1 = 1./a;
- return a1 * pow(std::max<double>(fabs(x) - dz, 0), expt) * sign;
-}
-
-void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position,
- double *new_camera_position)
-{
- if (first_run)
- {
- for (int i = 0; i < 6; i++)
- {
- for (int j = 0; j < 3; j++)
- last_output[j][i] = target_camera_position[i];
- l.write(target_camera_position, target_camera_position, new_camera_position);
- }
-
- first_run = false;
- return;
- }
-
- if (!l.idempotentp(target_camera_position))
- {
- for (int i=0;i<6;i++)
- {
- const double vec = target_camera_position[i] - last_output[0][i];
- const double vec2 = target_camera_position[i] - last_output[1][i];
- const double vec3 = target_camera_position[i] - last_output[2][i];
- const int sign = vec < 0 ? -1 : 1;
- const double a = i >= 3 ? s.rotation_alpha : s.translation_alpha;
- const double a2 = a * s.second_order_alpha;
- const double a3 = a * s.third_order_alpha;
- const double deadzone = i >= 3 ? s.rot_deadzone : s.trans_deadzone;
- const double velocity =
- parabola(a, vec, deadzone, s.expt) +
- parabola(a2, vec2, deadzone, s.expt) +
- parabola(a3, vec3, deadzone, s.expt);
- const double result = last_output[0][i] + velocity;
- const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i];
- last_output[2][i] = last_output[1][i];
- last_output[1][i] = last_output[0][i];
- last_output[0][i] = done ? target_camera_position[i] : result;
- }
- }
-
- l.write(target_camera_position, last_output[0], new_camera_position);
-}
-
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
-{
- return new FTNoIR_Filter;
-}
+/* Copyright (c) 2012-2013 Stanislaw Halik
+ *
+ * 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_filter_accela/ftnoir_filter_accela.h"
+#include <algorithm>
+#include <cmath>
+#include <QDebug>
+#include <QMutexLocker>
+#include "facetracknoir/plugin-support.h"
+using namespace std;
+
+FTNoIR_Filter::FTNoIR_Filter() : first_run(true)
+{
+}
+
+static inline double parabola(const double a, const double x, const double dz, const double expt)
+{
+ const double sign = x > 0 ? 1 : -1;
+ const double a1 = 1./a;
+ return a1 * pow(std::max<double>(fabs(x) - dz, 0), expt) * sign;
+}
+
+void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position,
+ double *new_camera_position)
+{
+ if (first_run)
+ {
+ for (int i = 0; i < 6; i++)
+ {
+ new_camera_position[i] = target_camera_position[i];
+ for (int j = 0; j < 3; j++)
+ last_output[j][i] = target_camera_position[i];
+ }
+
+ first_run = false;
+ return;
+ }
+
+ for (int i=0;i<6;i++)
+ {
+ const double vec = target_camera_position[i] - last_output[0][i];
+ const double vec2 = target_camera_position[i] - last_output[1][i];
+ const double vec3 = target_camera_position[i] - last_output[2][i];
+ const int sign = vec < 0 ? -1 : 1;
+ const double a = i >= 3 ? s.rotation_alpha : s.translation_alpha;
+ const double a2 = a * s.second_order_alpha;
+ const double a3 = a * s.third_order_alpha;
+ const double deadzone = i >= 3 ? s.rot_deadzone : s.trans_deadzone;
+ const double velocity =
+ parabola(a, vec, deadzone, s.expt) +
+ parabola(a2, vec2, deadzone, s.expt) +
+ parabola(a3, vec3, deadzone, s.expt);
+ const double result = last_output[0][i] + velocity;
+ const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i];
+ last_output[2][i] = last_output[1][i];
+ last_output[1][i] = last_output[0][i];
+ last_output[0][i] = new_camera_position[i] = done ? target_camera_position[i] : result;
+ }
+}
+
+extern "C" OPENTRACK_EXPORT IFilter* GetConstructor()
+{
+ return new FTNoIR_Filter;
+}
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h
index 2187fd01..0a736042 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela.h
+++ b/ftnoir_filter_accela/ftnoir_filter_accela.h
@@ -1,81 +1,79 @@
-#pragma once
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
-#include "ui_ftnoir_accela_filtercontrols.h"
-#include "facetracknoir/global-settings.h"
-#include "facetracknoir/lerp.hpp"
-#include <QMutex>
-
-#define ACCELA_SMOOTHING_ROTATION 60.0
-#define ACCELA_SMOOTHING_TRANSLATION 40.0
-#define ACCELA_SECOND_ORDER_ALPHA 100.0
-#define ACCELA_THIRD_ORDER_ALPHA 180.0
-
-#include <facetracknoir/options.h>
-using namespace options;
-
-struct settings {
- pbundle b;
- value<double> rotation_alpha,
- translation_alpha,
- second_order_alpha,
- third_order_alpha,
- rot_deadzone,
- trans_deadzone,
- expt;
- settings() :
- b(bundle("Accela")),
- rotation_alpha(b, "rotation-alpha", ACCELA_SMOOTHING_ROTATION),
- translation_alpha(b, "translation-alpha", ACCELA_SMOOTHING_TRANSLATION),
- second_order_alpha(b, "second-order-alpha", ACCELA_SECOND_ORDER_ALPHA),
- third_order_alpha(b, "third-order-alpha", ACCELA_THIRD_ORDER_ALPHA),
- rot_deadzone(b, "rotation-deadband", 0),
- trans_deadzone(b, "translation-deadband", 0),
- expt(b, "exponent", 2)
- {}
-};
-
-class FTNoIR_Filter : public IFilter
-{
-public:
- FTNoIR_Filter();
- void FilterHeadPoseData(const double* target_camera_position, double *new_camera_position);
- void reset() {
- first_run = true;
- }
- void receiveSettings() {
- s.b->reload();
- }
-private:
- lerp l;
- settings s;
- bool first_run;
- double last_output[3][6];
-};
-
-class FilterControls: public QWidget, public IFilterDialog
-{
- Q_OBJECT
-public:
- FilterControls();
- void registerFilter(IFilter* filter);
- void unregisterFilter();
-private:
- Ui::AccelaUICFilterControls ui;
- void discard();
- void save();
- FTNoIR_Filter* accela_filter;
- settings s;
-private slots:
- void doOK();
- void doCancel();
-};
-
-class FTNoIR_FilterDll : public Metadata
-{
-public:
- void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk4"); }
- void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk4"); }
- void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk4"); }
-
- void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
-};
+#pragma once
+#include "ui_ftnoir_accela_filtercontrols.h"
+#include "facetracknoir/plugin-api.hpp"
+#include <QMutex>
+
+#define ACCELA_SMOOTHING_ROTATION 60.0
+#define ACCELA_SMOOTHING_TRANSLATION 40.0
+#define ACCELA_SECOND_ORDER_ALPHA 100.0
+#define ACCELA_THIRD_ORDER_ALPHA 180.0
+
+#include <facetracknoir/options.h>
+using namespace options;
+
+struct settings {
+ pbundle b;
+ value<double> rotation_alpha,
+ translation_alpha,
+ second_order_alpha,
+ third_order_alpha,
+ rot_deadzone,
+ trans_deadzone,
+ expt;
+ settings() :
+ b(bundle("Accela")),
+ rotation_alpha(b, "rotation-alpha", ACCELA_SMOOTHING_ROTATION),
+ translation_alpha(b, "translation-alpha", ACCELA_SMOOTHING_TRANSLATION),
+ second_order_alpha(b, "second-order-alpha", ACCELA_SECOND_ORDER_ALPHA),
+ third_order_alpha(b, "third-order-alpha", ACCELA_THIRD_ORDER_ALPHA),
+ rot_deadzone(b, "rotation-deadband", 0),
+ trans_deadzone(b, "translation-deadband", 0),
+ expt(b, "exponent", 2)
+ {}
+};
+
+class FTNoIR_Filter : public IFilter
+{
+public:
+ FTNoIR_Filter();
+ void FilterHeadPoseData(const double* target_camera_position, double *new_camera_position);
+ void reset() {
+ first_run = true;
+ }
+ void receiveSettings() {
+ s.b->reload();
+ }
+
+private:
+ settings s;
+ bool first_run;
+ double last_output[3][6];
+};
+
+class FilterControls: public QWidget, public IFilterDialog
+{
+ Q_OBJECT
+public:
+ FilterControls();
+ void registerFilter(IFilter* filter);
+ void unregisterFilter();
+private:
+ Ui::AccelaUICFilterControls ui;
+ void discard();
+ void save();
+ FTNoIR_Filter* accela_filter;
+ settings s;
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class FTNoIR_FilterDll : public Metadata
+{
+public:
+ void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk4"); }
+ void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk4"); }
+ void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk4"); }
+
+ void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
+};
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp
index ca321891..1520ad6e 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp
+++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp
@@ -3,7 +3,7 @@
#include <QDebug>
#include <algorithm>
#include <QDoubleSpinBox>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FilterControls::FilterControls() :
accela_filter(nullptr)
@@ -43,7 +43,7 @@ void FilterControls::doCancel() {
void FilterControls::discard()
{
- s.b->revert();
+ s.b->reload();
}
void FilterControls::save() {
@@ -52,7 +52,7 @@ void FilterControls::save() {
accela_filter->receiveSettings();
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog()
+extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog()
{
return new FilterControls;
}
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp
index a024e789..65bee314 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp
+++ b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp
@@ -1,7 +1,7 @@
#include "ftnoir_filter_accela.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_FilterDll;
}
diff --git a/ftnoir_filter_base/ftnoir_filter_base.h b/ftnoir_filter_base/ftnoir_filter_base.h
deleted file mode 100644
index fbb0441d..00000000
--- a/ftnoir_filter_base/ftnoir_filter_base.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef FTNOIR_FILTER_BASE_H
-#define FTNOIR_FILTER_BASE_H
-
-#include "ftnoir_filter_base_global.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include <QString>
-#include <QList>
-#include <QFile>
-#include <QCoreApplication>
-#include <QMessageBox>
-#include <QSettings>
-
-struct IFilter
-{
- virtual ~IFilter() = 0;
- virtual void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position) = 0;
- virtual void reset() = 0;
-};
-
-inline IFilter::~IFilter() { }
-
-struct IFilterDialog
-{
- virtual ~IFilterDialog() {}
- virtual void registerFilter(IFilter* tracker) = 0;
- virtual void unregisterFilter() = 0;
-};
-
-#endif // FTNOIR_FILTER_BASE_H
diff --git a/ftnoir_filter_base/ftnoir_filter_base_global.h b/ftnoir_filter_base/ftnoir_filter_base_global.h
deleted file mode 100644
index a1a13315..00000000
--- a/ftnoir_filter_base/ftnoir_filter_base_global.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef FTNOIR_FILTER_BASE_GLOBAL_H
-#define FTNOIR_FILTER_BASE_GLOBAL_H
-
-#include <QtGlobal>
-
-#ifndef OPENTRACK_MAIN
-# if !defined(_MSC_VER)
-# define FTNOIR_FILTER_BASE_EXPORT __attribute__ ((visibility ("default")))
-# else
-# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT
-#endif
-#else
-# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT
-#endif
-
-#endif // FTNOIR_FILTER_BASE_GLOBAL_H
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp
index d3cb2c32..c7169faa 100644
--- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp
+++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp
@@ -1,13 +1,5 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
+/*** Written by Donovan Baarda
+*
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 3 of the License, or (at your *
@@ -23,28 +15,13 @@
* *
********************************************************************************/
#include "ftnoir_filter_ewma2.h"
-#include "math.h"
+#include <cmath>
#include <QDebug>
#include <QWidget>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
#include <algorithm>
#include <QMutexLocker>
-///////////////////////////////////////////////////////////////////////////////
-//
-// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter
-//
-// This filter tries to adjust the amount of filtering to minimize lag when
-// moving, and minimize noise when still. It uses the delta filtered over the
-// last 3 frames (0.1secs) compared to the delta's average noise variance over
-// the last 3600 frames (~2mins) to try and detect movement vs noise. As the
-// delta increases from 0->3 stdevs of the noise, the filtering scales down
-// from maxSmooth->minSmooth at a rate controlled by the powCurve setting.
-//
-// Written by Donovan Baarda
-//
-///////////////////////////////////////////////////////////////////////////////
-
FTNoIR_Filter::FTNoIR_Filter() :
first_run(true),
// Deltas are smoothed over the last 3 frames (0.1sec at 30fps).
@@ -64,46 +41,57 @@ void FTNoIR_Filter::FilterHeadPoseData(const double *target_camera_position,
{
double new_delta, new_noise, norm_noise;
double alpha;
- double pos[6];
//On the first run, initialize to output=target and return.
if (first_run==true) {
for (int i=0;i<6;i++) {
+ new_camera_position[i] = target_camera_position[i];
+ current_camera_position[i] = target_camera_position[i];
delta[i] = 0.0;
noise[i] = 0.0;
- l.write(target_camera_position, target_camera_position, new_camera_position);
}
first_run=false;
return;
}
- if (!l.idempotentp(target_camera_position))
+ bool new_frame = false;
+
+ for (int i = 0; i < 6; i++)
{
- double cur[6];
- l.get_state(cur);
- // Calculate the new camera position.
- for (int i=0;i<6;i++) {
- // Calculate the current and smoothed delta.
- new_delta = target_camera_position[i]-cur[i];
- delta[i] = delta_smoothing*new_delta + (1.0-delta_smoothing)*delta[i];
- // Calculate the current and smoothed noise variance.
- new_noise = delta[i]*delta[i];
- noise[i] = noise_smoothing*new_noise + (1.0-noise_smoothing)*noise[i];
- // Normalise the noise between 0->1 for 0->9 variances (0->3 stddevs).
- norm_noise = std::min<double>(new_noise/(9.0*noise[i]), 1.0);
- // Calculate the alpha from the normalized noise.
- // TODO(abo): change kSmoothingScaleCurve to a float where 1.0 is sqrt(norm_noise).
- alpha = 1.0/(s.kMinSmoothing+(1.0-pow(norm_noise,s.kSmoothingScaleCurve/20.0))*(s.kMaxSmoothing-s.kMinSmoothing));
- // Update the current camera position to the new position.
- double value = alpha*target_camera_position[i] + (1.0-alpha)*cur[i];
- pos[i] = value;
+ if (target_camera_position[i] != current_camera_position[i])
+ {
+ new_frame = true;
+ break;
}
}
- l.write(target_camera_position, pos, new_camera_position);
+ if (!new_frame)
+ {
+ for (int i = 0; i < 6; i++)
+ new_camera_position[i] = current_camera_position[i];
+ return;
+ }
+
+ // Calculate the new camera position.
+ for (int i=0;i<6;i++) {
+ // Calculate the current and smoothed delta.
+ new_delta = target_camera_position[i]-current_camera_position[i];
+ delta[i] = delta_smoothing*new_delta + (1.0-delta_smoothing)*delta[i];
+ // Calculate the current and smoothed noise variance.
+ new_noise = delta[i]*delta[i];
+ noise[i] = noise_smoothing*new_noise + (1.0-noise_smoothing)*noise[i];
+ // Normalise the noise between 0->1 for 0->9 variances (0->3 stddevs).
+ norm_noise = std::min<double>(new_noise/(9.0*noise[i]), 1.0);
+ // Calculate the alpha from the normalized noise.
+ // TODO(abo): change kSmoothingScaleCurve to a float where 1.0 is sqrt(norm_noise).
+ alpha = 1.0/(s.kMinSmoothing+(1.0-pow(norm_noise,s.kSmoothingScaleCurve/20.0))*(s.kMaxSmoothing-s.kMinSmoothing));
+ // Update the current camera position to the new position.
+ double pos = alpha*target_camera_position[i] + (1.0-alpha)*current_camera_position[i];
+ new_camera_position[i] = current_camera_position[i] = pos;
+ }
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IFilter* GetConstructor()
{
return new FTNoIR_Filter;
}
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h
index ea25a135..8863348c 100644
--- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h
+++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h
@@ -1,38 +1,10 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#pragma once
-#ifndef INCLUDED_FTN_FILTER_H
-#define INCLUDED_FTN_FILTER_H
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "ui_ftnoir_ewma_filtercontrols.h"
#include <QWidget>
#include <QMutex>
#include "facetracknoir/options.h"
-#include "facetracknoir/lerp.hpp"
using namespace options;
struct settings {
@@ -62,8 +34,8 @@ private:
double noise_smoothing;
double delta[6];
double noise[6];
+ double current_camera_position[6];
settings s;
- lerp l;
};
class FilterControls: public QWidget, public IFilterDialog
@@ -93,6 +65,3 @@ public:
void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Exponentially Weighted Moving Average filter with dynamic smoothing parameter"); }
void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
};
-
-#endif //INCLUDED_FTN_FILTER_H
-//END
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp
index fb02354e..b6bde553 100644
--- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp
+++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp
@@ -1,31 +1,7 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#include "ftnoir_filter_ewma2.h"
#include <cmath>
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
#include "ui_ftnoir_ewma_filtercontrols.h"
FilterControls::FilterControls() :
@@ -57,7 +33,7 @@ void FilterControls::doOK() {
}
void FilterControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
@@ -67,7 +43,7 @@ void FilterControls::save() {
pFilter->receiveSettings();
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog( )
{
return new FilterControls;
}
diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp
index 6ef7768e..5ec6138a 100644
--- a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp
+++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp
@@ -1,31 +1,7 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#include "ftnoir_filter_ewma2.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_FilterDll;
}
diff --git a/ftnoir_filter_kalman/ftnoir_filter_kalman.h b/ftnoir_filter_kalman/ftnoir_filter_kalman.h
index 363b8cd4..558aebd6 100644..100755
--- a/ftnoir_filter_kalman/ftnoir_filter_kalman.h
+++ b/ftnoir_filter_kalman/ftnoir_filter_kalman.h
@@ -8,29 +8,24 @@
#ifndef INCLUDED_FTN_FILTER_H
#define INCLUDED_FTN_FILTER_H
-#undef FTNOIR_TRACKER_BASE_LIB
-#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT
-
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
#include "ui_ftnoir_kalman_filtercontrols.h"
-#include "facetracknoir/global-settings.h"
-#include <opencv2/opencv.hpp>
+#include "facetracknoir/plugin-api.hpp"
+#include <opencv2/core/core.hpp>
+#include <opencv2/video/video.hpp>
#include <vector>
#include <QString>
-#include <QIcon>
-#include <QWidget>
#include <QElapsedTimer>
-#include <QObject>
+#include <QWidget>
#include "facetracknoir/options.h"
using namespace options;
-class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter
+class OPENTRACK_EXPORT FTNoIR_Filter : public IFilter
{
public:
FTNoIR_Filter();
- void reset() virt_override;
+ void reset();
void FilterHeadPoseData(const double *target_camera_position,
- double *new_camera_position) virt_override;
+ double *new_camera_position);
double accel_variance;
double noise_variance;
cv::KalmanFilter kalman;
@@ -38,7 +33,7 @@ public:
QElapsedTimer timer;
};
-class FTNOIR_FILTER_BASE_EXPORT FTNoIR_FilterDll : public Metadata
+class OPENTRACK_EXPORT FTNoIR_FilterDll : public Metadata
{
public:
void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Kalman filter"); }
@@ -47,7 +42,7 @@ public:
void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
};
-class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog
+class OPENTRACK_EXPORT FilterControls: public QWidget, public IFilterDialog
{
Q_OBJECT
public:
@@ -58,8 +53,8 @@ public:
show();
}
Ui::KalmanUICFilterControls ui;
- virtual void registerFilter(IFilter*) virt_override {}
- virtual void unregisterFilter() virt_override {}
+ void registerFilter(IFilter*) override {}
+ void unregisterFilter() override {}
public slots:
void doOK();
void doCancel();
diff --git a/ftnoir_filter_kalman/kalman.cpp b/ftnoir_filter_kalman/kalman.cpp
index 388390f3..62d5ff98 100644
--- a/ftnoir_filter_kalman/kalman.cpp
+++ b/ftnoir_filter_kalman/kalman.cpp
@@ -5,9 +5,9 @@
* copyright notice and this permission notice appear in all copies.
*/
#include "ftnoir_filter_kalman.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
#include <QDebug>
-#include <math.h>
+#include <cmath>
FTNoIR_Filter::FTNoIR_Filter() {
reset();
@@ -118,16 +118,16 @@ void FilterControls::doCancel() {
close();
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_FilterDll;
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IFilter* GetConstructor()
{
return new FTNoIR_Filter;
}
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog() {
+extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog() {
return new FilterControls;
}
diff --git a/ftnoir_posewidget/glwidget.h b/ftnoir_posewidget/glwidget.h
index c4b2e09d..91536336 100644
--- a/ftnoir_posewidget/glwidget.h
+++ b/ftnoir_posewidget/glwidget.h
@@ -5,12 +5,11 @@
* copyright notice and this permission notice appear in all copies.
*/
-#ifndef GLWIDGET_H
-#define GLWIDGET_H
+#pragma once
#include <QtGui>
#include <QPixmap>
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
+#include "facetracknoir/plugin-api.hpp"
struct Point {
Point(int x, int y) :
@@ -48,7 +47,7 @@ struct Vec2f {
}
};
-class FTNOIR_TRACKER_BASE_EXPORT GLWidget : public QWidget
+class OPENTRACK_EXPORT GLWidget : public QWidget
{
Q_OBJECT
@@ -56,10 +55,8 @@ public:
GLWidget(QWidget *parent);
~GLWidget();
void rotateBy(double xAngle, double yAngle, double zAngle);
-
protected:
- void paintEvent ( QPaintEvent * event );
-
+ void paintEvent ( QPaintEvent * event ) override;
private:
Point project(const Vec3f& point) {
Point rect;
@@ -93,5 +90,3 @@ private:
QImage back;
QImage texture;
};
-
-#endif
diff --git a/ftnoir_protocol_base/ftnoir_protocol_base.h b/ftnoir_protocol_base/ftnoir_protocol_base.h
deleted file mode 100644
index d2f85ec0..00000000
--- a/ftnoir_protocol_base/ftnoir_protocol_base.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of the some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2010 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* This class implements a tracker-base *
-*********************************************************************************/
-/*
- Modifications (last one on top):
-
- 20121115 - WVR: Added RegisterProtocol() and unRegisterProtocol() to Dialog Class
- 20110415 - WVR: Added overloaded operator - and -=
-*/
-
-#ifndef FTNOIR_PROTOCOL_BASE_H
-#define FTNOIR_PROTOCOL_BASE_H
-
-#include "ftnoir_protocol_base_global.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
-#include <QWidget>
-#include <QFrame>
-
-struct IProtocol
-{
- virtual ~IProtocol() = 0;
- virtual bool checkServerInstallationOK() = 0;
- virtual void sendHeadposeToGame( const double* headpose ) = 0;
- virtual QString getGameName() = 0;
-};
-
-inline IProtocol::~IProtocol() { }
-
-struct IProtocolDialog
-{
- virtual ~IProtocolDialog() {}
- virtual void registerProtocol(IProtocol *protocol) = 0;
- virtual void unRegisterProtocol() = 0;
-};
-
-#endif // FTNOIR_PROTOCOL_BASE_H
diff --git a/ftnoir_protocol_base/ftnoir_protocol_base_global.h b/ftnoir_protocol_base/ftnoir_protocol_base_global.h
deleted file mode 100644
index 06386c7f..00000000
--- a/ftnoir_protocol_base/ftnoir_protocol_base_global.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H
-#define FTNOIR_PROTOCOL_BASE_GLOBAL_H
-
-#include <QtGlobal>
-
-#ifndef OPENTRACK_MAIN
-# if !defined(_MSC_VER)
-# define FTNOIR_PROTOCOL_BASE_EXPORT __attribute__ ((visibility ("default")))
-# else
-# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT
-#endif
-#else
-# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT
-#endif
-
-#endif // FTNOIR_PROTOCOL_BASE_GLOBAL_H
diff --git a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui
index a4092c05..575549d6 100644
--- a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui
+++ b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui
@@ -1,143 +1,143 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFGControls</class>
- <widget class="QWidget" name="UICFGControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>415</width>
- <height>112</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>FlightGear protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="../ftnoir_filter_ewma2/ewma-filter.qrc">
- <normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>IP-address remote PC</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="spinIPFirstNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QSpinBox" name="spinIPSecondNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QSpinBox" name="spinIPThirdNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QSpinBox" name="spinIPFourthNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>1000</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- <item row="2" column="2" colspan="3">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinIPFirstNibble</tabstop>
- <tabstop>spinIPSecondNibble</tabstop>
- <tabstop>spinIPThirdNibble</tabstop>
- <tabstop>spinIPFourthNibble</tabstop>
- <tabstop>spinPortNumber</tabstop>
- </tabstops>
- <resources>
- <include location="../ftnoir_filter_ewma2/ewma-filter.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFGControls</class>
+ <widget class="QWidget" name="UICFGControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>415</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>FlightGear protocol settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="../ftnoir_filter_ewma2/ewma-filter.qrc">
+ <normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>IP-address remote PC</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="spinIPFirstNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QSpinBox" name="spinIPSecondNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QSpinBox" name="spinIPThirdNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QSpinBox" name="spinIPFourthNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Port-number</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="spinPortNumber">
+ <property name="minimum">
+ <number>1000</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="3">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinIPFirstNibble</tabstop>
+ <tabstop>spinIPSecondNibble</tabstop>
+ <tabstop>spinIPThirdNibble</tabstop>
+ <tabstop>spinIPFourthNibble</tabstop>
+ <tabstop>spinPortNumber</tabstop>
+ </tabstops>
+ <resources>
+ <include location="../ftnoir_filter_ewma2/ewma-filter.qrc"/>
+ </resources>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp
index 0ef6b50f..b2d29118 100644
--- a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp
+++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp
@@ -26,8 +26,7 @@
* It is based on the (Linux) example made by Melchior FRANZ. *
********************************************************************************/
#include "ftnoir_protocol_fg.h"
-#include "facetracknoir/global-settings.h"
-#include <ftnoir_tracker_base/ftnoir_tracker_types.h>
+#include "facetracknoir/plugin-api.hpp"
// For Todd and Arda Kutlu
@@ -58,7 +57,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return outSocket.bind(QHostAddress::Any, 0, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.h b/ftnoir_protocol_fg/ftnoir_protocol_fg.h
index dca1f245..4b25a3e1 100644
--- a/ftnoir_protocol_fg/ftnoir_protocol_fg.h
+++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.h
@@ -26,13 +26,12 @@
* It is based on the (Linux) example made by Melchior FRANZ. *
********************************************************************************/
#pragma once
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
#include "ui_ftnoir_fgcontrols.h"
#include "fgtypes.h"
#include <QThread>
#include <QUdpSocket>
#include <QMessageBox>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "facetracknoir/options.h"
using namespace options;
diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp
index 1c3e5ef8..0074a64a 100644
--- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp
+++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp
@@ -28,7 +28,7 @@
#include "ftnoir_protocol_fg.h"
#include <QObject>
#include <QFile>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
//*******************************************************************************************************
// FaceTrackNoIR Client Settings-dialog.
@@ -59,11 +59,11 @@ void FGControls::doOK() {
}
void FGControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new FGControls;
}
diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp
index 3125f136..f830f8f7 100644
--- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp
+++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp
@@ -24,9 +24,9 @@
********************************************************************************/
#include "ftnoir_protocol_fg.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui
index 6cb066bd..637e4dba 100644
--- a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui
+++ b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui
@@ -1,134 +1,134 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFSUIPCControls</class>
- <widget class="QWidget" name="UICFSUIPCControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>512</width>
- <height>100</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>FSUIPC settings FaceTrackNoIR</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="1">
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="txtLocationOfDLL">
- <property name="minimumSize">
- <size>
- <width>230</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Location of FSUIPC.dll</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="text">
- <string>Location of FSUIPC.dll</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>The DLL should be located in the Modules/ directory of MS FS 2004</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="btnFindDLL">
- <property name="maximumSize">
- <size>
- <width>35</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFSUIPCControls</class>
+ <widget class="QWidget" name="UICFSUIPCControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>512</width>
+ <height>100</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>FSUIPC settings FaceTrackNoIR</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="txtLocationOfDLL">
+ <property name="minimumSize">
+ <size>
+ <width>230</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Location of FSUIPC.dll</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="text">
+ <string>Location of FSUIPC.dll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>The DLL should be located in the Modules/ directory of MS FS 2004</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="btnOK">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="btnFindDLL">
+ <property name="maximumSize">
+ <size>
+ <width>35</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp
index 632d502a..822cdb4d 100644
--- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp
+++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp
@@ -25,9 +25,8 @@
* to games, using the FSUIPC.dll. *
********************************************************************************/
#include "ftnoir_protocol_fsuipc.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-/** constructor **/
FTNoIR_Protocol::FTNoIR_Protocol()
{
prevPosX = 0.0f;
@@ -43,9 +42,6 @@ FTNoIR_Protocol::~FTNoIR_Protocol()
FSUIPCLib.unload();
}
-//
-// Scale the measured value to the Joystick values
-//
int FTNoIR_Protocol::scale2AnalogLimits( float x, float min_x, float max_x ) {
double y;
double local_x;
@@ -162,7 +158,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return true;
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT FTNoIR_Protocol* CALLING_CONVENTION GetConstructor(void)
+extern "C" OPENTRACK_EXPORT FTNoIR_Protocol* GetConstructor(void)
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h
index ff8d3b7f..bde16d8f 100644
--- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h
+++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h
@@ -31,8 +31,7 @@
#include <windows.h>
#include <stdlib.h>
#include "FSUIPC_User.h"
-#include "facetracknoir/global-settings.h"
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
+#include "facetracknoir/plugin-api.hpp"
#include "ui_ftnoir_fsuipccontrols.h"
#include <QMessageBox>
#include <QSettings>
@@ -67,7 +66,7 @@ class FTNoIR_Protocol : public IProtocol
{
public:
FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol() virt_override;
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK();
void sendHeadposeToGame(const double* headpose);
QString getGameName() {
diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp
index d97cff99..ceabeabf 100644
--- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp
+++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp
@@ -23,7 +23,7 @@
* *
********************************************************************************/
#include "ftnoir_protocol_fsuipc.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FSUIPCControls::FSUIPCControls() :
QWidget()
@@ -42,7 +42,7 @@ void FSUIPCControls::doOK() {
}
void FSUIPCControls::doCancel() {
- s.b->revert();
+ s.b->reload();
close();
}
@@ -56,7 +56,7 @@ void FSUIPCControls::getLocationOfDLL()
}
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog(void)
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog(void)
{
return new FSUIPCControls;
}
diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp
index 57b174c5..dbea2c46 100644
--- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp
+++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp
@@ -23,9 +23,9 @@
* *
********************************************************************************/
#include "ftnoir_protocol_fsuipc.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata(void)
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata(void)
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui
index 941aaff0..5356d2e5 100644
--- a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui
+++ b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui
@@ -1,223 +1,182 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTControls</class>
- <widget class="QWidget" name="UICFTControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>489</width>
- <height>402</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="windowTitle">
- <string>freetrack protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="ft-protocol.qrc">
- <normaloff>:/images/freetrack.png</normaloff>:/images/freetrack.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>TIRViews</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <item row="0" column="0">
- <widget class="QCheckBox" name="chkTIRViews">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Memory hacks</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Only for very old and buggy old games such as CFS3.</string>
- </property>
- <property name="scaledContents">
- <bool>false</bool>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>TrackIR.exe</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_3">
- <item row="0" column="0">
- <widget class="QCheckBox" name="chkStartDummy">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Using EZCA</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>FSX-specific EZCA protocol hacks</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Select interface</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QComboBox" name="cbxSelectInterface"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Disable one of the protocols if game is confused by presence of both at the same time.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QGroupBox" name="groupBox_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Repair NPClient location</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QPushButton" name="bntLocateNPClient">
- <property name="text">
- <string>Locate DLL</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources>
- <include location="ft-protocol.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFTControls</class>
+ <widget class="QWidget" name="UICFTControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>422</width>
+ <height>305</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="windowTitle">
+ <string>freetrack protocol settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="ft-protocol.qrc">
+ <normaloff>:/images/freetrack.png</normaloff>:/images/freetrack.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>TIRViews</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="chkTIRViews">
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Memory hacks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Only for very old and buggy old games such as CFS3.</string>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Repair NPClient location</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="bntLocateNPClient">
+ <property name="text">
+ <string>Locate DLL</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Select interface</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QComboBox" name="cbxSelectInterface"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Disable one of the protocols if game is confused by presence of both at the same time.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="ft-protocol.qrc"/>
+ </resources>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp
index 281af6a0..ae23be3c 100644
--- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp
+++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp
@@ -28,9 +28,9 @@
#include "ftnoir_csv/csv.h"
FTNoIR_Protocol::FTNoIR_Protocol() :
- shm(FT_MM_DATA, FREETRACK_MUTEX, sizeof(FTMemMap))
+ shm(FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap))
{
- pMemData = (FTMemMap*) shm.mem;
+ pMemData = (FTHeap*) shm.ptr();
ProgramName = "";
intGameID = 0;
viewsStart = 0;
@@ -49,50 +49,30 @@ FTNoIR_Protocol::~FTNoIR_Protocol()
}
void FTNoIR_Protocol::sendHeadposeToGame(const double* headpose) {
- float virtPosX;
- float virtPosY;
- float virtPosZ;
-
- float virtRotX;
- float virtRotY;
- float virtRotZ;
-
- float headPosX;
- float headPosY;
- float headPosZ;
-
- float headRotX;
- float headRotY;
- float headRotZ;
- headRotX = virtRotX = getRadsFromDegrees(headpose[Pitch]) * (s.useDummyExe ? 2.0 : 1.0);
- headRotY = virtRotY = getRadsFromDegrees(headpose[Yaw]);
- headRotZ = virtRotZ = getRadsFromDegrees(headpose[Roll]);
- headPosX = virtPosX = headpose[TX] * 10;
- headPosY = virtPosY = headpose[TY] * 10;
- headPosZ = virtPosZ = headpose[TZ] * 10;
+ float yaw = getRadsFromDegrees(headpose[Yaw]);
+ float pitch = getRadsFromDegrees(headpose[Pitch]);
+ float roll = getRadsFromDegrees(headpose[Roll]);
+ float tx = headpose[TX] * 10.f;
+ float ty = headpose[TY] * 10.f;
+ float tz = headpose[TZ] * 10.f;
shm.lock();
- pMemData->data.RawX = headPosX;
- pMemData->data.RawY = headPosY;
- pMemData->data.RawZ = headPosZ;
- pMemData->data.RawPitch = headRotX;
- pMemData->data.RawYaw = headRotY;
- pMemData->data.RawRoll = headRotZ;
-
- //
- //
- pMemData->data.X = virtPosX;
- pMemData->data.Y = virtPosY;
- pMemData->data.Z = virtPosZ;
- pMemData->data.Pitch = virtRotX;
- pMemData->data.Yaw = virtRotY;
- pMemData->data.Roll = virtRotZ;
-
- //
- // Leave some values 0 yet...
- //
- pMemData->data.X1 = pMemData->data.DataID + 10;
+ pMemData->data.RawX = 0;
+ pMemData->data.RawY = 0;
+ pMemData->data.RawZ = 0;
+ pMemData->data.RawPitch = 0;
+ pMemData->data.RawYaw = 0;
+ pMemData->data.RawRoll = 0;
+
+ pMemData->data.X = tx;
+ pMemData->data.Y = ty;
+ pMemData->data.Z = tz;
+ pMemData->data.Yaw = yaw;
+ pMemData->data.Pitch = pitch;
+ pMemData->data.Roll = roll;
+
+ pMemData->data.X1 = ++pMemData->data.DataID;
pMemData->data.X2 = 0;
pMemData->data.X3 = 0;
pMemData->data.X4 = 0;
@@ -146,28 +126,18 @@ void FTNoIR_Protocol::start_dummy() {
QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe";
dummyTrackIR.setProgram("\"" + program + "\"");
dummyTrackIR.start();
-
- qDebug() << "FTServer::run() says: TrackIR.exe executed!" << program;
}
bool FTNoIR_Protocol::checkServerInstallationOK()
{
QSettings settings("Freetrack", "FreetrackClient"); // Registry settings (in HK_USER)
QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER)
- QString aLocation; // Location of Client DLL
-
if (!shm.success())
return false;
- qDebug() << "checkServerInstallationOK says: Starting Function";
+ QString aLocation = QCoreApplication::applicationDirPath() + "/";
- //
- // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s).
- //
- aLocation = QCoreApplication::applicationDirPath() + "/";
-
- qDebug() << "checkServerInstallationOK says: used interface = " << s.intUsedInterface;
switch (s.intUsedInterface) {
case 0: // Use both interfaces
settings.setValue( "Path" , aLocation );
@@ -182,13 +152,9 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
settingsTIR.setValue( "Path" , aLocation );
break;
default:
- // should never be reached
- break;
+ break;
}
- //
- // TIRViews must be started first, or the NPClient DLL will never be loaded.
- //
if (s.useTIRViews) {
start_tirviews();
}
@@ -205,7 +171,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return true;
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.h b/ftnoir_protocol_ft/ftnoir_protocol_ft.h
index 0af9ff07..5a9e5cdd 100644
--- a/ftnoir_protocol_ft/ftnoir_protocol_ft.h
+++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.h
@@ -25,10 +25,8 @@
* to games, using the FreeTrackClient.dll. *
********************************************************************************/
#pragma once
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
#include "ui_ftnoir_ftcontrols.h"
-#include "facetracknoir/global-settings.h"
-#include "fttypes.h"
+#include "facetracknoir/plugin-api.hpp"
#include <QMessageBox>
#include <QSettings>
#include <QLibrary>
@@ -36,34 +34,32 @@
#include <QDebug>
#include <QFile>
#include <QString>
-#include <windows.h>
#include <QMutex>
#include <QMutexLocker>
#include "compat/compat.h"
#include "facetracknoir/options.h"
+#include "fttypes.h"
using namespace options;
struct settings {
pbundle b;
value<int> intUsedInterface;
- value<bool> useTIRViews, useDummyExe;
+ value<bool> useTIRViews;
settings() :
b(bundle("proto-freetrack")),
intUsedInterface(b, "used-interfaces", 0),
- useTIRViews(b, "use-memory-hacks", false),
- useDummyExe(b, "ezca-mode", false)
+ useTIRViews(b, "use-memory-hacks", false)
{}
};
-//typedef char *(WINAPI *importProvider)(void);
-typedef void (WINAPI *importTIRViewsStart)(void);
-typedef void (WINAPI *importTIRViewsStop)(void);
+typedef void (__stdcall *importTIRViewsStart)(void);
+typedef void (__stdcall *importTIRViewsStop)(void);
class FTNoIR_Protocol : public IProtocol
{
public:
FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK( );
void sendHeadposeToGame( const double *headpose );
QString getGameName() {
@@ -71,14 +67,13 @@ public:
return connected_game;
}
private:
- importTIRViewsStart viewsStart; // Functions inside TIRViews.dll
+ importTIRViewsStart viewsStart;
importTIRViewsStop viewsStop;
-
- FTMemMap *pMemData;
+
+ FTHeap *pMemData;
QString game_name;
PortableLockedShm shm;
- // Private properties
QString ProgramName;
QLibrary FTIRViewsLib;
QProcess dummyTrackIR;
diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp
index 5ce903b7..3e440607 100644
--- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp
+++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp
@@ -26,26 +26,14 @@
#include <QDebug>
#include <QFileDialog>
-//*******************************************************************************************************
-// FaceTrackNoIR Client Settings-dialog.
-//*******************************************************************************************************
-
-//
-// Constructor for server-settings-dialog
-//
-FTControls::FTControls() :
- QWidget()
+FTControls::FTControls()
{
- QString aFileName; // File Path and Name
-
ui.setupUi( this );
- // Connect Qt signals to member-functions
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL()));
- tie_setting(s.useDummyExe, ui.chkStartDummy);
tie_setting(s.useTIRViews, ui.chkTIRViews);
ui.cbxSelectInterface->addItem("Enable both");
@@ -54,8 +42,8 @@ FTControls::FTControls() :
tie_setting(s.intUsedInterface, ui.cbxSelectInterface);
- aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll";
- if ( !QFile::exists( aFileName ) ) {
+ QFile memhacks_pathname(QCoreApplication::applicationDirPath() + "/TIRViews.dll");
+ if (!memhacks_pathname.exists()) {
ui.chkTIRViews->setChecked( false );
ui.chkTIRViews->setEnabled ( false );
}
@@ -70,27 +58,21 @@ void FTControls::doOK() {
}
void FTControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
void FTControls::selectDLL() {
- QString fileName = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)"));
-
- //
- // Write the location of the file in the required Registry-key.
- //
- if (! fileName.isEmpty() ) {
- if (fileName.endsWith("NPClient.dll", Qt::CaseInsensitive) ) {
- QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER)
- QString aLocation = fileName.left(fileName.length() - 12); // Location of Client DLL
+ QString filename = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)"));
- settingsTIR.setValue( "Path" , aLocation );
- }
+ if (! filename.isEmpty() ) {
+ QSettings node("NaturalPoint", "NATURALPOINT\\NPClient Location");
+ QFileInfo dllname(filename);
+ node.setValue( "Path" , dllname.dir().path() );
}
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog()
{
return new FTControls;
}
diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp
index 38f11211..d7a13fa5 100644
--- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp
+++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp
@@ -1,30 +1,7 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
-#include "ftnoir_protocol_ft.h"
+#include "facetracknoir/plugin-support.h"
+#include "ftnoir_protocol_ft/ftnoir_protocol_ft.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_ft/fttypes.h b/ftnoir_protocol_ft/fttypes.h
index ced844dc..f41350c8 100644
--- a/ftnoir_protocol_ft/fttypes.h
+++ b/ftnoir_protocol_ft/fttypes.h
@@ -16,45 +16,38 @@
* * The FTTypes sources were translated from the original Delphi sources *
* * created by the FreeTrack developers. *
*/
-#ifndef INCLUDED_FTTYPES_H
-#define INCLUDED_FTTYPES_H
-#if !defined(_WIN32)
+#pragma once
+
+#ifndef _MSC_VER
# include <inttypes.h>
-typedef int32_t my_32bit_int;
-# define WINAPI
#else
-# include <windows.h>
-typedef __int32 my_32bit_int;
+typedef unsigned __int32 uint32_t;
#endif
-//#include "Registry.h"
-
-// static const char* FT_CLIENT_LOCATION = "Software\\Freetrack\\FreetrackClient";
-//#define FT_CLIENT_FILENAME "FreeTrackClient.Dll"
-#define FT_MM_DATA "FT_SharedMem"
-//#define FREETRACK "Freetrack"
+#define FREETRACK_HEAP "FT_SharedMem"
#define FREETRACK_MUTEX "FT_Mutext"
-struct TFreeTrackData {
+/* only 6 headpose floats and the data id are filled -sh */
+typedef struct __FTData {
int DataID;
int CamWidth;
int CamHeight;
- // virtual pose
- float Yaw; // positive yaw to the left
- float Pitch; // positive pitch up
- float Roll; // positive roll to the left
+ /* virtual pose */
+ float Yaw; /* positive yaw to the left */
+ float Pitch; /* positive pitch up */
+ float Roll; /* positive roll to the left */
float X;
float Y;
float Z;
- // raw pose with no smoothing, sensitivity, response curve etc.
+ /* raw pose with no smoothing, sensitivity, response curve etc. */
float RawYaw;
float RawPitch;
float RawRoll;
float RawX;
float RawY;
float RawZ;
- // raw points, sorted by Y, origin top left corner
+ /* raw points, sorted by Y, origin top left corner */
float X1;
float Y1;
float X2;
@@ -63,24 +56,13 @@ struct TFreeTrackData {
float Y3;
float X4;
float Y4;
-};
-typedef TFreeTrackData * PFreetrackData;
+} FTData;
-struct FTMemMap {
- TFreeTrackData data;
- my_32bit_int GameID;
- unsigned char table[8];
- my_32bit_int GameID2;
-};
-typedef FTMemMap * PFTMemMap;
+/* we add some shit at the end for other legacy proto, sadly */
-//extern bool (*FTGetData) (PFreetrackData data);
-// DLL function signatures
-// These match those given in FTTypes.pas
-// WINAPI is macro for __stdcall defined somewhere in the depths of windows.h
-typedef bool (WINAPI *importGetData)(TFreeTrackData * data);
-typedef char *(WINAPI *importGetDllVersion)(void);
-typedef void (WINAPI *importReportID)(int name);
-typedef char *(WINAPI *importProvider)(void);
-
-#endif//INCLUDED_FTTYPES_H
+typedef struct __FTHeap {
+ FTData data;
+ int32_t GameID;
+ unsigned char table[8];
+ int32_t GameID2;
+} FTHeap;
diff --git a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui
index 48679f3c..ca811e99 100644
--- a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui
+++ b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui
@@ -1,266 +1,266 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTNControls</class>
- <widget class="QWidget" name="UICFTNControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>411</width>
- <height>169</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>UDP protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="../facetracknoir/main-facetracknoir.qrc">
- <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="4">
- <widget class="QSpinBox" name="spinIPFourthNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinIPFirstNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QSpinBox" name="spinIPSecondNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QSpinBox" name="spinIPThirdNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>IP-address remote PC</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>1000</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Enter IP-address and port-number for the remote PC.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Remember: you may have to change firewall-settings too!</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinIPFirstNibble</tabstop>
- <tabstop>spinIPSecondNibble</tabstop>
- <tabstop>spinIPThirdNibble</tabstop>
- <tabstop>spinIPFourthNibble</tabstop>
- <tabstop>spinPortNumber</tabstop>
- <tabstop>btnOK</tabstop>
- <tabstop>btnCancel</tabstop>
- </tabstops>
- <resources>
- <include location="../facetracknoir/main-facetracknoir.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFTNControls</class>
+ <widget class="QWidget" name="UICFTNControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>411</width>
+ <height>169</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>UDP protocol settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="../facetracknoir/main-facetracknoir.qrc">
+ <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="_vertical_layout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="4">
+ <widget class="QSpinBox" name="spinIPFourthNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="spinIPFirstNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QSpinBox" name="spinIPSecondNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QSpinBox" name="spinIPThirdNibble">
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>IP-address remote PC</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Port-number</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="spinPortNumber">
+ <property name="minimum">
+ <number>1000</number>
+ </property>
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Enter IP-address and port-number for the remote PC.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Remember: you may have to change firewall-settings too!</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinIPFirstNibble</tabstop>
+ <tabstop>spinIPSecondNibble</tabstop>
+ <tabstop>spinIPThirdNibble</tabstop>
+ <tabstop>spinIPFourthNibble</tabstop>
+ <tabstop>spinPortNumber</tabstop>
+ <tabstop>btnOK</tabstop>
+ <tabstop>btnCancel</tabstop>
+ </tabstops>
+ <resources>
+ <include location="../facetracknoir/main-facetracknoir.qrc"/>
+ </resources>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp
index e93a751e..ccff1ba5 100644
--- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp
+++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp
@@ -27,9 +27,8 @@
********************************************************************************/
#include "ftnoir_protocol_ftn.h"
#include <QFile>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-/** constructor **/
FTNoIR_Protocol::FTNoIR_Protocol()
{
}
@@ -49,7 +48,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return outSocket.bind(QHostAddress::Any, 0, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h
index 99e6c6a1..c14a7dba 100644
--- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h
+++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h
@@ -27,14 +27,12 @@
********************************************************************************/
#pragma once
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "ui_ftnoir_ftncontrols.h"
#include <QThread>
#include <QUdpSocket>
#include <QMessageBox>
-#include <math.h>
-#include "facetracknoir/global-settings.h"
+#include <cmath>
+#include "facetracknoir/plugin-api.hpp"
#include "facetracknoir/options.h"
using namespace options;
diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp
index 37db314f..8af12ad7 100644
--- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp
+++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp
@@ -23,7 +23,7 @@
* *
********************************************************************************/
#include "ftnoir_protocol_ftn.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FTNControls::FTNControls() :
QWidget()
@@ -52,11 +52,11 @@ void FTNControls::doOK() {
// Cancel clicked on server-dialog
//
void FTNControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new FTNControls;
}
diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp
index 99689432..0d24ccf8 100644
--- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp
+++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp
@@ -23,9 +23,9 @@
* *
********************************************************************************/
#include "ftnoir_protocol_ftn.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp
index 70fde395..1840fa03 100644
--- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp
+++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp
@@ -1,6 +1,5 @@
#include "ftnoir_protocol_libevdev.h"
-#include "facetracknoir/global-settings.h"
-//#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
+#include "facetracknoir/plugin-api.hpp"
#include <cstdio>
#include <algorithm>
@@ -95,7 +94,7 @@ void FTNoIR_Protocol::sendHeadposeToGame(const double* headpose) {
(void) libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h
index 66f53547..e613885a 100644
--- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h
+++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h
@@ -5,11 +5,10 @@
* copyright notice and this permission notice appear in all copies.
*/
#pragma once
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
#include "ui_ftnoir_libevdev_controls.h"
#include <QMessageBox>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
extern "C" {
# include <libevdev/libevdev.h>
@@ -20,7 +19,7 @@ class FTNoIR_Protocol : public IProtocol
{
public:
FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK() {
return dev != NULL;
}
@@ -33,7 +32,6 @@ private:
struct libevdev_uinput* uidev;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class LibevdevControls: public QWidget, public IProtocolDialog
{
Q_OBJECT
diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp
index bb54c354..d522610b 100644
--- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp
+++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp
@@ -1,5 +1,5 @@
#include "ftnoir_protocol_libevdev.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
LibevdevControls::LibevdevControls() : QWidget()
{
@@ -20,7 +20,7 @@ void LibevdevControls::doCancel() {
void LibevdevControls::save() {
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new LibevdevControls;
}
diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp
index 79a22d5e..e258b077 100644
--- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp
+++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp
@@ -1,6 +1,6 @@
#include "ftnoir_protocol_libevdev.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
}
@@ -10,7 +10,7 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui
index 2705fff7..258ed06a 100644
--- a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui
+++ b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui
@@ -1,205 +1,205 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICMOUSEControls</class>
- <widget class="QWidget" name="UICMOUSEControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>257</width>
- <height>114</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Mouse protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="win32-mouse-protocol.qrc">
- <normaloff>:/images/mouse.png</normaloff>:/images/mouse.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="1">
- <widget class="QComboBox" name="cbxSelectMouse_Y">
- <property name="maximumSize">
- <size>
- <width>80</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="textLabel2_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Map mouse Y to:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel2_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Map mouse X to:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="cbxSelectMouse_X">
- <property name="maximumSize">
- <size>
- <width>80</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources>
- <include location="win32-mouse-protocol.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICMOUSEControls</class>
+ <widget class="QWidget" name="UICMOUSEControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>257</width>
+ <height>114</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Mouse protocol settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="win32-mouse-protocol.qrc">
+ <normaloff>:/images/mouse.png</normaloff>:/images/mouse.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="_vertical_layout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QComboBox" name="cbxSelectMouse_Y">
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Select Number</string>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAlphabetically</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel2_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Map mouse Y to:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="textLabel2_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Map mouse X to:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cbxSelectMouse_X">
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Select Number</string>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAlphabetically</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="win32-mouse-protocol.qrc"/>
+ </resources>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp
index cc8aa11e..47f7a67e 100644
--- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp
+++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp
@@ -27,12 +27,14 @@
* but no face-tracking. *
********************************************************************************/
#include "ftnoir_protocol_mouse.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
void FTNoIR_Protocol::sendHeadposeToGame(const double *headpose ) {
double fMouse_X = 0;
double fMouse_Y = 0;
+ // XXX TODO remove axis selector, use mapping window's
+ // axis selection. Mention in UI axis used. -sh 20140920
int Mouse_X = s.Mouse_X;
int Mouse_Y = s.Mouse_Y;
@@ -61,7 +63,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return true;
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h
index 01f283d3..8f1f3ff1 100644
--- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h
+++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h
@@ -30,7 +30,6 @@
#ifndef INCLUDED_MOUSESERVER_H
#define INCLUDED_MOUSESERVER_H
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
#include "ui_ftnoir_mousecontrols.h"
#include <QMessageBox>
#include <QSettings>
@@ -40,7 +39,7 @@
#include <QFile>
#include <windows.h>
#include <winuser.h>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "facetracknoir/options.h"
using namespace options;
@@ -71,7 +70,6 @@ private:
struct settings s;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class MOUSEControls: public QWidget, public IProtocolDialog
{
Q_OBJECT
@@ -92,9 +90,6 @@ private slots:
void doCancel();
};
-//*******************************************************************************************************
-// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
-//*******************************************************************************************************
class FTNoIR_ProtocolDll : public Metadata
{
public:
diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp
index 22b7024c..efac958c 100644
--- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp
+++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp
@@ -23,7 +23,7 @@
* *
********************************************************************************/
#include "ftnoir_protocol_mouse.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
MOUSEControls::MOUSEControls() : _proto(nullptr)
{
@@ -59,11 +59,11 @@ void MOUSEControls::doOK() {
}
void MOUSEControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new MOUSEControls;
}
diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp
index 54f6b307..39bdf6e5 100644
--- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp
+++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp
@@ -23,9 +23,9 @@
* *
********************************************************************************/
#include "ftnoir_protocol_mouse.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp
index 2714e980..72b800d2 100644
--- a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp
+++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp
@@ -27,7 +27,7 @@
* must be treated as such... *
********************************************************************************/
#include "ftnoir_protocol_sc.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
importSimConnect_CameraSetRelative6DOF FTNoIR_Protocol::simconnect_set6DOF;
HANDLE FTNoIR_Protocol::hSimConnect = 0; // Handle to SimConnect
@@ -79,13 +79,11 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) {
if (!blnSimConnectActive) {
if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) {
- HRESULT hr;
-
simconnect_subscribetosystemevent(hSimConnect, EVENT_PING, "Frame");
- hr = simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, "");
- hr = simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false);
- hr = simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
+ simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, "");
+ simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false);
+ simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
blnSimConnectActive = true;
}
}
@@ -93,6 +91,8 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) {
(void) (simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, NULL));
}
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
class ActivationContext {
public:
ActivationContext(const int resid) {
@@ -103,7 +103,7 @@ public:
actx.lpResourceName = MAKEINTRESOURCEA(resid);
actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
#ifdef _MSC_VER
-# define PREFIX ""
+# error "MSVC support removed"
#else
# define PREFIX "lib"
#endif
@@ -203,7 +203,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK()
return true;
}
-void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext)
+void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD, void *)
{
switch(pData->dwID)
{
@@ -246,7 +246,7 @@ void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData
}
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.h b/ftnoir_protocol_sc/ftnoir_protocol_sc.h
index a13c0097..02cb7b0e 100644
--- a/ftnoir_protocol_sc/ftnoir_protocol_sc.h
+++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.h
@@ -29,7 +29,7 @@
#pragma once
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0502
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
//
// Prevent the SimConnect manifest from being merged in the application-manifest
// This is necessary to run FaceTrackNoIR on a PC without FSX
@@ -38,8 +38,7 @@
#include <windows.h>
#include <SimConnect.h>
-#include <ftnoir_protocol_base/ftnoir_protocol_base.h>
-#include <ui_ftnoir_sccontrols.h>
+#include "ui_ftnoir_sccontrols.h"
#include <QMessageBox>
#include <QSettings>
#include <QLibrary>
@@ -89,7 +88,7 @@ class FTNoIR_Protocol : public IProtocol
{
public:
FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK();
void sendHeadposeToGame(const double* headpose);
QString getGameName() {
@@ -128,13 +127,12 @@ private:
settings s;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class SCControls: public QWidget, public IProtocolDialog
{
Q_OBJECT
public:
SCControls();
- void registerProtocol(IProtocol *protocol) {}
+ void registerProtocol(IProtocol *) {}
void unRegisterProtocol() {}
private:
Ui::UICSCControls ui;
@@ -144,9 +142,6 @@ private slots:
void doCancel();
};
-//*******************************************************************************************************
-// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
-//*******************************************************************************************************
class FTNoIR_ProtocolDll : public Metadata
{
public:
diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp
index c7428d77..c3d64e9d 100644
--- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp
+++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp
@@ -24,7 +24,7 @@
********************************************************************************/
#include "ftnoir_protocol_sc.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
SCControls::SCControls() :
QWidget()
@@ -44,11 +44,11 @@ void SCControls::doOK() {
}
void SCControls::doCancel() {
- s.b->revert();
+ s.b->reload();
close();
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new SCControls;
}
diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp
index 0a52fa96..9bdbef09 100644
--- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp
+++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp
@@ -24,9 +24,9 @@
********************************************************************************/
#include "ftnoir_protocol_sc.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_sc/ftnoir_sccontrols.ui b/ftnoir_protocol_sc/ftnoir_sccontrols.ui
index 87dc8d86..5b2fd291 100644
--- a/ftnoir_protocol_sc/ftnoir_sccontrols.ui
+++ b/ftnoir_protocol_sc/ftnoir_sccontrols.ui
@@ -1,72 +1,72 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICSCControls</class>
- <widget class="QWidget" name="UICSCControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>290</width>
- <height>79</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>SimConnect settings FaceTrackNoIR</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>FSX version</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboBox">
- <item>
- <property name="text">
- <string>SP1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>SP2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Acceleration</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICSCControls</class>
+ <widget class="QWidget" name="UICSCControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>290</width>
+ <height>79</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>SimConnect settings FaceTrackNoIR</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>FSX version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string>SP1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SP2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Acceleration</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp
index a3a5cb5f..58fa2ab1 100644
--- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp
+++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp
@@ -1,22 +1,21 @@
#include "ftnoir_protocol_vjoy.h"
-#include "facetracknoir/global-settings.h"
-#include <ftnoir_tracker_base/ftnoir_tracker_types.h>
+#include "facetracknoir/plugin-api.hpp"
-/** constructor **/
FTNoIR_Protocol::FTNoIR_Protocol()
{
- VJoy_Initialize("", "");
+ static char meh[1] = {0};
+ VJoy_Initialize(meh, meh);
}
-/** destructor **/
FTNoIR_Protocol::~FTNoIR_Protocol()
{
VJoy_Shutdown();
}
void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) {
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
JOYSTICK_STATE state[2] = { 0 };
-
+
state[0].POV = (4 << 12) | (4 << 8) | (4 << 4) | 4;
state[0].XAxis = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[Yaw] * VJOY_AXIS_MAX / 180.0));
@@ -25,11 +24,11 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) {
state[0].XRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TX] * VJOY_AXIS_MAX / 100.0));
state[0].YRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TY] * VJOY_AXIS_MAX / 100.0));
state[0].ZRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TZ] * VJOY_AXIS_MAX / 100.0));
-
+
VJoy_UpdateJoyState(0, state);
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor()
{
return new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h
index 873b4e3c..eac3c610 100644
--- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h
+++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h
@@ -26,15 +26,9 @@
* It is based on the (Linux) example made by Melchior FRANZ. *
********************************************************************************/
#pragma once
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
#include "ui_ftnoir_vjoy_controls.h"
-#include <QThread>
-#include <QUdpSocket>
-#include <QMessageBox>
-#include <QSettings>
-#include <math.h>
-#include "facetracknoir/global-settings.h"
-#include <windows.h>
+#include <cmath>
+#include "facetracknoir/plugin-api.hpp"
#define FT_PROGRAMID "FT_ProgramID"
@@ -42,7 +36,7 @@ class FTNoIR_Protocol : public IProtocol
{
public:
FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK() {
return true;
}
@@ -60,7 +54,7 @@ class VJoyControls: public QWidget, public IProtocolDialog
public:
explicit VJoyControls();
- void registerProtocol(IProtocol *l) {}
+ void registerProtocol(IProtocol *) {}
void unRegisterProtocol() {}
private:
@@ -72,9 +66,6 @@ private slots:
void doCancel();
};
-//*******************************************************************************************************
-// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
-//*******************************************************************************************************
class FTNoIR_ProtocolDll : public Metadata
{
public:
@@ -92,6 +83,8 @@ public:
#define VJOY_AXIS_NIL 0
#define VJOY_AXIS_MAX 32767
+#include <windows.h>
+
#include <pshpack1.h>
typedef struct _JOYSTICK_STATE
@@ -109,17 +102,6 @@ typedef struct _JOYSTICK_STATE
UINT32 Buttons; // 32 Buttons
} JOYSTICK_STATE, * PJOYSTICK_STATE;
-#include <poppack.h>
-
-#undef EXTERN_C
-#if _MSC_VER
-# define EXTERN_C
-#else
-# define EXTERN_C extern "C"
-#endif
-#if _MSC_VER
-# pragma comment(linker, "/implib:vjoy.def")
-#endif
EXTERN_C BOOL __stdcall VJoy_Initialize(PCHAR name, PCHAR serial);
EXTERN_C VOID __stdcall VJoy_Shutdown();
EXTERN_C BOOL __stdcall VJoy_UpdateJoyState(int id, PJOYSTICK_STATE pJoyState);
diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp
index febb7b18..6bd82d9a 100644
--- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp
+++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp
@@ -1,5 +1,5 @@
#include "ftnoir_protocol_vjoy.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
VJoyControls::VJoyControls() : QWidget()
{
@@ -20,7 +20,7 @@ void VJoyControls::doCancel() {
void VJoyControls::save() {
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( )
{
return new VJoyControls;
}
diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp
index 5cb5ef05..367a0df6 100644
--- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp
+++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp
@@ -1,6 +1,6 @@
#include "ftnoir_protocol_vjoy.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
}
@@ -10,7 +10,7 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp
index 58ffe974..29a2a70c 100644
--- a/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp
+++ b/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp
@@ -3,18 +3,17 @@
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
+#include "ftnoir_csv/csv.h"
-/** constructor **/
FTNoIR_Protocol::FTNoIR_Protocol() : lck_shm(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)), shm(NULL), gameid(0)
{
if (lck_shm.success()) {
- shm = (WineSHM*) lck_shm.mem;
+ shm = (WineSHM*) lck_shm.ptr();
memset(shm, 0, sizeof(*shm));
}
wrapper.start("wine", QStringList() << (QCoreApplication::applicationDirPath() + "/opentrack-wrapper-wine.exe.so"));
}
-/** destructor **/
FTNoIR_Protocol::~FTNoIR_Protocol()
{
if (shm) {
@@ -52,25 +51,12 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) {
}
}
-//
-// Check if the Client DLL exists and load it (to test it), if so.
-// Returns 'true' if all seems OK.
-//
bool FTNoIR_Protocol::checkServerInstallationOK()
{
return lck_shm.success();
}
-////////////////////////////////////////////////////////////////////////////////
-// Factory function that creates instances if the Protocol object.
-
-// Export both decorated and undecorated names.
-// GetProtocol - Undecorated name, which can be easily used with GetProcAddress
-// Win32 API function.
-// _GetProtocol@0 - Common name decoration for __stdcall functions in C language.
-//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0")
-
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT void* GetConstructor()
{
return (IProtocol*) new FTNoIR_Protocol;
}
diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine.h b/ftnoir_protocol_wine/ftnoir_protocol_wine.h
index 50d2bc0c..9a7fb7d5 100644
--- a/ftnoir_protocol_wine/ftnoir_protocol_wine.h
+++ b/ftnoir_protocol_wine/ftnoir_protocol_wine.h
@@ -1,36 +1,5 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2010 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-* FTServer FTServer is the Class, that communicates headpose-data *
-* to games, using the FreeTrackClient.dll. *
-********************************************************************************/
#pragma once
-#ifndef INCLUDED_FTSERVER_H
-#define INCLUDED_FTSERVER_H
-#include "ftnoir_protocol_base/ftnoir_protocol_base.h"
-#include "ftnoir_protocol_ft/fttypes.h"
-#include "ftnoir_csv/csv.h"
#include "ui_ftnoir_winecontrols.h"
#include <QMessageBox>
#include <QLibrary>
@@ -39,15 +8,15 @@
#include <QMutex>
#include <QMutexLocker>
#include <QFile>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "compat/compat.h"
#include "ftnoir_protocol_wine/wine-shm.h"
class FTNoIR_Protocol : public IProtocol
{
public:
- FTNoIR_Protocol();
- virtual ~FTNoIR_Protocol();
+ FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
bool checkServerInstallationOK();
void sendHeadposeToGame(const double* headpose);
@@ -64,7 +33,6 @@ private:
QMutex game_name_mutex;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class FTControls: public QWidget, public IProtocolDialog
{
Q_OBJECT
@@ -77,18 +45,15 @@ private:
Ui::UICFTControls ui;
private slots:
- void doOK();
- void doCancel();
+ void doOK();
+ void doCancel();
};
-//*******************************************************************************************************
-// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol
-//*******************************************************************************************************
class FTNoIR_ProtocolDll : public Metadata
{
public:
- FTNoIR_ProtocolDll();
- ~FTNoIR_ProtocolDll();
+ FTNoIR_ProtocolDll();
+ ~FTNoIR_ProtocolDll();
void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Wine"); }
void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Wine"); }
@@ -96,7 +61,3 @@ public:
void getIcon(QIcon *icon) { *icon = QIcon(":/images/wine.png"); }
};
-
-
-#endif//INCLUDED_FTSERVER_H
-//END
diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp
index ecbc2137..c092de42 100644
--- a/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp
+++ b/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp
@@ -1,39 +1,23 @@
#include "ftnoir_protocol_wine.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-//*******************************************************************************************************
-// FaceTrackNoIR Client Settings-dialog.
-//*******************************************************************************************************
-
-//
-// Constructor for server-settings-dialog
-//
FTControls::FTControls() : QWidget()
{
- ui.setupUi( this );
- connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
- connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
+ ui.setupUi( this );
+ connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
+ connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
}
-//
-// Destructor for server-dialog
-
-//
-// OK clicked on server-dialog
-//
void FTControls::doOK() {
- this->close();
+ this->close();
}
-//
-// Cancel clicked on server-dialog
-//
void FTControls::doCancel() {
this->close();
}
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT void* GetDialog( )
{
return (IProtocolDialog*) new FTControls;
}
diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp
index dd7f17a6..c6e3d433 100644
--- a/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp
+++ b/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp
@@ -1,25 +1,15 @@
#include "ftnoir_protocol_wine.h"
-#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() {
+FTNoIR_ProtocolDll::FTNoIR_ProtocolDll()
+{
}
FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll()
{
-
}
-////////////////////////////////////////////////////////////////////////////////
-// Factory function that creates instances if the Protocol object.
-
-// Export both decorated and undecorated names.
-// GetProtocolDll - Undecorated name, which can be easily used with GetProcAddress
-// Win32 API function.
-// _GetProtocolDll@0 - Common name decoration for __stdcall functions in C language.
-//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0")
-
-extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_ProtocolDll;
}
diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx
index 6e512b6e..40f36f8d 100644
--- a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx
+++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx
@@ -1,8 +1,13 @@
-#include <errno.h>
-#include <stdio.h>
+#include <cerrno>
+#include <cstdio>
#include "ftnoir_protocol_ft/fttypes.h"
#include "ftnoir_protocol_wine/wine-shm.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
+
+#define OPENTRACK_CROSS_ONLY
+#include "facetracknoir/plugin-api.hpp"
+
+#define OPENTRACK_COMPAT_BUNDLED
+#include "compat/compat.h"
void create_registry_key(void);
@@ -13,8 +18,9 @@ public:
void lock();
void unlock();
bool success();
- void* mem;
+ inline void* ptr() { return mem; }
private:
+ void* mem;
int fd, size;
};
@@ -25,8 +31,9 @@ public:
void lock();
void unlock();
bool success();
- void* mem;
+ inline void* ptr() { return mem; }
private:
+ void* mem;
void *hMutex, *hMapFile;
};
#include <windows.h>
@@ -34,8 +41,8 @@ private:
int main(void)
{
ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM));
- ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTMemMap));
- if(!lck_posix.success()) {
+ ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap));
+ if(!lck_posix.success()) {
printf("Can't open posix map: %d\n", errno);
return 1;
}
@@ -43,12 +50,11 @@ int main(void)
printf("Can't open Wine map\n");
return 1;
}
- WineSHM* shm_posix = (WineSHM*) lck_posix.mem;
- FTMemMap* shm_wine = (FTMemMap*) lck_wine.mem;
- TFreeTrackData* data = &shm_wine->data;
+ WineSHM* shm_posix = (WineSHM*) lck_posix.ptr();
+ FTHeap* shm_wine = (FTHeap*) lck_wine.ptr();
+ FTData* data = &shm_wine->data;
create_registry_key();
while (1) {
- (void) Sleep(10);
lck_posix.lock();
if (shm_posix->stop) {
lck_posix.unlock();
@@ -70,5 +76,6 @@ int main(void)
shm_wine->table[i] = shm_posix->table[i];
lck_wine.unlock();
lck_posix.unlock();
+ (void) Sleep(4);
}
}
diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx
index e7102600..b7dc531c 100644
--- a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx
+++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx
@@ -1,19 +1,16 @@
-#define OPENTRACK_COMPAT_BUNDLED
-
#ifndef __WIN32
-#define __WIN32
+# error "bad cross"
#endif
+#define OPENTRACK_COMPAT_BUNDLED
#define PortableLockedShm ShmWine
-
-#include "ftnoir_protocol_ft/fttypes.h"
#include "compat/compat.h"
#include "compat/compat.cpp"
-#include <string.h>
+#include "wine-shm.h"
void create_registry_key(void) {
char dir[8192];
-
+
if (GetCurrentDirectoryA(8192, dir) < 8190)
{
HKEY hkpath;
diff --git a/ftnoir_protocol_wine/wine-shm.h b/ftnoir_protocol_wine/wine-shm.h
index ddbda8b5..c0f29cd3 100644
--- a/ftnoir_protocol_wine/wine-shm.h
+++ b/ftnoir_protocol_wine/wine-shm.h
@@ -3,6 +3,10 @@
#define WINE_SHM_NAME "facetracknoir-wine-shm"
#define WINE_MTX_NAME "facetracknoir-wine-mtx"
+#include <memory>
+
+template<typename t> using ptr = std::shared_ptr<t>;
+
struct WineSHM {
double data[6];
int gameid, gameid2;
diff --git a/ftnoir_tracker_aruco/ar_video_widget.cpp b/ftnoir_tracker_aruco/ar_video_widget.cpp
index 9a089213..61a611ea 100644
--- a/ftnoir_tracker_aruco/ar_video_widget.cpp
+++ b/ftnoir_tracker_aruco/ar_video_widget.cpp
@@ -40,3 +40,15 @@ void ArucoVideoWidget::update_and_repaint()
texture = qframe2;
update();
}
+
+void ArucoVideoWidget::paintEvent(QPaintEvent* e)
+{
+ QMutexLocker foo(&mtx);
+ QPainter(this).drawImage(e->rect(), texture);
+}
+
+ArucoVideoWidget::ArucoVideoWidget(QWidget* parent): QWidget(parent)
+{
+ connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()));
+ timer.start(60);
+} \ No newline at end of file
diff --git a/ftnoir_tracker_aruco/ar_video_widget.h b/ftnoir_tracker_aruco/ar_video_widget.h
index e2cf4d9f..820ba7d0 100644
--- a/ftnoir_tracker_aruco/ar_video_widget.h
+++ b/ftnoir_tracker_aruco/ar_video_widget.h
@@ -22,26 +22,18 @@
class ArucoVideoWidget : public QWidget
{
Q_OBJECT
-
-public:
- ArucoVideoWidget(QWidget *parent) : QWidget(parent) {
- connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()));
- timer.start(60);
- }
- void update_image(const cv::Mat& frame);
-protected slots:
- void paintEvent( QPaintEvent* e ) {
- QMutexLocker foo(&mtx);
- QPainter painter(this);
- painter.drawImage(e->rect(), texture);
- }
- void update_and_repaint();
-
+
private:
QMutex mtx;
QImage texture;
QTimer timer;
cv::Mat _frame;
+private slots:
+ void update_and_repaint();
+public:
+ ArucoVideoWidget(QWidget *parent);
+ void update_image(const cv::Mat& frame);
+ void paintEvent( QPaintEvent*) override;
};
#endif // VIDEOWIDGET_H
diff --git a/ftnoir_tracker_aruco/aruco-trackercontrols.ui b/ftnoir_tracker_aruco/aruco-trackercontrols.ui
index 1d5a4241..099dec02 100644
--- a/ftnoir_tracker_aruco/aruco-trackercontrols.ui
+++ b/ftnoir_tracker_aruco/aruco-trackercontrols.ui
@@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>615</width>
- <height>326</height>
+ <width>562</width>
+ <height>178</height>
</rect>
</property>
<property name="sizePolicy">
@@ -19,67 +19,160 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="maximumSize">
- <size>
- <width>6666</width>
- <height>6666</height>
- </size>
- </property>
<property name="windowTitle">
- <string>HT tracker settings</string>
+ <string>Tracker settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <property name="spacing">
- <number>7</number>
- </property>
- <item row="9" column="1" rowspan="3">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Head position</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
+ <item row="1" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>TY</string>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QFrame" name="frame">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="cameraFOV">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="locale">
+ <locale language="English" country="UnitedStates"/>
+ </property>
+ <property name="minimum">
+ <double>35.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>180.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>52.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
- <widget class="QLabel" name="label_5">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Frames per second</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Resolution</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
<property name="text">
- <string>TX</string>
+ <string>Horizontal FOV</string>
</property>
</widget>
</item>
<item row="1" column="1">
- <widget class="QDoubleSpinBox" name="cx">
+ <widget class="QComboBox" name="cameraFPS">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimum">
- <double>-10000.000000000000000</double>
+ <item>
+ <property name="text">
+ <string notr="true">Default</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>30</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>60</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>120</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>180</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="resolution">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="maximum">
- <double>10000.000000000000000</double>
+ <item>
+ <property name="text">
+ <string>640x480</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>320x240</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>320x200</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Default (not recommended!)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Camera name</string>
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_8">
+ <item row="2" column="1">
+ <widget class="QComboBox" name="cameraName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QFrame" name="frame_2">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
<property name="text">
- <string>TZ</string>
+ <string>Head X</string>
</property>
</widget>
</item>
- <item row="3" column="1">
- <widget class="QDoubleSpinBox" name="cz">
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="cy">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
@@ -94,8 +187,8 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QDoubleSpinBox" name="cy">
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="cx">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
@@ -110,264 +203,48 @@
</property>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item row="0" column="3" rowspan="3" colspan="2">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Enable axes</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <property name="horizontalSpacing">
- <number>7</number>
- </property>
- <property name="leftMargin">
- <number>6</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>6</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="rx">
- <property name="text">
- <string>RX</string>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="cz">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="tx">
- <property name="text">
- <string>TX</string>
+ <property name="minimum">
+ <double>-10000.000000000000000</double>
</property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="ry">
- <property name="text">
- <string>RY</string>
+ <property name="maximum">
+ <double>10000.000000000000000</double>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="ty">
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_8">
<property name="text">
- <string>TY</string>
+ <string>Head Z </string>
</property>
</widget>
</item>
<item row="2" column="0">
- <widget class="QCheckBox" name="rz">
+ <widget class="QLabel" name="label_7">
<property name="text">
- <string>RZ</string>
+ <string>Head Y</string>
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="tz">
+ <item row="4" column="1">
+ <widget class="QPushButton" name="btn_calibrate">
<property name="text">
- <string>TZ</string>
+ <string>Calibrate</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Frames per second</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1" colspan="2">
- <widget class="QComboBox" name="cameraName"/>
- </item>
- <item row="1" column="1" colspan="2">
- <widget class="QComboBox" name="cameraFPS">
- <item>
- <property name="text">
- <string notr="true">Default</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>30</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>60</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>120</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>180</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="7" column="1">
- <widget class="QCheckBox" name="red_only">
- <property name="text">
- <string>Recommended!</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Camera name</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" colspan="2">
- <widget class="QDoubleSpinBox" name="cameraFOV">
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="minimum">
- <double>35.000000000000000</double>
- </property>
- <property name="maximum">
- <double>180.000000000000000</double>
- </property>
- <property name="value">
- <double>52.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="6" column="2" rowspan="5" colspan="3">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The ARUCO Library has been developed by the Ava group of the Univeristy of Cordoba, Spain&lt;/p&gt;&lt;p&gt;Rafael Muñoz Salinas &amp;lt;&lt;a href=&quot;mailto:rmsalinas@uco.es&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;rmsalinas@uco.es&lt;/span&gt;&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;&lt;a href=&quot;https://github.com/rmsalinas/aruco&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;https://github.com/rmsalinas/aruco&lt;/span&gt;&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="margin">
- <number>4</number>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Red channel only</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QComboBox" name="resolution">
- <item>
- <property name="text">
- <string>640x480</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>320x240</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>320x200</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Default (not recommended!)</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Horizontal FOV</string>
- </property>
- </widget>
- </item>
- <item row="11" column="4">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="8" column="1">
- <widget class="QDoubleSpinBox" name="marker_pitch">
- <property name="minimum">
- <double>-180.000000000000000</double>
- </property>
- <property name="maximum">
- <double>180.000000000000000</double>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Resolution</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Marker pitch</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
- <tabstops>
- <tabstop>cameraFOV</tabstop>
- <tabstop>cameraFPS</tabstop>
- <tabstop>cameraName</tabstop>
- <tabstop>resolution</tabstop>
- <tabstop>red_only</tabstop>
- <tabstop>marker_pitch</tabstop>
- <tabstop>cx</tabstop>
- <tabstop>cy</tabstop>
- <tabstop>cz</tabstop>
- <tabstop>rx</tabstop>
- <tabstop>ry</tabstop>
- <tabstop>rz</tabstop>
- <tabstop>tx</tabstop>
- <tabstop>ty</tabstop>
- <tabstop>tz</tabstop>
- <tabstop>buttonBox</tabstop>
- </tabstops>
<resources/>
<connections/>
<designerdata>
diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
index ae7ca0b5..fd8a8ce1 100644
--- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
+++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
@@ -5,17 +5,16 @@
* copyright notice and this permission notice appear in all copies.
*/
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "ftnoir_tracker_aruco.h"
-#include "ui_aruco-trackercontrols.h"
-#include "facetracknoir/global-settings.h"
-#include <cmath>
-#include <QMutexLocker>
-#include <aruco.h>
-#include <opencv2/opencv.hpp>
-#include <opencv/highgui.h>
#include <vector>
#include <cstdio>
+#include <cmath>
+#include <algorithm>
+#include <QMutexLocker>
+#include "./include/markerdetector.h"
+#include "ftnoir_tracker_aruco.h"
+#include "facetracknoir/plugin-api.hpp"
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
#if defined(_WIN32)
# undef NOMINMAX
@@ -30,51 +29,51 @@
static QList<QString> get_camera_names(void) {
QList<QString> ret;
#if defined(_WIN32)
- // Create the System Device Enumerator.
- HRESULT hr;
- ICreateDevEnum *pSysDevEnum = NULL;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
- if (FAILED(hr))
- {
- return ret;
- }
- // Obtain a class enumerator for the video compressor category.
- IEnumMoniker *pEnumCat = NULL;
- hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
-
- if (hr == S_OK) {
- // Enumerate the monikers.
- IMoniker *pMoniker = NULL;
- ULONG cFetched;
- while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
- // To retrieve the filter's friendly name, do the following:
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr))
- {
- // Display the name in your UI somehow.
- QString str((QChar*)varName.bstrVal, wcslen(varName.bstrVal));
- ret.append(str);
- }
- VariantClear(&varName);
-
- ////// To create an instance of the filter, do the following:
- ////IBaseFilter *pFilter;
- ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
- //// (void**)&pFilter);
- // Now add the filter to the graph.
- //Remember to release pFilter later.
- pPropBag->Release();
- }
- pMoniker->Release();
- }
- pEnumCat->Release();
- }
- pSysDevEnum->Release();
+ // Create the System Device Enumerator.
+ HRESULT hr;
+ ICreateDevEnum *pSysDevEnum = NULL;
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
+ if (FAILED(hr))
+ {
+ return ret;
+ }
+ // Obtain a class enumerator for the video compressor category.
+ IEnumMoniker *pEnumCat = NULL;
+ hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
+
+ if (hr == S_OK) {
+ // Enumerate the monikers.
+ IMoniker *pMoniker = NULL;
+ ULONG cFetched;
+ while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
+ if (SUCCEEDED(hr)) {
+ // To retrieve the filter's friendly name, do the following:
+ VARIANT varName;
+ VariantInit(&varName);
+ hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+ if (SUCCEEDED(hr))
+ {
+ // Display the name in your UI somehow.
+ QString str((QChar*)varName.bstrVal, wcslen(varName.bstrVal));
+ ret.append(str);
+ }
+ VariantClear(&varName);
+
+ ////// To create an instance of the filter, do the following:
+ ////IBaseFilter *pFilter;
+ ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
+ //// (void**)&pFilter);
+ // Now add the filter to the graph.
+ //Remember to release pFilter later.
+ pPropBag->Release();
+ }
+ pMoniker->Release();
+ }
+ pEnumCat->Release();
+ }
+ pSysDevEnum->Release();
#else
for (int i = 0; i < 16; i++) {
char buf[128];
@@ -90,15 +89,15 @@ static QList<QString> get_camera_names(void) {
}
typedef struct {
- int width;
- int height;
+ int width;
+ int height;
} resolution_tuple;
static resolution_tuple resolution_choices[] = {
- { 640, 480 },
- { 320, 240 },
- { 320, 200 },
- { 0, 0 }
+ { 640, 480 },
+ { 320, 240 },
+ { 320, 200 },
+ { 0, 0 }
};
Tracker::Tracker() : stop(false), layout(nullptr), videoWidget(nullptr)
@@ -109,8 +108,8 @@ Tracker::~Tracker()
{
stop = true;
wait();
- if (videoWidget)
- delete videoWidget;
+ if (videoWidget)
+ delete videoWidget;
if(layout)
delete layout;
qDebug() << "releasing camera, brace for impact";
@@ -137,12 +136,20 @@ void Tracker::StartTracker(QFrame* videoframe)
#define HT_PI 3.1415926535
+void Tracker::getRT(cv::Matx33d& r_, cv::Vec3d& t_)
+{
+ QMutexLocker l(&mtx);
+
+ r_ = r;
+ t_ = t;
+}
+
void Tracker::run()
{
- int res = s.resolution;
- if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple)))
- res = 0;
- resolution_tuple r = resolution_choices[res];
+ int rint = s.resolution;
+ if (rint < 0 || rint >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple)))
+ rint = 0;
+ resolution_tuple res = resolution_choices[rint];
int fps;
switch (static_cast<int>(s.force_fps))
{
@@ -164,23 +171,19 @@ void Tracker::run()
break;
}
camera = cv::VideoCapture(s.camera_index);
- if (r.width)
+ if (res.width)
{
- camera.set(CV_CAP_PROP_FRAME_WIDTH, r.width);
- camera.set(CV_CAP_PROP_FRAME_HEIGHT, r.height);
+ camera.set(CV_CAP_PROP_FRAME_WIDTH, res.width);
+ camera.set(CV_CAP_PROP_FRAME_HEIGHT, res.height);
}
if (fps)
camera.set(CV_CAP_PROP_FPS, fps);
-
+
aruco::MarkerDetector detector;
detector.setDesiredSpeed(3);
cv::Rect last_roi(65535, 65535, 0, 0);
- cv::Mat color, color_, grayscale, rvec, tvec;
-
- const double stateful_coeff = 0.88;
-
if (!camera.isOpened())
{
fprintf(stderr, "aruco tracker: can't open camera\n");
@@ -191,23 +194,17 @@ void Tracker::run()
auto last_time = cv::getTickCount();
int cur_fps = 0;
int last_fps = 0;
- cv::Point2f last_centroid;
- bool first = true;
while (!stop)
{
- if (!camera.read(color_))
+ cv::Mat color;
+ if (!camera.read(color))
continue;
auto tm = cv::getTickCount();
- color_.copyTo(color);
- if (s.red_only)
- {
- cv::Mat channel[3];
- cv::split(color, channel);
- grayscale = channel[2];
- } else
- cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY);
-
+
+ cv::Mat grayscale;
+ cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY);
+
const int scale = frame.cols > 480 ? 2 : 1;
detector.setThresholdParams(scale > 1 ? 11 : 7, 4);
@@ -225,27 +222,33 @@ void Tracker::run()
const double size_min = 0.04;
const double size_max = 0.38;
-
- if (last_roi.width > 0 &&
- (detector.detect(grayscale(last_roi), markers, cv::Mat(), cv::Mat(), -1, false),
- markers.size() == 1 && markers[0].size() == 4))
+
+ bool roi_valid = false;
+
+ if (last_roi.width > 0 && last_roi.height)
{
detector.setMinMaxSize(std::max(0.01, size_min * grayscale.cols / last_roi.width),
std::min(1.0, size_max * grayscale.cols / last_roi.width));
- auto& m = markers.at(0);
- for (int i = 0; i < 4; i++)
+ if (detector.detect(grayscale(last_roi), markers, cv::Mat(), cv::Mat(), -1, false),
+ markers.size() == 1 && markers[0].size() == 4)
{
- auto& p = m.at(i);
- p.x += last_roi.x;
- p.y += last_roi.y;
+ auto& m = markers.at(0);
+ for (int i = 0; i < 4; i++)
+ {
+ auto& p = m.at(i);
+ p.x += last_roi.x;
+ p.y += last_roi.y;
+ }
+ roi_valid = true;
}
}
- else
+
+ if (!roi_valid)
{
detector.setMinMaxSize(size_min, size_max);
detector.detect(grayscale, markers, cv::Mat(), cv::Mat(), -1, false);
}
-
+
if (markers.size() == 1 && markers[0].size() == 4) {
const auto& m = markers.at(0);
for (int i = 0; i < 4; i++)
@@ -268,97 +271,122 @@ void Tracker::run()
frame = color.clone();
::sprintf(buf, "Hz: %d", last_fps);
- cv::putText(frame, buf, cv::Point(10, 32), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(0, 255, 0), scale);
+ cv::putText(frame, buf, cv::Point(10, 32), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(0, 255, 0), 1);
::sprintf(buf, "Jiffies: %ld", (long) (10000 * (time - tm) / freq));
- cv::putText(frame, buf, cv::Point(10, 54), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(80, 255, 0), scale);
-
+ cv::putText(frame, buf, cv::Point(10, 54), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(80, 255, 0), 1);
+
if (markers.size() == 1 && markers[0].size() == 4) {
const auto& m = markers.at(0);
const float size = 40;
-
- const double p = s.marker_pitch;
- const double sq = sin(p * HT_PI / 180);
- const double cq = cos(p * HT_PI / 180);
cv::Mat obj_points(4,3,CV_32FC1);
- obj_points.at<float>(1,0)=-size + s.headpos_x;
- obj_points.at<float>(1,1)=-size * cq + s.headpos_y;
- obj_points.at<float>(1,2)=-size * sq + s.headpos_z;
- obj_points.at<float>(2,0)=size + s.headpos_x;
- obj_points.at<float>(2,1)=-size * cq + s.headpos_y;
- obj_points.at<float>(2,2)=-size * sq + s.headpos_z;
- obj_points.at<float>(3,0)=size + s.headpos_x;
- obj_points.at<float>(3,1)=size * cq + s.headpos_y;
- obj_points.at<float>(3,2)=size * sq + s.headpos_z;
- obj_points.at<float>(0,0)=-size + s.headpos_x;
- obj_points.at<float>(0,1)=size * cq + s.headpos_y;
- obj_points.at<float>(0,2)=size * sq + s.headpos_z;
-
- last_roi = cv::Rect(65535, 65535, 0, 0);
-
+ const int x1=1, x2=2, x3=3, x4=0;
+ obj_points.at<float>(x1,0)=-size + s.headpos_x;
+ obj_points.at<float>(x1,1)=-size + s.headpos_y;
+ obj_points.at<float>(x1,2)= 0 + s.headpos_z;
+
+ obj_points.at<float>(x2,0)=size + s.headpos_x;
+ obj_points.at<float>(x2,1)=-size + s.headpos_y;
+ obj_points.at<float>(x2,2)= 0 + s.headpos_z;
+
+ obj_points.at<float>(x3,0)=size + s.headpos_x;
+ obj_points.at<float>(x3,1)=size + s.headpos_y;
+ obj_points.at<float>(x3,2)= 0 + s.headpos_z;
+
+ obj_points.at<float>(x4,0)= -size + s.headpos_x;
+ obj_points.at<float>(x4,1)= size + s.headpos_y;
+ obj_points.at<float>(x4,2)= 0 + s.headpos_z;
+
+ cv::Vec3d rvec, tvec;
+
+ cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, false, cv::P3P);
+
+ std::vector<cv::Point2f> roi_projection(4);
+
+ {
+ std::vector<cv::Point2f> repr2;
+ std::vector<cv::Point3f> centroid;
+ centroid.push_back(cv::Point3f(0, 0, 0));
+ cv::projectPoints(centroid, rvec, tvec, intrinsics, dist_coeffs, repr2);
+
+ {
+ auto s = cv::Scalar(255, 0, 255);
+ cv::circle(frame, repr2.at(0), 4, s, -1);
+ }
+ }
+
for (int i = 0; i < 4; i++)
{
- auto foo = m.at(i);
- last_roi.x = std::min<int>(foo.x, last_roi.x);
- last_roi.y = std::min<int>(foo.y, last_roi.y);
- last_roi.width = std::max<int>(foo.x, last_roi.width);
- last_roi.height = std::max<int>(foo.y, last_roi.height);
+ obj_points.at<float>(i, 0) -= s.headpos_x;
+ obj_points.at<float>(i, 1) -= s.headpos_y;
+ obj_points.at<float>(i, 2) -= s.headpos_z;
}
+
+ {
+ cv::Mat rvec_, tvec_;
+ cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec_, tvec_, false, cv::P3P);
+ tvec = tvec_;
+ }
+
+ cv::Mat roi_points = obj_points * c_search_window;
+ cv::projectPoints(roi_points, rvec, tvec, intrinsics, dist_coeffs, roi_projection);
+
+ last_roi = cv::Rect(color.cols-1, color.rows-1, 0, 0);
+
+ for (int i = 0; i < 4; i++)
{
- last_roi.width -= last_roi.x;
- last_roi.height -= last_roi.y;
- last_roi.x -= last_roi.width * stateful_coeff;
- last_roi.y -= last_roi.height * stateful_coeff;
- last_roi.width *= stateful_coeff * 3;
- last_roi.height *= stateful_coeff * 3;
- last_roi.x = std::max<int>(0, last_roi.x);
- last_roi.y = std::max<int>(0, last_roi.y);
- last_roi.width = std::min<int>(grayscale.cols - last_roi.x, last_roi.width);
- last_roi.height = std::min<int>(grayscale.rows - last_roi.y, last_roi.height);
+ auto proj = roi_projection[i];
+ int min_x = std::min<int>(proj.x, last_roi.x),
+ min_y = std::min<int>(proj.y, last_roi.y);
+
+ int max_x = std::max<int>(proj.x, last_roi.width),
+ max_y = std::max<int>(proj.y, last_roi.height);
+
+ last_roi.x = min_x;
+ last_roi.y = min_y;
+
+ last_roi.width = max_x;
+ last_roi.height = max_y;
}
+
+ if (last_roi.x < 0)
+ last_roi.x = 0;
+ if (last_roi.y < 0)
+ last_roi.y = 0;
+
+ if (last_roi.width+1 > color.cols)
+ last_roi.width = color.cols-1;
+
+ if (last_roi.height+1 > color.rows)
+ last_roi.height = color.rows-1;
- cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, !first, cv::ITERATIVE);
- first = false;
- cv::Mat rotation_matrix = cv::Mat::zeros(3, 3, CV_64FC1);
- cv::Mat junk1(3, 3, CV_64FC1), junk2(3, 3, CV_64FC1);
- cv::Rodrigues(rvec, rotation_matrix);
+ last_roi.width -= last_roi.x;
+ last_roi.height -= last_roi.y;
+
+ auto rmat = cv::Matx33d::zeros();
+ cv::Matx33d m_r(3, 3, CV_64FC1), m_q(3, 3, CV_64FC1);
+ cv::Rodrigues(rvec, rmat);
{
- cv::Vec3d euler = cv::RQDecomp3x3(rotation_matrix, junk1, junk2);
-
- if (fabs(euler[0]) + fabs(s.marker_pitch) > 60)
- {
- first = true;
- qDebug() << "reset levmarq due to pitch breakage";
- }
+ cv::Vec3d euler = cv::RQDecomp3x3(rmat, m_r, m_q);
QMutexLocker lck(&mtx);
for (int i = 0; i < 3; i++)
- pose[i] = tvec.at<double>(i);
-
+ pose[i] = tvec(i);
pose[Yaw] = euler[1];
pose[Pitch] = -euler[0];
pose[Roll] = euler[2];
- }
- std::vector<cv::Point2f> repr2;
- std::vector<cv::Point3f> centroid;
- centroid.push_back(cv::Point3f(0, 0, 0));
- cv::projectPoints(centroid, rvec, tvec, intrinsics, dist_coeffs, repr2);
-
- {
- auto s = cv::Scalar(255, 0, 255);
- cv::circle(frame, repr2.at(0), 4, s, -1);
+ r = rmat;
+ t = tvec;
}
-
- last_centroid = repr2[0];
+
+ if (roi_valid)
+ cv::rectangle(frame, last_roi, cv::Scalar(255, 0, 255), 1);
}
else
- {
last_roi = cv::Rect(65535, 65535, 0, 0);
- first = true;
- }
if (frame.rows > 0)
videoWidget->update_image(frame);
@@ -368,28 +396,22 @@ void Tracker::run()
void Tracker::GetHeadPoseData(double *data)
{
QMutexLocker lck(&mtx);
-
- if (s.eyaw)
- data[Yaw] = pose[Yaw];
- if (s.epitch)
- data[Pitch] = pose[Pitch];
- if (s.eroll)
- data[Roll] = pose[Roll];
- if (s.ex)
- data[TX] = pose[TX] * .1;
- if (s.ey)
- data[TY] = pose[TY] * .1;
- if (s.ez)
- data[TZ] = pose[TZ] * .1;
+
+ data[Yaw] = pose[Yaw];
+ data[Pitch] = pose[Pitch];
+ data[Roll] = pose[Roll];
+ data[TX] = pose[TX] * .1;
+ data[TY] = pose[TY] * .1;
+ data[TZ] = pose[TZ] * .1;
}
class TrackerDll : public Metadata
{
- // ITrackerDll interface
- void getFullName(QString *strToBeFilled);
- void getShortName(QString *strToBeFilled);
- void getDescription(QString *strToBeFilled);
- void getIcon(QIcon *icon);
+ // ITrackerDll interface
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
};
//-----------------------------------------------------------------------------
@@ -400,12 +422,12 @@ void TrackerDll::getFullName(QString *strToBeFilled)
void TrackerDll::getShortName(QString *strToBeFilled)
{
- *strToBeFilled = "aruco";
+ *strToBeFilled = "aruco";
}
void TrackerDll::getDescription(QString *strToBeFilled)
{
- *strToBeFilled = "";
+ *strToBeFilled = "";
}
void TrackerDll::getIcon(QIcon *icon)
@@ -417,28 +439,19 @@ void TrackerDll::getIcon(QIcon *icon)
//-----------------------------------------------------------------------------
//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
- return new TrackerDll;
+ return new TrackerDll;
}
//#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new Tracker;
}
-////////////////////////////////////////////////////////////////////////////////
-// Factory function that creates instances if the Tracker-settings dialog object.
-
-// Export both decorated and undecorated names.
-// GetTrackerDialog - Undecorated name, which can be easily used with GetProcAddress
-// Win32 API function.
-// _GetTrackerDialog@0 - Common name decoration for __stdcall functions in C language.
-//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
-
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
{
return new TrackerControls;
}
@@ -446,26 +459,54 @@ extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDial
TrackerControls::TrackerControls()
{
tracker = nullptr;
- ui.setupUi(this);
+ calib_timer.setInterval(200);
+ ui.setupUi(this);
setAttribute(Qt::WA_NativeWindow, true);
+ ui.cameraName->addItems(get_camera_names());
tie_setting(s.camera_index, ui.cameraName);
- tie_setting(s.resolution, ui.resolution);
+ tie_setting(s.resolution, ui.resolution);
tie_setting(s.force_fps, ui.cameraFPS);
tie_setting(s.fov, ui.cameraFOV);
- tie_setting(s.eyaw, ui.rx);
- tie_setting(s.epitch, ui.ry);
- tie_setting(s.eroll, ui.rz);
- tie_setting(s.ex, ui.tx);
- tie_setting(s.ey, ui.ty);
- tie_setting(s.ez, ui.tz);
tie_setting(s.headpos_x, ui.cx);
tie_setting(s.headpos_y, ui.cy);
tie_setting(s.headpos_z, ui.cz);
- tie_setting(s.red_only, ui.red_only);
- tie_setting(s.marker_pitch, ui.marker_pitch);
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- ui.cameraName->addItems(get_camera_names());
+ connect(ui.btn_calibrate, SIGNAL(clicked()), this, SLOT(toggleCalibrate()));
+ connect(this, SIGNAL(destroyed()), this, SLOT(cleanupCalib()));
+ connect(&calib_timer, SIGNAL(timeout()), this, SLOT(update_tracker_calibration()));
+}
+
+void TrackerControls::toggleCalibrate()
+{
+ if (!calib_timer.isActive())
+ {
+ calibrator.reset();
+ calib_timer.start();
+ } else {
+ cleanupCalib();
+ }
+}
+
+void TrackerControls::cleanupCalib()
+{
+ if (calib_timer.isActive())
+ calib_timer.stop();
+}
+
+void TrackerControls::update_tracker_calibration()
+{
+ if (calib_timer.isActive() && tracker)
+ {
+ cv::Matx33d r;
+ cv::Vec3d t;
+ tracker->getRT(r, t);
+ calibrator.update(r, t);
+ auto pos = calibrator.get_estimate() * .1;
+ s.headpos_x = pos(0);
+ s.headpos_y = pos(1);
+ s.headpos_z = pos(2);
+ }
}
void TrackerControls::doOK()
@@ -473,11 +514,11 @@ void TrackerControls::doOK()
s.b->save();
if (tracker)
tracker->reload();
- this->close();
+ this->close();
}
void TrackerControls::doCancel()
{
- s.b->revert();
+ s.b->reload();
this->close();
}
diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h
index 4cab84b5..3d37dacd 100644
--- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h
+++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h
@@ -5,10 +5,8 @@
* copyright notice and this permission notice appear in all copies.
*/
-#ifndef FTNOIR_TRACKER_HT_H
-#define FTNOIR_TRACKER_HT_H
+#pragma once
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "ui_aruco-trackercontrols.h"
#include "ar_video_widget.h"
#include <QObject>
@@ -16,18 +14,20 @@
#include <QMutex>
#include <QHBoxLayout>
#include <QDialog>
-#include <opencv2/opencv.hpp>
-#include <opencv/highgui.h>
+#include <QTimer>
#include "facetracknoir/options.h"
+#include "ftnoir_tracker_aruco/trans_calib.h"
+#include "facetracknoir/plugin-api.hpp"
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
+
using namespace options;
struct settings {
pbundle b;
value<double> fov, headpos_x, headpos_y, headpos_z;
value<int> camera_index, force_fps, resolution;
- value<bool> red_only;
- value<bool> eyaw, epitch, eroll, ex, ey, ez;
- value<double> marker_pitch;
settings() :
b(bundle("aruco-tracker")),
fov(b, "field-of-view", 56),
@@ -36,59 +36,52 @@ struct settings {
headpos_z(b, "headpos-z", 0),
camera_index(b, "camera-index", 0),
force_fps(b, "force-fps", 0),
- resolution(b, "force-resolution", 0),
- red_only(b, "red-only", false),
- eyaw(b, "enable-y", true),
- epitch(b, "enable-p", true),
- eroll(b, "enable-r", true),
- ex(b, "enable-x", true),
- ey(b, "enable-y", true),
- ez(b, "enable-z", true),
- marker_pitch(b, "marker-pitch", 0)
+ resolution(b, "force-resolution", 0)
{}
};
class Tracker : protected QThread, public ITracker
{
Q_OBJECT
+ static constexpr double c_search_window = 2.2;
public:
- Tracker();
- virtual ~Tracker();
+ Tracker();
+ ~Tracker() override;
void StartTracker(QFrame* frame);
void GetHeadPoseData(double *data);
void run();
void reload() { s.b->reload(); }
+ void getRT(cv::Matx33d &r, cv::Vec3d &t);
private:
QMutex mtx;
volatile bool stop;
QHBoxLayout* layout;
- ArucoVideoWidget* videoWidget;
+ ArucoVideoWidget* videoWidget;
settings s;
double pose[6];
cv::Mat frame;
cv::VideoCapture camera;
+ cv::Matx33d r;
+ cv::Vec3d t;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class TrackerControls : public QWidget, public ITrackerDialog
{
Q_OBJECT
public:
TrackerControls();
- void registerTracker(ITracker * x) {
- tracker = dynamic_cast<Tracker*>(x);
- }
- void unRegisterTracker() {
- tracker = nullptr;
- }
+ void registerTracker(ITracker * x) { tracker = dynamic_cast<Tracker*>(x); }
+ void unRegisterTracker() { tracker = nullptr; }
private:
- Ui::Form ui;
+ Ui::Form ui;
Tracker* tracker;
settings s;
+ TranslationCalibrator calibrator;
+ QTimer calib_timer;
private slots:
- void doOK();
- void doCancel();
+ void doOK();
+ void doCancel();
+ void toggleCalibrate();
+ void cleanupCalib();
+ void update_tracker_calibration();
};
-
-#endif
-
diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h
index ffdc5262..66e57100 100644
--- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h
+++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h
@@ -5,8 +5,7 @@
* copyright notice and this permission notice appear in all copies.
*/
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
//-----------------------------------------------------------------------------
class TrackerDll : public Metadata
diff --git a/ftnoir_tracker_aruco/include/boarddetector.h b/ftnoir_tracker_aruco/include/boarddetector.h
index 4770b5c9..a0ee2361 100644
--- a/ftnoir_tracker_aruco/include/boarddetector.h
+++ b/ftnoir_tracker_aruco/include/boarddetector.h
@@ -134,6 +134,6 @@ private:
};
-}
+};
#endif
diff --git a/ftnoir_tracker_aruco/include/cameraparameters.h b/ftnoir_tracker_aruco/include/cameraparameters.h
index c3381a74..a419afbe 100644
--- a/ftnoir_tracker_aruco/include/cameraparameters.h
+++ b/ftnoir_tracker_aruco/include/cameraparameters.h
@@ -28,7 +28,7 @@ or implied, of Rafael Muñoz Salinas.
#ifndef _Aruco_CameraParameters_H
#define _Aruco_CameraParameters_H
#include "exports.h"
-#include <opencv2/opencv.hpp>
+#include <opencv2/core/core.hpp>
#include <string>
using namespace std;
namespace aruco
@@ -105,7 +105,7 @@ public:
* @param invert: indicates if the output projection matrix has to yield a horizontally inverted image because image data has not been stored in the order of glDrawPixels: bottom-to-top.
*/
void glGetProjectionMatrix( cv::Size orgImgSize, cv::Size size,double proj_matrix[16],double gnear,double gfar,bool invert=false )throw(cv::Exception);
-
+
/**
* setup camera for an Ogre project.
* Use:
@@ -117,7 +117,7 @@ public:
* As in OpenGL, it assumes no camera distorsion
*/
void OgreGetProjectionMatrix( cv::Size orgImgSize, cv::Size size,double proj_matrix[16],double gnear,double gfar,bool invert=false )throw(cv::Exception);
-
+
private:
//GL routines
diff --git a/ftnoir_tracker_aruco/include/cvdrawingutils.h b/ftnoir_tracker_aruco/include/cvdrawingutils.h
index 38e9986e..ff67242f 100644
--- a/ftnoir_tracker_aruco/include/cvdrawingutils.h
+++ b/ftnoir_tracker_aruco/include/cvdrawingutils.h
@@ -46,7 +46,7 @@ namespace aruco
static void draw3dCube(cv::Mat &Image,Board &m,const CameraParameters &CP);
};
-}
+};
#endif
diff --git a/ftnoir_tracker_aruco/include/exports.h b/ftnoir_tracker_aruco/include/exports.h
index 154605ec..aaeb94e4 100644
--- a/ftnoir_tracker_aruco/include/exports.h
+++ b/ftnoir_tracker_aruco/include/exports.h
@@ -25,7 +25,7 @@ The views and conclusions contained in the software and documentation are those
authors and should not be interpreted as representing official policies, either expressed
or implied, of Rafael Muñoz Salinas.
********************************/
-
+
#ifndef __OPENARUCO_CORE_TYPES_H__
@@ -37,9 +37,9 @@ or implied, of Rafael Muñoz Salinas.
#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined DSO_EXPORTS
- #define ARUCO_EXPORTS __declspec(dllexport)
+ #define ARUCO_EXPORTS __declspec(dllexport)
#else
- #define ARUCO_EXPORTS
+ #define ARUCO_EXPORTS __attribute__ ((visibility ("default")))
#endif
diff --git a/ftnoir_tracker_aruco/include/marker.h b/ftnoir_tracker_aruco/include/marker.h
index dc6bb28c..89961002 100644
--- a/ftnoir_tracker_aruco/include/marker.h
+++ b/ftnoir_tracker_aruco/include/marker.h
@@ -29,7 +29,7 @@ or implied, of Rafael Muñoz Salinas.
#define _Aruco_Marker_H
#include <vector>
#include <iostream>
-#include <opencv2/opencv.hpp>
+#include <opencv2/core/core.hpp>
#include "exports.h"
#include "cameraparameters.h"
using namespace std;
@@ -81,12 +81,12 @@ public:
* @param setYPerperdicular If set the Y axis will be perpendicular to the surface. Otherwise, it will be the Z axis
*/
void calculateExtrinsics(float markerSize,cv::Mat CameraMatrix,cv::Mat Distorsion=cv::Mat(),bool setYPerperdicular=true)throw(cv::Exception);
-
+
/**Given the extrinsic camera parameters returns the GL_MODELVIEW matrix for opengl.
* Setting this matrix, the reference coordinate system will be set in this marker
*/
void glGetModelViewMatrix( double modelview_matrix[16])throw(cv::Exception);
-
+
/**
* Returns position vector and orientation quaternion for an Ogre scene node or entity.
* Use:
@@ -97,8 +97,8 @@ public:
* mySceneNode->setOrientation( ogreOrient );
* ...
*/
- void OgreGetPoseParameters( double position[3], double orientation[4] )throw(cv::Exception);
-
+ void OgreGetPoseParameters( double position[3], double orientation[4] )throw(cv::Exception);
+
/**Returns the centroid of the marker
*/
cv::Point2f getCenter()const;
@@ -132,11 +132,11 @@ public:
return str;
}
-
-
+
+
private:
void rotateXAxis(cv::Mat &rotation);
-
+
};
}
diff --git a/ftnoir_tracker_aruco/include/markerdetector.h b/ftnoir_tracker_aruco/include/markerdetector.h
index 4d6e7b90..6f489c34 100644
--- a/ftnoir_tracker_aruco/include/markerdetector.h
+++ b/ftnoir_tracker_aruco/include/markerdetector.h
@@ -27,7 +27,7 @@ or implied, of Rafael Muñoz Salinas.
********************************/
#ifndef _ARUCO_MarkerDetector_H
#define _ARUCO_MarkerDetector_H
-#include <opencv2/opencv.hpp>
+#include <opencv2/core/core.hpp>
#include <cstdio>
#include <iostream>
#include "cameraparameters.h"
@@ -47,27 +47,25 @@ class ARUCO_EXPORTS MarkerDetector
class MarkerCandidate: public Marker{
public:
MarkerCandidate(){}
- MarkerCandidate(const Marker &M): Marker(M){}
+ MarkerCandidate(const Marker &M): Marker(M){}
MarkerCandidate(const MarkerCandidate &M): Marker(M){
contour=M.contour;
idx=M.idx;
}
- MarkerCandidate operator=(const MarkerCandidate &M){
- if (this == &M)
- return *this;
+ MarkerCandidate & operator=(const MarkerCandidate &M){
(*(Marker*)this)=(*(Marker*)&M);
contour=M.contour;
idx=M.idx;
- return M;
+ return *this;
}
-
+
vector<cv::Point> contour;//all the points of its contour
int idx;//index position in the global contour list
};
public:
/**
- * See
+ * See
*/
MarkerDetector();
@@ -161,17 +159,17 @@ public:
* of cols and rows.
* @param min size of the contour to consider a possible marker as valid (0,1]
* @param max size of the contour to consider a possible marker as valid [0,1)
- *
+ *
*/
void setMinMaxSize(float min=0.03,float max=0.5)throw(cv::Exception);
-
+
/**reads the min and max sizes employed
* @param min output size of the contour to consider a possible marker as valid (0,1]
* @param max output size of the contour to consider a possible marker as valid [0,1)
- *
+ *
*/
void getMinMaxSize(float &min,float &max){min=_minSize;max=_maxSize;}
-
+
/**Enables/Disables erosion process that is REQUIRED for chessboard like boards.
* By default, this property is enabled
*/
@@ -210,10 +208,10 @@ public:
markerIdDetector_ptrfunc=markerdetector_func;
}
- /** Use an smaller version of the input image for marker detection.
+ /** Use an smaller version of the input image for marker detection.
* If your marker is small enough, you can employ an smaller image to perform the detection without noticeable reduction in the precision.
* Internally, we are performing a pyrdown operation
- *
+ *
* @param level number of times the image size is divided by 2. Internally, we are performing a pyrdown.
*/
void pyrDown(unsigned int level){pyrdown_level=level;}
@@ -247,17 +245,17 @@ public:
* @return true if the operation succeed
*/
bool warp(cv::Mat &in,cv::Mat &out,cv::Size size, std::vector<cv::Point2f> points)throw (cv::Exception);
-
-
-
+
+
+
/** Refine MarkerCandidate Corner using LINES method
* @param candidate candidate to refine corners
*/
- void refineCandidateLines(MarkerCandidate &candidate);
-
-
+ void refineCandidateLines(MarkerCandidate &candidate);
+
+
/**DEPRECATED!!! Use the member function in CameraParameters
- *
+ *
* Given the intrinsic camera parameters returns the GL_PROJECTION matrix for opengl.
* PLease NOTE that when using OpenGL, it is assumed no camera distorsion! So, if it is not true, you should have
* undistor image
@@ -308,26 +306,26 @@ private:
*/
int perimeter(std::vector<cv::Point2f> &a);
-
+
// //GL routines
-//
+//
// static void argConvGLcpara2( double cparam[3][4], int width, int height, double gnear, double gfar, double m[16], bool invert )throw(cv::Exception);
// static int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] )throw(cv::Exception);
// static double norm( double a, double b, double c );
// static double dot( double a1, double a2, double a3,
// double b1, double b2, double b3 );
-//
+//
//detection of the
void findBestCornerInRegion_harris(const cv::Mat & grey,vector<cv::Point2f> & Corners,int blockSize);
-
-
+
+
// auxiliar functions to perform LINES refinement
void interpolate2Dline( const vector< cv::Point > &inPoints, cv::Point3f &outLine);
- cv::Point2f getCrossPoint(const cv::Point3f& line1, const cv::Point3f& line2);
-
-
- /**Given a vector vinout with elements and a boolean vector indicating the lements from it to remove,
+ cv::Point2f getCrossPoint(const cv::Point3f& line1, const cv::Point3f& line2);
+
+
+ /**Given a vector vinout with elements and a boolean vector indicating the lements from it to remove,
* this function remove the elements
* @param vinout
* @param toRemove
@@ -353,5 +351,9 @@ private:
void draw(cv::Mat out,const std::vector<Marker> &markers );
};
-}
+
+
+
+
+};
#endif
diff --git a/ftnoir_tracker_aruco/trans_calib.cpp b/ftnoir_tracker_aruco/trans_calib.cpp
new file mode 100644
index 00000000..369de449
--- /dev/null
+++ b/ftnoir_tracker_aruco/trans_calib.cpp
@@ -0,0 +1,44 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 "trans_calib.h"
+
+using namespace cv;
+
+//-----------------------------------------------------------------------------
+TranslationCalibrator::TranslationCalibrator()
+{
+ reset();
+}
+
+void TranslationCalibrator::reset()
+{
+ P = Matx66f::zeros();
+ y = Vec6f(0,0,0, 0,0,0);
+}
+
+void TranslationCalibrator::update(const Matx33d& R_CM_k, const Vec3d& t_CM_k)
+{
+ Matx<double, 6,3> H_k_T = Matx<double, 6,3>::zeros();
+ for (int i=0; i<3; ++i) {
+ for (int j=0; j<3; ++j) {
+ H_k_T(i,j) = R_CM_k(j,i);
+ }
+ }
+ for (int i=0; i<3; ++i)
+ {
+ H_k_T(3+i,i) = 1.0;
+ }
+ P += H_k_T * H_k_T.t();
+ y += H_k_T * t_CM_k;
+}
+
+Vec3f TranslationCalibrator::get_estimate()
+{
+ Vec6f x = P.inv() * y;
+ return Vec3f(x[0], x[1], x[2]);
+}
diff --git a/FTNoIR_Tracker_PT/trans_calib.h b/ftnoir_tracker_aruco/trans_calib.h
index f2521690..5a2d7c0f 100644
--- a/FTNoIR_Tracker_PT/trans_calib.h
+++ b/ftnoir_tracker_aruco/trans_calib.h
@@ -1,39 +1,39 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef TRANSCALIB_H
-#define TRANSCALIB_H
-
-#include <opencv2/opencv.hpp>
-
-//-----------------------------------------------------------------------------
-// Calibrates the translation from head to model = t_MH
-// by recursive least squares /
-// kalman filter in information form with identity noise covariance
-// measurement equation when head position = t_CH is fixed:
-// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k
-
-class TranslationCalibrator
-{
-public:
- TranslationCalibrator();
-
- // reset the calibration process
- void reset();
-
- // update the current estimate
- void update(const cv::Matx33f& R_CM_k, const cv::Vec3f& t_CM_k);
-
- // get the current estimate for t_MH
- cv::Vec3f get_estimate();
-
-protected:
- cv::Matx66f P; // normalized precision matrix = inverse covariance
- cv::Vec6f y; // P*(-t_MH, t_CH)
-};
-
-#endif //TRANSCALIB_H \ No newline at end of file
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef TRANSCALIB_H
+#define TRANSCALIB_H
+
+#include <opencv2/core/core.hpp>
+
+//-----------------------------------------------------------------------------
+// Calibrates the translation from head to model = t_MH
+// by recursive least squares /
+// kalman filter in information form with identity noise covariance
+// measurement equation when head position = t_CH is fixed:
+// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k
+
+class TranslationCalibrator
+{
+public:
+ TranslationCalibrator();
+
+ // reset the calibration process
+ void reset();
+
+ // update the current estimate
+ void update(const cv::Matx33d& R_CM_k, const cv::Vec3d& t_CM_k);
+
+ // get the current estimate for t_MH
+ cv::Vec3f get_estimate();
+
+private:
+ cv::Matx66f P; // normalized precision matrix = inverse covariance
+ cv::Vec6f y; // P*(-t_MH, t_CH)
+};
+
+#endif //TRANSCALIB_H
diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h
deleted file mode 100644
index 09723d84..00000000
--- a/ftnoir_tracker_base/ftnoir_tracker_base.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of the some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2010 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* This class implements a tracker-base *
-*********************************************************************************/
-#ifndef FTNOIR_TRACKER_BASE_H
-#define FTNOIR_TRACKER_BASE_H
-
-#include "ftnoir_tracker_base_global.h"
-#include "ftnoir_tracker_types.h"
-#include <QWidget>
-#include <QFrame>
-#include <QWaitCondition>
-#include <QMutex>
-#include <QFrame>
-
-////////////////////////////////////////////////////////////////////////////////
-// COM-Like abstract interface.
-// This interface doesn't require __declspec(dllexport/dllimport) specifier.
-// Method calls are dispatched via virtual table.
-// Any C++ compiler can use it.
-// Instances are obtained via factory function.
-struct ITracker
-{
- virtual ~ITracker() = 0;
- virtual void StartTracker( QFrame* frame ) = 0;
- virtual void GetHeadPoseData(double *data) = 0;
- virtual int preferredHz() { return 200; }
-};
-
-inline ITracker::~ITracker() { }
-
-////////////////////////////////////////////////////////////////////////////////
-// COM-Like abstract interface.
-// This interface doesn't require __declspec(dllexport/dllimport) specifier.
-// Method calls are dispatched via virtual table.
-// Any C++ compiler can use it.
-// Instances are obtained via factory function.
-struct ITrackerDialog
-{
- virtual ~ITrackerDialog() {}
- virtual void registerTracker(ITracker *tracker) = 0;
- virtual void unRegisterTracker() = 0;
-};
-
-#endif // FTNOIR_TRACKER_BASE_H
diff --git a/ftnoir_tracker_base/ftnoir_tracker_base_global.h b/ftnoir_tracker_base/ftnoir_tracker_base_global.h
deleted file mode 100644
index e717d845..00000000
--- a/ftnoir_tracker_base/ftnoir_tracker_base_global.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H
-#define FTNOIR_TRACKER_BASE_GLOBAL_H
-
-#include <QtGlobal>
-
-#ifndef FTNOIR_TRACKER_BASE_EXPORT
-# ifndef OPENTRACK_MAIN
-# if !defined(_MSC_VER)
-# define FTNOIR_TRACKER_BASE_EXPORT __attribute__ ((visibility ("default")))
-# else
-# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT
-# endif
-# else
-# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT
-# endif
-#endif
-
-#endif // FTNOIR_TRACKER_BASE_GLOBAL_H
diff --git a/ftnoir_tracker_base/ftnoir_tracker_types.h b/ftnoir_tracker_base/ftnoir_tracker_types.h
deleted file mode 100644
index d38baee4..00000000
--- a/ftnoir_tracker_base/ftnoir_tracker_types.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-enum Axis {
- TX = 0, TY, TZ, Yaw, Pitch, Roll
-};
diff --git a/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui b/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui
new file mode 100644
index 00000000..48290bf2
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UI_freepie_udp_dialog</class>
+ <widget class="QWidget" name="UI_freepie_udp_dialog">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>198</width>
+ <height>71</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>UDP tracker settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>UDP port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="port">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc b/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc
new file mode 100644
index 00000000..3fd3edc4
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>glovepie.png</file>
+ </qresource>
+</RCC>
diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp
new file mode 100644
index 00000000..ad505229
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp
@@ -0,0 +1,94 @@
+#include "ftnoir_tracker_freepie-udp.h"
+#include "facetracknoir/plugin-support.h"
+
+#include <cinttypes>
+#include <algorithm>
+
+TrackerImpl::TrackerImpl() : pose { 0,0,0, 0,0,0 }, should_quit(false)
+{
+}
+
+TrackerImpl::~TrackerImpl()
+{
+ should_quit = true;
+ wait();
+}
+
+void TrackerImpl::run() {
+#pragma pack(push, 1)
+ struct {
+ uint8_t pad1;
+ uint8_t flags;
+ uint8_t pad2;
+ float fl[12];
+ } data;
+#pragma pack(pop)
+ enum F {
+ flag_Raw = 1 << 0,
+ flag_Orient = 1 << 1,
+ Mask = flag_Raw | flag_Orient
+ };
+
+ while (1) {
+ if (should_quit)
+ break;
+
+ float orient[3];
+ bool filled = false;
+
+ while (sock.hasPendingDatagrams())
+ {
+ using t = decltype(data);
+ t tmp {0,0,0, {0,0,0, 0,0,0}};
+ (void) sock.readDatagram(reinterpret_cast<char*>(&tmp), sizeof(data));
+
+ int flags = tmp.flags & F::Mask;
+
+ switch (flags)
+ {
+ case flag_Raw:
+ continue;
+ case flag_Raw | flag_Orient:
+ for (int i = 0; i < 3; i++)
+ orient[i] = tmp.fl[i+9];
+ break;
+ case flag_Orient:
+ for (int i = 0; i < 3; i++)
+ orient[i] = tmp.fl[i];
+ break;
+ }
+
+ filled = true;
+ data = tmp;
+ }
+
+ if (filled)
+ {
+ QMutexLocker foo(&mtx);
+ static constexpr double d2r = 57.295781;
+ for (int i = 0; i < 3; i++)
+ pose[Yaw + i] = d2r * orient[i];
+ }
+ usleep(4000);
+ }
+}
+
+void TrackerImpl::StartTracker(QFrame*)
+{
+ (void) sock.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
+ start();
+}
+
+void TrackerImpl::GetHeadPoseData(double *data)
+{
+ QMutexLocker foo(&mtx);
+
+ data[Yaw] = pose[Yaw];
+ data[Pitch] = pose[Pitch];
+ data[Roll] = pose[Roll];
+}
+
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
+{
+ return new TrackerImpl;
+}
diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h
new file mode 100644
index 00000000..de32e64b
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2014 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 <cinttypes>
+#include <QUdpSocket>
+#include <QThread>
+#include "ui_freepie-udp-controls.h"
+#include "facetracknoir/plugin-api.hpp"
+#include "facetracknoir/options.h"
+using namespace options;
+
+struct settings {
+ pbundle b;
+ value<int> port;
+ settings() :
+ b(bundle("freepie-udp-tracker")),
+ port(b, "port", 4237)
+ {}
+};
+
+class TrackerImpl : public ITracker, private QThread
+{
+public:
+ TrackerImpl();
+ ~TrackerImpl() override;
+ void StartTracker(QFrame *);
+ void GetHeadPoseData(double *data);
+protected:
+ void run() override;
+private:
+ double pose[6];
+ QUdpSocket sock;
+ settings s;
+ QMutex mtx;
+ volatile bool should_quit;
+};
+
+class TrackerDialog : public QWidget, public ITrackerDialog
+{
+ Q_OBJECT
+public:
+ TrackerDialog();
+ void registerTracker(ITracker *) {}
+ void unRegisterTracker() {}
+private:
+ Ui::UI_freepie_udp_dialog ui;
+ settings s;
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class TrackerMeta : public Metadata
+{
+public:
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
+};
+
diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp
new file mode 100644
index 00000000..6d6a951e
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp
@@ -0,0 +1,27 @@
+#include "ftnoir_tracker_freepie-udp.h"
+#include "facetracknoir/plugin-support.h"
+
+TrackerDialog::TrackerDialog()
+{
+ ui.setupUi(this);
+
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
+
+ tie_setting(s.port, ui.port);
+}
+
+void TrackerDialog::doOK() {
+ s.b->save();
+ this->close();
+}
+
+void TrackerDialog::doCancel() {
+ s.b->reload();
+ this->close();
+}
+
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog()
+{
+ return new TrackerDialog;
+}
diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp
new file mode 100644
index 00000000..afcc8c6e
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp
@@ -0,0 +1,27 @@
+#include "ftnoir_tracker_freepie-udp.h"
+#include "facetracknoir/plugin-support.h"
+
+void TrackerMeta::getFullName(QString *strToBeFilled)
+{
+ *strToBeFilled = "FreePIE UDP";
+}
+
+void TrackerMeta::getShortName(QString *strToBeFilled)
+{
+ *strToBeFilled = "FreePIE";
+}
+
+void TrackerMeta::getDescription(QString *strToBeFilled)
+{
+ *strToBeFilled = "FreePIE UDP";
+}
+
+void TrackerMeta::getIcon(QIcon *icon)
+{
+ *icon = QIcon(":/glovepie.png");
+}
+
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
+{
+ return new TrackerMeta;
+}
diff --git a/ftnoir_tracker_freepie-udp/glovepie.png b/ftnoir_tracker_freepie-udp/glovepie.png
new file mode 100644
index 00000000..2156b7af
--- /dev/null
+++ b/ftnoir_tracker_freepie-udp/glovepie.png
Binary files differ
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
index 76a6ba71..a1cb33a5 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
@@ -1,10 +1,9 @@
#include "stdafx.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "headtracker-ftnoir.h"
#include "ftnoir_tracker_ht.h"
#include "ftnoir_tracker_ht_dll.h"
#include "ui_ht-trackercontrols.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include <cmath>
#if defined(_WIN32)
@@ -139,7 +138,7 @@ void Tracker::load_settings(ht_config_t* config)
Tracker::Tracker() :
lck_shm(HT_SHM_NAME, HT_MUTEX_NAME, sizeof(ht_shm_t)),
- shm(reinterpret_cast<ht_shm_t*>(lck_shm.mem)),
+ shm(reinterpret_cast<ht_shm_t*>(lck_shm.ptr())),
videoWidget(nullptr),
layout(nullptr)
{
@@ -197,24 +196,12 @@ void Tracker::GetHeadPoseData(double *data)
shm->frame.width = 0;
}
if (shm->result.filled) {
- if (s.enableRX)
- data[Yaw] = shm->result.rotx;
- if (s.enableRY) {
- data[Pitch] = shm->result.roty;
- }
- if (s.enableRZ) {
- data[Roll] = shm->result.rotz;
- }
- if (s.enableTX)
- data[TX] = shm->result.tx;
- if (s.enableTY)
- data[TY] = shm->result.ty;
- if (s.enableTZ)
- data[TZ] = shm->result.tz;
- if (fabs(data[Yaw]) > 60 || fabs(data[Pitch]) > 50 || fabs(data[Roll]) > 40)
- {
- shm->pause = true;
- }
+ data[Yaw] = shm->result.rotx;
+ data[Pitch] = shm->result.roty;
+ data[Roll] = shm->result.rotz;
+ data[TX] = shm->result.tx;
+ data[TY] = shm->result.ty;
+ data[TZ] = shm->result.tz;
} else {
shm->pause = false;
}
@@ -224,7 +211,7 @@ void Tracker::GetHeadPoseData(double *data)
//-----------------------------------------------------------------------------
void TrackerDll::getFullName(QString *strToBeFilled)
{
- *strToBeFilled = "HT 1.0";
+ *strToBeFilled = "HT face tracker";
}
void TrackerDll::getShortName(QString *strToBeFilled)
@@ -242,17 +229,17 @@ void TrackerDll::getIcon(QIcon *icon)
*icon = QIcon(":/images/ht.png");
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new TrackerDll;
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new Tracker;
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
{
return new TrackerControls;
}
@@ -267,12 +254,6 @@ TrackerControls::TrackerControls()
tie_setting(s.camera_idx, ui.cameraName);
tie_setting(s.fps, ui.cameraFPS);
tie_setting(s.fov, ui.cameraFOV);
- tie_setting(s.enableTX, ui.tx);
- tie_setting(s.enableTY, ui.ty);
- tie_setting(s.enableTZ, ui.tz);
- tie_setting(s.enableRX, ui.rx);
- tie_setting(s.enableRY, ui.ry);
- tie_setting(s.enableRZ, ui.rz);
tie_setting(s.resolution, ui.resolution);
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
@@ -286,6 +267,6 @@ void TrackerControls::doOK()
void TrackerControls::doCancel()
{
- s.b->revert();
+ s.b->reload();
this->close();
}
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.h b/ftnoir_tracker_ht/ftnoir_tracker_ht.h
index 583249dc..ea2cb75e 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht.h
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.h
@@ -9,28 +9,21 @@
#define FTNOIR_TRACKER_HT_H
#include "stdafx.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "headtracker-ftnoir.h"
#include "ui_ht-trackercontrols.h"
#include "ht_video_widget.h"
#include "compat/compat.h"
#include <QObject>
#include "facetracknoir/options.h"
+#include "facetracknoir/plugin-api.hpp"
using namespace options;
struct settings {
pbundle b;
- value<bool> enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ;
value<double> fov;
value<int> fps, camera_idx, resolution;
settings() :
b(bundle("HT-Tracker")),
- enableTX(b, "enable-tx", true),
- enableTY(b, "enable-ty", true),
- enableTZ(b, "enable-tz", true),
- enableRX(b, "enable-rx", true),
- enableRY(b, "enable-ry", true),
- enableRZ(b, "enable-rz", true),
fov(b, "fov", 56),
fps(b, "fps", 0),
camera_idx(b, "camera-index", 0),
@@ -43,7 +36,7 @@ class Tracker : public QObject, public ITracker
Q_OBJECT
public:
Tracker();
- virtual ~Tracker();
+ ~Tracker() override;
void StartTracker(QFrame* frame);
void GetHeadPoseData(double *data);
void load_settings(ht_config_t* config);
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h
index ffdc5262..66e57100 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h
@@ -5,8 +5,7 @@
* copyright notice and this permission notice appear in all copies.
*/
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
//-----------------------------------------------------------------------------
class TrackerDll : public Metadata
diff --git a/ftnoir_tracker_ht/ht-trackercontrols.ui b/ftnoir_tracker_ht/ht-trackercontrols.ui
index f57022c8..0b94ffc5 100644
--- a/ftnoir_tracker_ht/ht-trackercontrols.ui
+++ b/ftnoir_tracker_ht/ht-trackercontrols.ui
@@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>531</width>
- <height>166</height>
+ <width>354</width>
+ <height>158</height>
</rect>
</property>
<property name="sizePolicy">
@@ -52,91 +52,6 @@
</property>
</widget>
</item>
- <item row="0" column="2" rowspan="3">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Enable axes</string>
- </property>
- <widget class="QCheckBox" name="rx">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>20</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>RX</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="ry">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>40</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>RY</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="rz">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>60</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>RZ</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="tx">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>20</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>TX</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="ty">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>40</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>TY</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="tz">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>60</y>
- <width>70</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>TZ</string>
- </property>
- </widget>
- </widget>
- </item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@@ -214,7 +129,7 @@
</item>
</widget>
</item>
- <item row="4" column="2">
+ <item row="4" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
diff --git a/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui b/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui
index e5e41bec..7cfac075 100644
--- a/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui
+++ b/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui
@@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>172</width>
- <height>145</height>
+ <width>190</width>
+ <height>62</height>
</rect>
</property>
<property name="windowTitle">
@@ -26,167 +26,15 @@
<property name="autoFillBackground">
<bool>false</bool>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>None whatsoever</string>
</property>
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_61">
- <property name="text">
- <string>Pitch:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>X:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QCheckBox" name="chkEnableX">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_91">
- <property name="text">
- <string>Yaw:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Y:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QCheckBox" name="chkEnableY">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_111">
- <property name="text">
- <string>Roll:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QCheckBox" name="chkEnableZ">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
</widget>
</item>
- <item>
+ <item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp
index 70af2893..b7d078c2 100644
--- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp
+++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp
@@ -1,20 +1,17 @@
/* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */
#include "ftnoir_tracker_hydra.h"
-#include "facetracknoir/global-settings.h"
-#include "facetracknoir/rotation.h"
+#include "facetracknoir/plugin-support.h"
#include <cstdio>
#ifdef _WIN32
# define SIXENSE_STATIC_LIB
# define SIXENSE_UTILS_STATIC_LIB
#endif
#include <sixense.h>
-#include <sixense_math.hpp>
-Hydra_Tracker::Hydra_Tracker() : should_quit(false)
-{
- for (int i = 0; i < 6; i++)
- newHeadPose[i] = 0;
-}
+Hydra_Tracker::Hydra_Tracker() : should_quit(false) {}
+
+#pragma GCC diagnostic ignored "-Wreorder"
+#include <sixense_math.hpp>
Hydra_Tracker::~Hydra_Tracker()
{
@@ -38,36 +35,16 @@ void Hydra_Tracker::GetHeadPoseData(double *data)
float ypr[3];
mat.getEulerAngles().fill(ypr);
- newHeadPose[Yaw] = ypr[0];
- newHeadPose[Pitch] = ypr[1];
- newHeadPose[Roll] = ypr[2];
-
-
- newHeadPose[TX] = acd.controllers[0].pos[0]/50.0f;
- newHeadPose[TY] = acd.controllers[0].pos[1]/50.0f;
- newHeadPose[TZ] = acd.controllers[0].pos[2]/50.0f;
-
- if (s.bEnableX) {
- data[TX] = newHeadPose[TX];
- }
- if (s.bEnableY) {
- data[TY] = newHeadPose[TY];
- }
- if (s.bEnableY) {
- data[TZ] = newHeadPose[TZ];
- }
- if (s.bEnableYaw) {
- data[Yaw] = newHeadPose[Yaw] * 57.295781f;
- }
- if (s.bEnablePitch) {
- data[Pitch] = newHeadPose[Pitch] * 57.295781f;
- }
- if (s.bEnableRoll) {
- data[Roll] = newHeadPose[Roll] * 57.295781f;
- }
+ data[TX] = acd.controllers[0].pos[0]/50.0;
+ data[TY] = acd.controllers[0].pos[1]/50.0;
+ data[TZ] = acd.controllers[0].pos[2]/50.0;
+ static constexpr double r2d = 57.295781;
+ data[Yaw] = ypr[0] * r2d;
+ data[Pitch] = ypr[1] * r2d;
+ data[Roll] = ypr[2] * r2d;
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new Hydra_Tracker;
}
diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h
index 05a8b076..672efa28 100644
--- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h
+++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h
@@ -1,65 +1,49 @@
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "ui_ftnoir_hydra_clientcontrols.h"
-#include <QMessageBox>
-#include <QWaitCondition>
-#include <math.h>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "facetracknoir/options.h"
using namespace options;
struct settings {
pbundle b;
- value<bool> bEnableRoll, bEnablePitch, bEnableYaw, bEnableX, bEnableY, bEnableZ;
settings() :
- b(bundle("tracker-hydra")),
- bEnableRoll(b, "enable-rz", true),
- bEnablePitch(b, "enable-ry", true),
- bEnableYaw(b, "enable-rx", true),
- bEnableX(b, "enable-tx", true),
- bEnableY(b, "enable-ty", true),
- bEnableZ(b, "enable-tz", true)
+ b(bundle("tracker-hydra"))
{}
};
class Hydra_Tracker : public ITracker
{
public:
- Hydra_Tracker();
+ Hydra_Tracker();
~Hydra_Tracker();
- void StartTracker(QFrame *) virt_override;
- void GetHeadPoseData(double *data) virt_override;
+ void StartTracker(QFrame *) override;
+ void GetHeadPoseData(double *data) override;
volatile bool should_quit;
-protected:
- void run(); // qthread override run method
private:
settings s;
- bool isCalibrated;
- double newHeadPose[6]; // Structure with new headpose
QMutex mutex;
- virtual int preferredHz() virt_override { return 250; }
};
class TrackerControls: public QWidget, public ITrackerDialog
{
Q_OBJECT
public:
- explicit TrackerControls();
+ explicit TrackerControls();
void registerTracker(ITracker *) {}
void unRegisterTracker() {}
private:
settings s;
- Ui::UIHydraControls ui;
+ Ui::UIHydraControls ui;
private slots:
- void doOK();
- void doCancel();
+ void doOK();
+ void doCancel();
};
class FTNoIR_TrackerDll : public Metadata
{
public:
- void getFullName(QString *strToBeFilled);
- void getShortName(QString *strToBeFilled);
- void getDescription(QString *strToBeFilled);
- void getIcon(QIcon *icon);
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
};
diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp
index 14be2c37..c81ddce7 100644
--- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp
+++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp
@@ -1,5 +1,5 @@
#include "ftnoir_tracker_hydra.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
TrackerControls::TrackerControls() :
QWidget()
@@ -9,13 +9,6 @@ QWidget()
// Connect Qt signals to member-functions
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
-
- tie_setting(s.bEnableYaw, ui.chkEnableYaw);
- tie_setting(s.bEnablePitch, ui.chkEnablePitch);
- tie_setting(s.bEnableRoll, ui.chkEnableRoll);
- tie_setting(s.bEnableX, ui.chkEnableX);
- tie_setting(s.bEnableY, ui.chkEnableY);
- tie_setting(s.bEnableZ, ui.chkEnableZ);
}
void TrackerControls::doOK() {
@@ -24,11 +17,11 @@ void TrackerControls::doOK() {
}
void TrackerControls::doCancel() {
- s.b->revert();
+ s.b->reload();
close();
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
{
return new TrackerControls;
}
diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp
index a2cc7c01..18efea05 100644
--- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp
+++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp
@@ -1,7 +1,7 @@
/* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */
#include "ftnoir_tracker_hydra.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled)
{
@@ -23,16 +23,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)
*icon = QIcon(":/images/facetracknoir.png");
}
-////////////////////////////////////////////////////////////////////////////////
-// Factory function that creates instances if the Tracker object.
-
-// Export both decorated and undecorated names.
-// GetTrackerDll - Undecorated name, which can be easily used with GetProcAddress
-// Win32 API function.
-// _GetTrackerDll@0 - Common name decoration for __stdcall functions in C language.
-//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
-
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_TrackerDll;
}
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
index f9789dce..bb1076dd 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
@@ -1,17 +1,13 @@
#include "ftnoir_tracker_joystick.h"
-#include "facetracknoir/global-settings.h"
-#undef NDEBUG
+#include "facetracknoir/plugin-support.h"
#include <QMutexLocker>
FTNoIR_Tracker::FTNoIR_Tracker() :
g_pDI(nullptr),
g_pJoystick(nullptr),
- iter(-1),
- mtx(QMutex::Recursive)
+ mtx(QMutex::Recursive),
+ iter(-1)
{
- for (int i = 0; i < 6; i++)
- min_[i] = max_[i] = 0;
- GUID bar = {0};
}
void FTNoIR_Tracker::reload()
@@ -45,13 +41,13 @@ FTNoIR_Tracker::~FTNoIR_Tracker()
}
}
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
auto self = (FTNoIR_Tracker*) pContext;
- // For axes that are returned, set the DIPROP_RANGE property for the
- // enumerated axis in order to scale min/max values.
if( pdidoi->dwType & DIDFT_AXIS )
{
DIPROPRANGE diprg = {0};
@@ -59,15 +55,12 @@ static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType;
+ diprg.lMax = FTNoIR_Tracker::AXIS_MAX;
+ diprg.lMin = -FTNoIR_Tracker::AXIS_MAX;
- // Set the range for the axis
-
- if( FAILED( self->g_pJoystick->GetProperty( DIPROP_RANGE, &diprg.diph ) ) )
+ if( FAILED( self->g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_STOP;
- self->min_[self->iter] = diprg.lMin;
- self->max_[self->iter] = diprg.lMax;
- qDebug() << "axis" << self->iter << diprg.lMin << diprg.lMax;
self->iter++;
}
@@ -138,8 +131,6 @@ void FTNoIR_Tracker::StartTracker(QFrame* frame)
goto fail;
}
- qDebug() << "joy init success";
-
return;
fail:
@@ -161,18 +152,26 @@ void FTNoIR_Tracker::GetHeadPoseData(double *data)
if( !g_pDI || !g_pJoystick)
return;
- auto hr = g_pJoystick->Poll();
- if( FAILED( hr ))
- {
- hr = g_pJoystick->Acquire();
- for (int i = 0; hr == DIERR_INPUTLOST && i < 200; i++)
- hr = g_pJoystick->Acquire();
- if (hr != DI_OK)
+ bool ok = false;
+
+ for (int i = 0; i < 100; i++)
+ {
+ if (!FAILED(g_pJoystick->Poll()))
{
- qDebug() << "joy read failure" << hr;
- return;
+ ok = true;
+ break;
}
- }
+ if (g_pJoystick->Acquire() != DI_OK)
+ continue;
+ else
+ ok = true;
+ break;
+ }
+
+ if (!ok)
+ return;
+
+ HRESULT hr = 0;
if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof( js ), &js ) ) )
return;
@@ -196,35 +195,12 @@ void FTNoIR_Tracker::GetHeadPoseData(double *data)
90,
180
};
-
- int axes[] = {
- s.axis_0,
- s.axis_1,
- s.axis_2,
- s.axis_3,
- s.axis_4,
- s.axis_5
- };
-
+
for (int i = 0; i < 6; i++)
- {
- auto idx = axes[i] - 1;
- if (idx < 0 || idx > 7)
- {
- data[i] = 0;
- }
- else {
- auto mid = (min_[idx] + max_[idx]) / 2;
- auto val = values[idx] - mid;
-
- auto max = (max_[idx] - min_[idx]) / 2;
- auto min = (min_[idx] - max_[idx]) / -2;
- data[i] = val * limits[i] / (double) (val >= 0 ? max : min);
- }
- }
+ data[i] = values[i] * limits[i] / AXIS_MAX;
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new FTNoIR_Tracker;
}
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
index 06d06186..04a933db 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
@@ -5,7 +5,6 @@
* copyright notice and this permission notice appear in all copies.
*/
#pragma once
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "ui_ftnoir_tracker_joystick_controls.h"
#include <QComboBox>
#include <QCheckBox>
@@ -16,7 +15,7 @@
#include <QMutex>
#include <QFrame>
#include <cmath>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#ifndef DIRECTINPUT_VERSION
# define DIRECTINPUT_VERSION 0x800
#endif
@@ -32,21 +31,9 @@ using namespace options;
struct settings {
pbundle b;
- value<int> axis_0;
- value<int> axis_1;
- value<int> axis_2;
- value<int> axis_3;
- value<int> axis_4;
- value<int> axis_5;
value<QString> joyid;
settings() :
b(bundle("tracker-joystick")),
- axis_0(b, "axis-0", 0),
- axis_1(b, "axis-1", 0),
- axis_2(b, "axis-2", 0),
- axis_3(b, "axis-3", 0),
- axis_4(b, "axis-4", 0),
- axis_5(b, "axis-5", 0),
joyid(b, "joy-id", "")
{}
};
@@ -61,12 +48,12 @@ public:
void reload();
LPDIRECTINPUT8 g_pDI;
LPDIRECTINPUTDEVICE8 g_pJoystick;
- int min_[8], max_[8];
QMutex mtx;
QFrame* frame;
DIDEVICEINSTANCE def;
int iter; // XXX bad style
settings s;
+ static constexpr int AXIS_MAX = 65535;
};
class TrackerControls: public QWidget, public ITrackerDialog
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
index 5d349169..424d1c44 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
@@ -9,12 +9,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>216</width>
- <height>259</height>
+ <width>458</width>
+ <height>134</height>
</rect>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -32,401 +32,61 @@
<property name="autoFillBackground">
<bool>false</bool>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QGroupBox" name="groupBox_3">
+ <layout class="QFormLayout" name="formLayout">
+ <property name="horizontalSpacing">
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Joystick</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="joylist">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
- </property>
- <property name="title">
- <string>Axis enablement</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>X</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Y</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Roll</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QComboBox" name="comboBox_5">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="7" column="1">
- <widget class="QComboBox" name="comboBox_6">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QComboBox" name="comboBox_4">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="comboBox_2">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="comboBox">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Yaw</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QComboBox" name="comboBox_3">
- <item>
- <property name="text">
- <string/>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#3</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#4</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#5</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#6</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>#8</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Z</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Pitch</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Joy Id</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="joylist">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
</widget>
</item>
- <item>
+ <item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Only first 6 axes available.
+Adjust order in mapping window &quot;output remap&quot; option.</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<tabstops>
<tabstop>joylist</tabstop>
- <tabstop>comboBox</tabstop>
- <tabstop>comboBox_2</tabstop>
- <tabstop>comboBox_3</tabstop>
- <tabstop>comboBox_4</tabstop>
- <tabstop>comboBox_5</tabstop>
- <tabstop>comboBox_6</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
index b0766634..84e02fb0 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
@@ -1,5 +1,5 @@
#include "ftnoir_tracker_joystick.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
{
@@ -19,13 +19,6 @@ TrackerControls::TrackerControls() : tracker(nullptr)
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- tie_setting(s.axis_0, ui.comboBox);
- tie_setting(s.axis_1, ui.comboBox_2);
- tie_setting(s.axis_2, ui.comboBox_3);
- tie_setting(s.axis_3, ui.comboBox_4);
- tie_setting(s.axis_4, ui.comboBox_5);
- tie_setting(s.axis_5, ui.comboBox_6);
-
{
auto hr = CoInitialize( nullptr );
LPDIRECTINPUT8 g_pDI = nullptr;
@@ -56,11 +49,11 @@ void TrackerControls::doOK() {
}
void TrackerControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
{
return new TrackerControls;
}
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp
index 325d24a4..af1a9679 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp
@@ -1,6 +1,6 @@
#include "ftnoir_tracker_joystick.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled)
{
@@ -22,7 +22,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)
*icon = QIcon(":/images/facetracknoir.png");
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_TrackerDll;
}
diff --git a/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui
new file mode 100644
index 00000000..73b1f767
--- /dev/null
+++ b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui
@@ -0,0 +1,1207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICPTClientControls</class>
+ <widget class="QWidget" name="UICPTClientControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>453</width>
+ <height>621</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>PointTracker Settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="ftnoir_tracker_pt.qrc">
+ <normaloff>:/Resources/Logo_IR.png</normaloff>:/Resources/Logo_IR.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_9">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="groupBox_5">
+ <property name="title">
+ <string>Status</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_10">
+ <item row="2" column="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Extracted Points:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_38">
+ <property name="text">
+ <string>Camera Info:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox_2">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Apply</set>
+ </property>
+ <property name="centerButtons">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="caminfo_label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="pointinfo_label">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="locale">
+ <locale language="English" country="UnitedStates"/>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Camera</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Camera settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Device</string>
+ </property>
+ <property name="buddy">
+ <cstring>camdevice_combo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="camdevice_combo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumContentsLength">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_36">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Width</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="res_x_spin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Desired capture width</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>2000</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_41">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Height</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="res_y_spin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Desired capture height</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>2000</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_37">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>FPS</string>
+ </property>
+ <property name="buddy">
+ <cstring>fps_spin</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="fps_spin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Desired capture framerate</string>
+ </property>
+ <property name="suffix">
+ <string> Hz</string>
+ </property>
+ <property name="maximum">
+ <number>2000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="title">
+ <string>Camera orientation</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ <property name="buddy">
+ <cstring>camroll_combo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="camroll_combo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Rotation of the camera image</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ <property name="buddy">
+ <cstring>campitch_spin</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="campitch_spin">
+ <property name="contextMenuPolicy">
+ <enum>Qt::DefaultContextMenu</enum>
+ </property>
+ <property name="toolTip">
+ <string>The angle the camera is facing upwards</string>
+ </property>
+ <property name="suffix">
+ <string> deg</string>
+ </property>
+ <property name="minimum">
+ <number>-180</number>
+ </property>
+ <property name="maximum">
+ <number>180</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>positive = upwards</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_20">
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ <property name="buddy">
+ <cstring>camyaw_spin</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="camyaw_spin">
+ <property name="contextMenuPolicy">
+ <enum>Qt::DefaultContextMenu</enum>
+ </property>
+ <property name="toolTip">
+ <string>The angle the camera is facing leftwards</string>
+ </property>
+ <property name="suffix">
+ <string> deg</string>
+ </property>
+ <property name="prefix">
+ <string/>
+ </property>
+ <property name="minimum">
+ <number>-180</number>
+ </property>
+ <property name="maximum">
+ <number>180</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_21">
+ <property name="text">
+ <string>positve = left</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Point extraction</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_7">
+ <item row="0" column="4">
+ <widget class="QSpinBox" name="mindiam_spin">
+ <property name="toolTip">
+ <string>Minimum point diameter</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>1024</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QSlider" name="threshold_slider">
+ <property name="toolTip">
+ <string>Intensity threshold for point extraction</string>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBothSides</enum>
+ </property>
+ <property name="tickInterval">
+ <number>25</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QSpinBox" name="maxdiam_spin">
+ <property name="toolTip">
+ <string>Maximum point diameter</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>1024</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Max size</string>
+ </property>
+ <property name="buddy">
+ <cstring>maxdiam_spin</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QSlider" name="threshold_secondary_slider">
+ <property name="toolTip">
+ <string>Per pixel hysteresis width (leave left if there is little difference between dot and non-dot, move right for increased stability against pixel noise)</string>
+ </property>
+ <property name="maximum">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</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>25</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Threshold</string>
+ </property>
+ <property name="buddy">
+ <cstring>threshold_slider</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_secondary">
+ <property name="text">
+ <string>Hysteresis</string>
+ </property>
+ <property name="buddy">
+ <cstring>threshold_secondary_slider</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Min size</string>
+ </property>
+ <property name="buddy">
+ <cstring>mindiam_spin</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
+ <string>Model</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_16">
+ <item>
+ <widget class="QTabWidget" name="model_tabs">
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <property name="usesScrollButtons">
+ <bool>false</bool>
+ </property>
+ <property name="documentMode">
+ <bool>false</bool>
+ </property>
+ <property name="tabsClosable">
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="tab_5">
+ <attribute name="title">
+ <string>Clip</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox_8">
+ <property name="title">
+ <string>Model Dimensions</string>
+ </property>
+ <widget class="QSpinBox" name="clip_tlength_spin">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>35</y>
+ <width>100</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="clip_bheight_spin">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>115</y>
+ <width>100</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_44">
+ <property name="geometry">
+ <rect>
+ <x>40</x>
+ <y>55</y>
+ <width>71</width>
+ <height>111</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_side.png</pixmap>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_50">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>35</y>
+ <width>46</width>
+ <height>13</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Side</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="clip_blength_spin">
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>165</y>
+ <width>100</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="clip_theight_spin">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>75</y>
+ <width>100</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_51">
+ <property name="geometry">
+ <rect>
+ <x>255</x>
+ <y>40</y>
+ <width>46</width>
+ <height>13</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Front</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_45">
+ <property name="geometry">
+ <rect>
+ <x>265</x>
+ <y>60</y>
+ <width>21</width>
+ <height>111</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_front.png</pixmap>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_6">
+ <attribute name="title">
+ <string>Cap</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <item>
+ <widget class="QGroupBox" name="groupBox_9">
+ <property name="title">
+ <string>Model Dimensions</string>
+ </property>
+ <widget class="QLabel" name="label_46">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>90</y>
+ <width>111</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_side.png</pixmap>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_48">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>35</y>
+ <width>46</width>
+ <height>13</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Side</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="cap_length_spin">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>70</y>
+ <width>101</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_54">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>90</y>
+ <width>16</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>R</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_55">
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>85</y>
+ <width>16</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>R</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_47">
+ <property name="geometry">
+ <rect>
+ <x>270</x>
+ <y>85</y>
+ <width>81</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_front.png</pixmap>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="cap_width_spin">
+ <property name="geometry">
+ <rect>
+ <x>255</x>
+ <y>55</y>
+ <width>100</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_49">
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>35</y>
+ <width>46</width>
+ <height>13</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Front</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="cap_height_spin">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>120</y>
+ <width>116</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_7">
+ <attribute name="title">
+ <string>Custom</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox_7">
+ <property name="title">
+ <string>Model Dimensions</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_57">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>z:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5">
+ <widget class="QSpinBox" name="m2y_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_63">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>x:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QSpinBox" name="m1x_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QSpinBox" name="m1y_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="5">
+ <widget class="QSpinBox" name="m2z_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <widget class="QSpinBox" name="m2x_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="6">
+ <widget class="QLabel" name="label_56">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Location of the two remaining model points&lt;br/&gt;with respect to the reference point in default pose&lt;/p&gt;&lt;p&gt;Use any units you want, e.g. millimeters, inches, parsecs...&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QSpinBox" name="m1z_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QLabel" name="label_70">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>y:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QLabel" name="label_67">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>x:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="label_64">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt;&quot;&gt;P&lt;/span&gt;&lt;span style=&quot; font-size:16pt; vertical-align:sub;&quot;&gt;3&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_60">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt;&quot;&gt;P&lt;/span&gt;&lt;span style=&quot; font-size:16pt; vertical-align:sub;&quot;&gt;3&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4">
+ <widget class="QLabel" name="label_69">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>z:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="label_58">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>y:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_10">
+ <property name="title">
+ <string>Model position</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="tx_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="label_59">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Translation from head center to model reference point&lt;br/&gt; in default pose&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="ty_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_62">
+ <property name="text">
+ <string>y:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_66">
+ <property name="text">
+ <string>z:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_61">
+ <property name="text">
+ <string>x:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="tz_spin">
+ <property name="suffix">
+ <string> units</string>
+ </property>
+ <property name="minimum">
+ <number>-65535</number>
+ </property>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QPushButton" name="tcalib_button">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Calibrate</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>About</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_8">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;FTNoIR PointTracker Plugin&lt;br/&gt;Version 1.1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;by Patrick Ruoff&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://ftnoirpt.sourceforge.net/&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline; color:#0000ff;&quot;&gt;Manual (external)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_35">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/Logo_IR.png</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>camdevice_combo</tabstop>
+ <tabstop>res_x_spin</tabstop>
+ <tabstop>camroll_combo</tabstop>
+ <tabstop>campitch_spin</tabstop>
+ <tabstop>camyaw_spin</tabstop>
+ <tabstop>threshold_slider</tabstop>
+ <tabstop>model_tabs</tabstop>
+ <tabstop>m1x_spin</tabstop>
+ <tabstop>m1y_spin</tabstop>
+ <tabstop>m1z_spin</tabstop>
+ <tabstop>m2x_spin</tabstop>
+ <tabstop>m2y_spin</tabstop>
+ <tabstop>m2z_spin</tabstop>
+ <tabstop>tx_spin</tabstop>
+ <tabstop>ty_spin</tabstop>
+ <tabstop>tz_spin</tabstop>
+ </tabstops>
+ <resources>
+ <include location="ftnoir_tracker_pt.qrc"/>
+ </resources>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/FTNoIR_Tracker_PT/Resources/Logo_IR.png b/ftnoir_tracker_pt/Resources/Logo_IR.png
index 95032a25..95032a25 100644
--- a/FTNoIR_Tracker_PT/Resources/Logo_IR.png
+++ b/ftnoir_tracker_pt/Resources/Logo_IR.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/Resources/cap_front.png b/ftnoir_tracker_pt/Resources/cap_front.png
index 14207a67..14207a67 100644
--- a/FTNoIR_Tracker_PT/Resources/cap_front.png
+++ b/ftnoir_tracker_pt/Resources/cap_front.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/Resources/cap_side.png b/ftnoir_tracker_pt/Resources/cap_side.png
index 5ad4ee65..5ad4ee65 100644
--- a/FTNoIR_Tracker_PT/Resources/cap_side.png
+++ b/ftnoir_tracker_pt/Resources/cap_side.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/Resources/clip_front.png b/ftnoir_tracker_pt/Resources/clip_front.png
index 04880138..04880138 100644
--- a/FTNoIR_Tracker_PT/Resources/clip_front.png
+++ b/ftnoir_tracker_pt/Resources/clip_front.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/Resources/clip_side.png b/ftnoir_tracker_pt/Resources/clip_side.png
index 72667ac7..72667ac7 100644
--- a/FTNoIR_Tracker_PT/Resources/clip_side.png
+++ b/ftnoir_tracker_pt/Resources/clip_side.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/camera.cpp b/ftnoir_tracker_pt/camera.cpp
index 754533c5..7c2c09ce 100644
--- a/FTNoIR_Tracker_PT/camera.cpp
+++ b/ftnoir_tracker_pt/camera.cpp
@@ -1,351 +1,328 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
- #if defined(OPENTRACK_API) && defined(_WIN32)
-#include <windows.h>
-#include <dshow.h>
-#endif
-
-#include "camera.h"
-#include <string>
-#include <QDebug>
-
-using namespace cv;
-
-#if defined(OPENTRACK_API) && (defined(__unix) || defined(__linux) || defined(__APPLE__))
-#include <unistd.h>
-#endif
-
-#ifdef OPENTRACK_API
-void get_camera_device_names(std::vector<std::string>& device_names) {
-# if defined(_WIN32)
- // Create the System Device Enumerator.
- HRESULT hr;
- ICreateDevEnum *pSysDevEnum = NULL;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
- if (FAILED(hr))
- {
- return;
- }
- // Obtain a class enumerator for the video compressor category.
- IEnumMoniker *pEnumCat = NULL;
- hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
-
- if (hr == S_OK) {
- // Enumerate the monikers.
- IMoniker *pMoniker = NULL;
- ULONG cFetched;
- while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
- // To retrieve the filter's friendly name, do the following:
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr))
- {
- auto wstr = std::wstring(varName.bstrVal);
- auto str = std::string(wstr.begin(), wstr.end());
- device_names.push_back(str);
- }
- VariantClear(&varName);
-
- ////// To create an instance of the filter, do the following:
- ////IBaseFilter *pFilter;
- ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
- //// (void**)&pFilter);
- // Now add the filter to the graph.
- //Remember to release pFilter later.
- pPropBag->Release();
- }
- pMoniker->Release();
- }
- pEnumCat->Release();
- }
- pSysDevEnum->Release();
-# else
- for (int i = 0; i < 16; i++) {
- char buf[128];
- sprintf(buf, "/dev/video%d", i);
- if (access(buf, R_OK | W_OK) == 0) {
- device_names.push_back(std::string(buf));
- }
- }
-# endif
-}
-#else
-// ----------------------------------------------------------------------------
-void get_camera_device_names(std::vector<std::string>& device_names)
-{
- videoInput VI;
- VI.listDevices();
- std::string device_name;
- for(int index = 0; ; ++index) {
- device_name = VI.getDeviceName(index);
- if (device_name.empty()) break;
- device_names.push_back(device_name);
- }
-}
-#endif
-
-// ----------------------------------------------------------------------------
-void Camera::set_device_index(int index)
-{
- if (desired_index != index)
- {
- desired_index = index;
- _set_device_index();
-
- // reset fps
- dt_valid = 0;
- dt_mean = 0;
- active_index = index;
- }
-}
-
-void Camera::set_f(float f)
-{
- if (cam_desired.f != f)
- {
- cam_desired.f = f;
- _set_f();
- }
-}
-void Camera::set_fps(int fps)
-{
- if (cam_desired.fps != fps)
- {
- cam_desired.fps = fps;
- _set_fps();
- }
-}
-
-void Camera::set_res(int x_res, int y_res)
-{
- if (cam_desired.res_x != x_res || cam_desired.res_y != y_res)
- {
- cam_desired.res_x = x_res;
- cam_desired.res_y = y_res;
- _set_res();
- _set_fps();
- }
-}
-
-bool Camera::get_frame(float dt, cv::Mat* frame)
-{
- bool new_frame = _get_frame(frame);
- // measure fps of valid frames
- const float dt_smoothing_const = 0.9;
- dt_valid += dt;
- if (new_frame)
- {
- dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid;
- cam_info.fps = 1.0 / dt_mean;
- dt_valid = 0;
- }
- return new_frame;
-}
-
-// ----------------------------------------------------------------------------
-#ifdef OPENTRACK_API
-void CVCamera::start()
-{
- cap = new VideoCapture(desired_index);
- // extract camera info
- if (cap->isOpened())
- {
- active = true;
- active_index = desired_index;
- cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
- cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
- } else {
- delete cap;
- cap = nullptr;
- }
-}
-
-void CVCamera::stop()
-{
- if (cap)
- {
- cap->release();
- delete cap;
- }
- active = false;
-}
-
-bool CVCamera::_get_frame(Mat* frame)
-{
- if (cap && cap->isOpened())
- {
- Mat img;
- /*
- * XXX some Windows webcams fail to decode first
- * frames and then some every once in a while
- * -sh
- */
- for (int i = 0; i < 100 && !cap->read(img); i++)
- ;;
-
- if (img.empty())
- return false;
-
- *frame = img;
- return true;
- }
- return false;
-}
-
-void CVCamera::_set_index()
-{
- if (active) restart();
-}
-
-void CVCamera::_set_f()
-{
- cam_info.f = cam_desired.f;
-}
-
-void CVCamera::_set_fps()
-{
- if (cap) cap->set(CV_CAP_PROP_FPS, cam_desired.fps);
-}
-
-void CVCamera::_set_res()
-{
- if (cap)
- {
- cap->set(CV_CAP_PROP_FRAME_WIDTH, cam_desired.res_x);
- cap->set(CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y);
- cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
- cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
- }
-}
-void CVCamera::_set_device_index()
-{
- if (cap)
- {
- cap->release();
- delete cap;
- }
- cap = new VideoCapture(desired_index);
-}
-
-#else
-// ----------------------------------------------------------------------------
-VICamera::VICamera() : frame_buffer(NULL)
-{
- VI.listDevices();
-}
-
-void VICamera::start()
-{
- if (desired_index >= 0)
- {
- if (cam_desired.res_x == 0 || cam_desired.res_y == 0)
- VI.setupDevice(desired_index);
- else
- VI.setupDevice(desired_index, cam_desired.res_x, cam_desired.res_y);
-
- active = true;
- active_index = desired_index;
-
- cam_info.res_x = VI.getWidth(active_index);
- cam_info.res_y = VI.getHeight(active_index);
- new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3);
- // If matrix is not continuous we have to copy manually via frame_buffer
- if (!new_frame.isContinuous()) {
- unsigned int size = VI.getSize(active_index);
- frame_buffer = new unsigned char[size];
- }
- }
-}
-
-void VICamera::stop()
-{
- if (active)
- {
- VI.stopDevice(active_index);
- }
- if (frame_buffer)
- {
- delete[] frame_buffer;
- frame_buffer = NULL;
- }
- active = false;
-}
-
-bool VICamera::_get_frame(Mat* frame)
-{
- if (active && VI.isFrameNew(active_index))
- {
- if (new_frame.isContinuous())
- {
- VI.getPixels(active_index, new_frame.data, false, true);
- }
- else
- {
- // If matrix is not continuous we have to copy manually via frame_buffer
- VI.getPixels(active_index, frame_buffer, false, true);
- new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3, frame_buffer).clone();
- }
- *frame = new_frame;
- return true;
- }
- return false;
-}
-
-void VICamera::_set_device_index()
-{
- if (active) restart();
-}
-
-void VICamera::_set_f()
-{
- cam_info.f = cam_desired.f;
-}
-
-void VICamera::_set_fps()
-{
- bool was_active = active;
- if (active) stop();
- VI.setIdealFramerate(desired_index, cam_desired.fps);
- if (was_active) start();
-}
-
-void VICamera::_set_res()
-{
- if (active) restart();
-}
-#endif
-
-// ----------------------------------------------------------------------------
-Mat FrameRotation::rotate_frame(Mat frame)
-{
- switch (rotation)
- {
- case CLOCKWISE:
- {
- Mat dst;
- transpose(frame, dst);
- flip(dst, dst, 1);
- return dst;
- }
-
- case COUNTER_CLOCKWISE:
- {
- Mat dst;
- transpose(frame, dst);
- flip(dst, dst, 0);
- return dst;
- }
-
- default:
- return frame;
- }
-}
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+ #if defined(OPENTRACK_API) && defined(_WIN32)
+#include <windows.h>
+#include <dshow.h>
+#endif
+
+#include "camera.h"
+#include <string>
+#include <QDebug>
+
+using namespace cv;
+
+#if defined(OPENTRACK_API) && (defined(__unix) || defined(__linux) || defined(__APPLE__))
+#include <unistd.h>
+#endif
+
+#ifdef OPENTRACK_API
+void get_camera_device_names(std::vector<std::string>& device_names) {
+# if defined(_WIN32)
+ // Create the System Device Enumerator.
+ HRESULT hr;
+ ICreateDevEnum *pSysDevEnum = NULL;
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
+ if (FAILED(hr))
+ {
+ return;
+ }
+ // Obtain a class enumerator for the video compressor category.
+ IEnumMoniker *pEnumCat = NULL;
+ hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
+
+ if (hr == S_OK) {
+ // Enumerate the monikers.
+ IMoniker *pMoniker = NULL;
+ ULONG cFetched;
+ while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
+ if (SUCCEEDED(hr)) {
+ // To retrieve the filter's friendly name, do the following:
+ VARIANT varName;
+ VariantInit(&varName);
+ hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+ if (SUCCEEDED(hr))
+ {
+ auto wstr = std::wstring(varName.bstrVal);
+ auto str = std::string(wstr.begin(), wstr.end());
+ device_names.push_back(str);
+ }
+ VariantClear(&varName);
+
+ ////// To create an instance of the filter, do the following:
+ ////IBaseFilter *pFilter;
+ ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
+ //// (void**)&pFilter);
+ // Now add the filter to the graph.
+ //Remember to release pFilter later.
+ pPropBag->Release();
+ }
+ pMoniker->Release();
+ }
+ pEnumCat->Release();
+ }
+ pSysDevEnum->Release();
+# else
+ for (int i = 0; i < 16; i++) {
+ char buf[128];
+ sprintf(buf, "/dev/video%d", i);
+ if (access(buf, R_OK | W_OK) == 0) {
+ device_names.push_back(std::string(buf));
+ }
+ }
+# endif
+}
+#else
+// ----------------------------------------------------------------------------
+void get_camera_device_names(std::vector<std::string>& device_names)
+{
+ videoInput VI;
+ VI.listDevices();
+ std::string device_name;
+ for(int index = 0; ; ++index) {
+ device_name = VI.getDeviceName(index);
+ if (device_name.empty()) break;
+ device_names.push_back(device_name);
+ }
+}
+#endif
+
+// ----------------------------------------------------------------------------
+void Camera::set_device_index(int index)
+{
+ if (desired_index != index)
+ {
+ desired_index = index;
+ _set_device_index();
+
+ // reset fps
+ dt_valid = 0;
+ dt_mean = 0;
+ active_index = index;
+ }
+}
+
+void Camera::set_fps(int fps)
+{
+ if (cam_desired.fps != fps)
+ {
+ cam_desired.fps = fps;
+ _set_fps();
+ }
+}
+
+void Camera::set_res(int x_res, int y_res)
+{
+ if (cam_desired.res_x != x_res || cam_desired.res_y != y_res)
+ {
+ cam_desired.res_x = x_res;
+ cam_desired.res_y = y_res;
+ _set_res();
+ _set_fps();
+ }
+}
+
+bool Camera::get_frame(float dt, cv::Mat* frame)
+{
+ bool new_frame = _get_frame(frame);
+ // measure fps of valid frames
+ const float dt_smoothing_const = 0.9;
+ dt_valid += dt;
+ if (new_frame)
+ {
+ dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid;
+ cam_info.fps = dt_mean > 1e-3 ? 1.0 / dt_mean : 0;
+ dt_valid = 0;
+ }
+ return new_frame;
+}
+
+// ----------------------------------------------------------------------------
+#ifdef OPENTRACK_API
+void CVCamera::start()
+{
+ cap = new VideoCapture(desired_index);
+ // extract camera info
+ if (cap->isOpened())
+ {
+ active = true;
+ active_index = desired_index;
+ cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
+ cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
+ } else {
+ delete cap;
+ cap = nullptr;
+ }
+}
+
+void CVCamera::stop()
+{
+ if (cap)
+ {
+ cap->release();
+ delete cap;
+ }
+ active = false;
+}
+
+bool CVCamera::_get_frame(Mat* frame)
+{
+ if (cap && cap->isOpened())
+ {
+ Mat img;
+ for (int i = 0; i < 100 && !cap->read(img); i++)
+ ;;
+
+ if (img.empty())
+ return false;
+
+ *frame = img;
+ return true;
+ }
+ return false;
+}
+
+void CVCamera::_set_fps()
+{
+ if (cap) cap->set(CV_CAP_PROP_FPS, cam_desired.fps);
+}
+
+void CVCamera::_set_res()
+{
+ if (cap)
+ {
+ cap->set(CV_CAP_PROP_FRAME_WIDTH, cam_desired.res_x);
+ cap->set(CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y);
+ cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
+ cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
+ }
+}
+void CVCamera::_set_device_index()
+{
+ if (cap)
+ {
+ cap->release();
+ delete cap;
+ }
+ cap = new VideoCapture(desired_index);
+}
+
+#else
+// ----------------------------------------------------------------------------
+VICamera::VICamera() : frame_buffer(NULL)
+{
+ VI.listDevices();
+}
+
+void VICamera::start()
+{
+ if (desired_index >= 0)
+ {
+ if (cam_desired.res_x == 0 || cam_desired.res_y == 0)
+ VI.setupDevice(desired_index);
+ else
+ VI.setupDevice(desired_index, cam_desired.res_x, cam_desired.res_y);
+
+ active = true;
+ active_index = desired_index;
+
+ cam_info.res_x = VI.getWidth(active_index);
+ cam_info.res_y = VI.getHeight(active_index);
+ new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3);
+ // If matrix is not continuous we have to copy manually via frame_buffer
+ if (!new_frame.isContinuous()) {
+ unsigned int size = VI.getSize(active_index);
+ frame_buffer = new unsigned char[size];
+ }
+ }
+}
+
+void VICamera::stop()
+{
+ if (active)
+ {
+ VI.stopDevice(active_index);
+ }
+ if (frame_buffer)
+ {
+ delete[] frame_buffer;
+ frame_buffer = NULL;
+ }
+ active = false;
+}
+
+bool VICamera::_get_frame(Mat* frame)
+{
+ if (active && VI.isFrameNew(active_index))
+ {
+ if (new_frame.isContinuous())
+ {
+ VI.getPixels(active_index, new_frame.data, false, true);
+ }
+ else
+ {
+ // If matrix is not continuous we have to copy manually via frame_buffer
+ VI.getPixels(active_index, frame_buffer, false, true);
+ new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3, frame_buffer).clone();
+ }
+ *frame = new_frame;
+ return true;
+ }
+ return false;
+}
+
+void VICamera::_set_device_index()
+{
+ if (active) restart();
+}
+
+void VICamera::_set_f()
+{
+ cam_info.f = cam_desired.f;
+}
+
+void VICamera::_set_fps()
+{
+ bool was_active = active;
+ if (active) stop();
+ VI.setIdealFramerate(desired_index, cam_desired.fps);
+ if (was_active) start();
+}
+
+void VICamera::_set_res()
+{
+ if (active) restart();
+}
+#endif
+
+// ----------------------------------------------------------------------------
+Mat FrameRotation::rotate_frame(Mat frame)
+{
+ switch (rotation)
+ {
+ case CLOCKWISE:
+ {
+ Mat dst;
+ transpose(frame, dst);
+ flip(dst, dst, 1);
+ return dst;
+ }
+
+ case COUNTER_CLOCKWISE:
+ {
+ Mat dst;
+ transpose(frame, dst);
+ flip(dst, dst, 0);
+ return dst;
+ }
+
+ default:
+ return frame;
+ }
+}
diff --git a/FTNoIR_Tracker_PT/camera.h b/ftnoir_tracker_pt/camera.h
index ea68c387..889bf2d3 100644
--- a/FTNoIR_Tracker_PT/camera.h
+++ b/ftnoir_tracker_pt/camera.h
@@ -1,145 +1,141 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef CAMERA_H
-#define CAMERA_H
-
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-# include <opencv2/highgui/highgui.hpp>
-# include <opencv2/highgui/highgui_c.h>
-#endif
-#include <string>
-
-// ----------------------------------------------------------------------------
-void get_camera_device_names(std::vector<std::string>& device_names);
-
-
-// ----------------------------------------------------------------------------
-struct CamInfo
-{
- CamInfo() : res_x(0), res_y(0), fps(0), f(1) {}
-
- int res_x;
- int res_y;
- int fps;
- float f; // (focal length) / (sensor width)
-};
-
-// ----------------------------------------------------------------------------
-// Base class for cameras, calculates the frame rate
-class Camera
-{
-public:
- Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1), active(false) {}
- virtual ~Camera() {}
-
- // start/stop capturing
- virtual void start() = 0;
- virtual void stop() = 0;
- void restart() { stop(); start(); }
-
- // calls corresponding template methods and reinitializes frame rate calculation
- void set_device_index(int index);
- void set_f(float f);
- void set_fps(int fps);
- void set_res(int x_res, int y_res);
-
- // gets a frame from the camera, dt: time since last call in seconds
- bool get_frame(float dt, cv::Mat* frame);
-
- // WARNING: returned references are valid as long as object
- const CamInfo& get_info() const { return cam_info; }
- const CamInfo& get_desired() const { return cam_desired; }
-
-protected:
- // get a frame from the camera
- virtual bool _get_frame(cv::Mat* frame) = 0;
-
- // update the camera using cam_desired, write res and f to cam_info if successful
- virtual void _set_device_index() = 0;
- virtual void _set_f() = 0;
- virtual void _set_fps() = 0;
- virtual void _set_res() = 0;
-
- float dt_valid;
- float dt_mean;
- int desired_index;
- int active_index;
- bool active;
- CamInfo cam_info;
- CamInfo cam_desired;
-};
-
-
-// ----------------------------------------------------------------------------
-// camera based on OpenCV's videoCapture
-#ifdef OPENTRACK_API
-class CVCamera : public Camera
-{
-public:
- CVCamera() : cap(NULL) {}
- ~CVCamera() { stop(); }
-
- virtual void start();
- virtual void stop();
-
-protected:
- virtual bool _get_frame(cv::Mat* frame);
- virtual void _set_index();
- virtual void _set_f();
- virtual void _set_fps();
- virtual void _set_res();
- virtual void _set_device_index();
-
- cv::VideoCapture* cap;
-};
-#else
-// ----------------------------------------------------------------------------
-// Camera based on the videoInput library
-class VICamera : public Camera
-{
-public:
- VICamera();
- ~VICamera() { stop(); }
-
- virtual void start();
- virtual void stop();
-
-protected:
- virtual bool _get_frame(cv::Mat* frame);
- virtual void _set_device_index();
- virtual void _set_f();
- virtual void _set_fps();
- virtual void _set_res();
-
- videoInput VI;
- cv::Mat new_frame;
- unsigned char* frame_buffer;
-};
-#endif
-
-enum RotationType
-{
- CLOCKWISE = 0,
- ZERO = 1,
- COUNTER_CLOCKWISE = 2
-};
-
-// ----------------------------------------------------------------------------
-class FrameRotation
-{
-public:
- RotationType rotation;
-
- cv::Mat rotate_frame(cv::Mat frame);
-};
-
-#endif //CAMERA_H
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include <opencv2/core/core.hpp>
+#ifndef OPENTRACK_API
+# include <boost/shared_ptr.hpp>
+#else
+# include <memory>
+# include <opencv2/highgui/highgui.hpp>
+# include <opencv2/highgui/highgui_c.h>
+#endif
+#include <string>
+
+// ----------------------------------------------------------------------------
+void get_camera_device_names(std::vector<std::string>& device_names);
+
+
+// ----------------------------------------------------------------------------
+struct CamInfo
+{
+ CamInfo() : res_x(0), res_y(0), fps(0) {}
+
+ int res_x;
+ int res_y;
+ int fps;
+};
+
+// ----------------------------------------------------------------------------
+// Base class for cameras, calculates the frame rate
+class Camera
+{
+public:
+ Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1), active(false) {}
+ virtual ~Camera() = 0;
+
+ // start/stop capturing
+ virtual void start() = 0;
+ virtual void stop() = 0;
+ void restart() { stop(); start(); }
+
+ // calls corresponding template methods and reinitializes frame rate calculation
+ void set_device_index(int index);
+ void set_fps(int fps);
+ void set_res(int x_res, int y_res);
+
+ // gets a frame from the camera, dt: time since last call in seconds
+ bool get_frame(float dt, cv::Mat* frame);
+
+ // WARNING: returned references are valid as long as object
+ const CamInfo& get_info() const { return cam_info; }
+ const CamInfo& get_desired() const { return cam_desired; }
+
+protected:
+ // get a frame from the camera
+ virtual bool _get_frame(cv::Mat* frame) = 0;
+
+ // update the camera using cam_desired, write res and f to cam_info if successful
+ virtual void _set_device_index() = 0;
+ virtual void _set_fps() = 0;
+ virtual void _set_res() = 0;
+private:
+ float dt_valid;
+ float dt_mean;
+protected:
+ int desired_index;
+ int active_index;
+ bool active;
+ CamInfo cam_info;
+ CamInfo cam_desired;
+};
+inline Camera::~Camera() {}
+
+// ----------------------------------------------------------------------------
+// camera based on OpenCV's videoCapture
+#ifdef OPENTRACK_API
+class CVCamera : public Camera
+{
+public:
+ CVCamera() : cap(NULL) {}
+ ~CVCamera() { stop(); }
+
+ void start() override;
+ void stop() override;
+
+protected:
+ bool _get_frame(cv::Mat* frame) override;
+ void _set_fps() override;
+ void _set_res() override;
+ void _set_device_index() override;
+
+private:
+ cv::VideoCapture* cap;
+};
+#else
+// ----------------------------------------------------------------------------
+// Camera based on the videoInput library
+class VICamera : public Camera
+{
+public:
+ VICamera();
+ ~VICamera() { stop(); }
+
+ virtual void start();
+ virtual void stop();
+
+protected:
+ virtual bool _get_frame(cv::Mat* frame);
+ virtual void _set_device_index();
+ virtual void _set_fps();
+ virtual void _set_res();
+
+ videoInput VI;
+ cv::Mat new_frame;
+ unsigned char* frame_buffer;
+};
+#endif
+
+enum RotationType
+{
+ CLOCKWISE = 0,
+ ZERO = 1,
+ COUNTER_CLOCKWISE = 2
+};
+
+// ----------------------------------------------------------------------------
+class FrameRotation
+{
+public:
+ RotationType rotation;
+
+ cv::Mat rotate_frame(cv::Mat frame);
+};
+
+#endif //CAMERA_H
diff --git a/FTNoIR_Tracker_PT/doc/index.htm b/ftnoir_tracker_pt/doc/index.htm
index 87b7356f..87b7356f 100644
--- a/FTNoIR_Tracker_PT/doc/index.htm
+++ b/ftnoir_tracker_pt/doc/index.htm
diff --git a/FTNoIR_Tracker_PT/doc/logo.png b/ftnoir_tracker_pt/doc/logo.png
index 95032a25..95032a25 100644
--- a/FTNoIR_Tracker_PT/doc/logo.png
+++ b/ftnoir_tracker_pt/doc/logo.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/doc/ptrack.ico b/ftnoir_tracker_pt/doc/ptrack.ico
index c4b2aedc..c4b2aedc 100644
--- a/FTNoIR_Tracker_PT/doc/ptrack.ico
+++ b/ftnoir_tracker_pt/doc/ptrack.ico
Binary files differ
diff --git a/FTNoIR_Tracker_PT/doc/settings1.png b/ftnoir_tracker_pt/doc/settings1.png
index 35b84c5c..35b84c5c 100644
--- a/FTNoIR_Tracker_PT/doc/settings1.png
+++ b/ftnoir_tracker_pt/doc/settings1.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/doc/settings2.png b/ftnoir_tracker_pt/doc/settings2.png
index c6cfd1f3..c6cfd1f3 100644
--- a/FTNoIR_Tracker_PT/doc/settings2.png
+++ b/ftnoir_tracker_pt/doc/settings2.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/doc/settings3.png b/ftnoir_tracker_pt/doc/settings3.png
index 5922403d..5922403d 100644
--- a/FTNoIR_Tracker_PT/doc/settings3.png
+++ b/ftnoir_tracker_pt/doc/settings3.png
Binary files differ
diff --git a/FTNoIR_Tracker_PT/doc/style.css b/ftnoir_tracker_pt/doc/style.css
index a8d3e333..0c3d29a6 100644
--- a/FTNoIR_Tracker_PT/doc/style.css
+++ b/ftnoir_tracker_pt/doc/style.css
@@ -1,131 +1,131 @@
-body {
- width: 1000px;
- font-size: 13px;
- color: #000000;
- padding: 0;
- margin: 0 auto;
- background: #444444;
- font-family: verdana,arial;
-}
-
-table {
- border-width: 3px;
- border-color: #0000FF;
- border-style: ridge;
- margin-top: 5px;
- background-color: #E0E0FF;
-}
-
-table.blind {
- border: none;
- background-color: #E6E6E6;
-}
-
-fieldset.blind {
- border: none;
-}
-
-h1 { font-size: 160%; }
-h2 { font-size: 140%; }
-h3 { font-size: 115%; }
-
-.indent {
- margin-left: 25px;
-}
-
-p
-{
- margin-left: 10px;
-}
-
-li
-{
- margin: 10px;
-}
-
-
-dl
-{
- /*width: 80%;*/
- border-bottom: 1px solid #999;
-}
-
-dt
-{
- padding-top: 5px;
- font-weight: bold;
- border-top: 1px solid #999;
-}
-
-dd
-{
- padding: 5px;
-}
-
-
-hr {
- color: #688938;
-}
-
-a:link, a:visited {
- color: #0000BF;
-}
-a:hover {
- color: #0000FF;
-}
-
-a.nav {
- position: relative;
- top: -30px;
- display: block;
- visibility: hidden;
-}
-
-#navbar {
- width: 1000px;
- height: 30px;
- background-color:#1a1a1b;
- position: fixed;
- margin: 0 auto;
- padding: 0;
-}
-
-#navbar ul
-{
- list-style-type: none;
- margin: 0 auto;
- padding: 0;
- overflow: hidden;
-}
-
-#navbar li
-{
- margin: 0 auto;
- padding: 5px;
- float:left;
-}
-
-#navbar a:link,a:visited
-{
- display:block;
- width:150px;
- font-weight:bold;
- color:#e85d02;
- text-align:center;
- /*padding:4px;*/
- text-decoration:none;
- /*text-transform:uppercase;*/
-}
-
-#navbar a:hover,a:active
-{
- color:#ffffff;
-}
-
-#content {
- background-color:#ffffff;
- padding: 15px;
- padding-top: 40px;
- padding-right: 40px;
- margin: 0 auto;
-}
+body {
+ width: 1000px;
+ font-size: 13px;
+ color: #000000;
+ padding: 0;
+ margin: 0 auto;
+ background: #444444;
+ font-family: verdana,arial;
+}
+
+table {
+ border-width: 3px;
+ border-color: #0000FF;
+ border-style: ridge;
+ margin-top: 5px;
+ background-color: #E0E0FF;
+}
+
+table.blind {
+ border: none;
+ background-color: #E6E6E6;
+}
+
+fieldset.blind {
+ border: none;
+}
+
+h1 { font-size: 160%; }
+h2 { font-size: 140%; }
+h3 { font-size: 115%; }
+
+.indent {
+ margin-left: 25px;
+}
+
+p
+{
+ margin-left: 10px;
+}
+
+li
+{
+ margin: 10px;
+}
+
+
+dl
+{
+ /*width: 80%;*/
+ border-bottom: 1px solid #999;
+}
+
+dt
+{
+ padding-top: 5px;
+ font-weight: bold;
+ border-top: 1px solid #999;
+}
+
+dd
+{
+ padding: 5px;
+}
+
+
+hr {
+ color: #688938;
+}
+
+a:link, a:visited {
+ color: #0000BF;
+}
+a:hover {
+ color: #0000FF;
+}
+
+a.nav {
+ position: relative;
+ top: -30px;
+ display: block;
+ visibility: hidden;
+}
+
+#navbar {
+ width: 1000px;
+ height: 30px;
+ background-color:#1a1a1b;
+ position: fixed;
+ margin: 0 auto;
+ padding: 0;
+}
+
+#navbar ul
+{
+ list-style-type: none;
+ margin: 0 auto;
+ padding: 0;
+ overflow: hidden;
+}
+
+#navbar li
+{
+ margin: 0 auto;
+ padding: 5px;
+ float:left;
+}
+
+#navbar a:link,a:visited
+{
+ display:block;
+ width:150px;
+ font-weight:bold;
+ color:#e85d02;
+ text-align:center;
+ /*padding:4px;*/
+ text-decoration:none;
+ /*text-transform:uppercase;*/
+}
+
+#navbar a:hover,a:active
+{
+ color:#ffffff;
+}
+
+#content {
+ background-color:#ffffff;
+ padding: 15px;
+ padding-top: 40px;
+ padding-right: 40px;
+ margin: 0 auto;
+}
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
index ef72f9a2..8b77b681 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.cpp
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
@@ -1,265 +1,226 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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 <QHBoxLayout>
-#include <cmath>
-#include <QDebug>
-#include <QFile>
-#include <QCoreApplication>
-
-using namespace std;
-using namespace cv;
-using namespace boost;
-
-//#define PT_PERF_LOG //log performance
-
-const float rad2deg = 180.0/3.14159265;
-const float deg2rad = 1.0/rad2deg;
-
-//-----------------------------------------------------------------------------
-Tracker::Tracker()
- : mutex(QMutex::Recursive),
- commands(0),
- video_widget(NULL),
- video_frame(NULL),
- tracking_valid(false),
- new_settings(nullptr)
-
-{
- qDebug()<<"Tracker::Tracker";
-}
-
-Tracker::~Tracker()
-{
- qDebug()<<"Tracker::~Tracker";
- // terminate tracker thread
- set_command(ABORT);
- wait();
- s.video_widget = false;
- delete video_widget;
- video_widget = NULL;
- if (video_frame->layout()) delete video_frame->layout();
-}
-
-void Tracker::set_command(Command command)
-{
- //QMutexLocker lock(&mutex);
- commands |= command;
-}
-
-void Tracker::reset_command(Command command)
-{
- //QMutexLocker lock(&mutex);
- commands &= ~command;
-}
-
-void Tracker::run()
-{
- qDebug()<<"Tracker:: Thread started";
-
-#ifdef PT_PERF_LOG
- QFile log_file(QCoreApplication::applicationDirPath() + "/PointTrackerPerformance.txt");
- if (!log_file.open(QIODevice::WriteOnly | QIODevice::Text)) return;
- QTextStream log_stream(&log_file);
-#endif
-
- time.start();
- double dt;
- bool new_frame;
- forever
- {
- if (commands & ABORT) break;
- if (commands & PAUSE) continue;
- commands = 0;
- apply_inner();
- dt = time.start() / 1000000000.;
-
- new_frame = camera.get_frame(dt, &frame);
-
- if (new_frame && !frame.empty())
- {
- QMutexLocker lock(&mutex);
-
- frame = frame_rotation.rotate_frame(frame);
- const std::vector<cv::Vec2f>& points = point_extractor.extract_points(frame, dt, true);
- for (auto p : points)
- {
- auto p2 = cv::Point(p[0] * frame.cols + frame.cols/2, -p[1] * frame.cols + frame.rows/2);
- cv::Scalar color(0, 255, 0);
- cv::line(frame,
- cv::Point(p2.x - 20, p2.y),
- cv::Point(p2.x + 20, p2.y),
- color,
- 4);
- cv::line(frame,
- cv::Point(p2.x, p2.y - 20),
- cv::Point(p2.x, p2.y + 20),
- color,
- 4);
- }
- tracking_valid = point_tracker.track(points, camera.get_info().f, dt);
- video_widget->update_image(frame);
- }
-#ifdef PT_PERF_LOG
- log_stream<<"dt: "<<dt;
- if (!frame.empty()) log_stream<<" fps: "<<camera.get_info().fps;
- log_stream<<"\n";
-#endif
- }
-
- qDebug()<<"Tracker:: Thread stopping";
-}
-void Tracker::apply(settings& s)
-{
- // caller guarantees object lifetime
- new_settings = &s;
-}
-
-void Tracker::apply_inner()
-{
- settings* tmp = new_settings.exchange(nullptr);
- if (tmp == nullptr)
- return;
- auto& s = *tmp;
- qDebug()<<"Tracker:: Applying settings";
- camera.set_device_index(s.cam_index);
- camera.set_res(s.cam_res_x, s.cam_res_y);
- camera.set_fps(s.cam_fps);
- camera.set_f(s.cam_f);
- frame_rotation.rotation = static_cast<RotationType>(static_cast<int>(s.cam_roll));
- point_extractor.threshold_val = s.threshold;
- point_extractor.threshold_secondary_val = s.threshold_secondary;
- point_extractor.min_size = s.min_point_size;
- point_extractor.max_size = s.max_point_size;
- {
- cv::Vec3f M01(s.m01_x, s.m01_y, s.m01_z);
- cv::Vec3f M02(s.m02_x, s.m02_y, s.m02_z);
- point_tracker.point_model = boost::shared_ptr<PointModel>(new PointModel(M01, M02));
- }
- point_tracker.dynamic_pose_resolution = s.dyn_pose_res;
- point_tracker.dt_reset = s.reset_time / 1000.0;
- t_MH = cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z);
- R_GC = Matx33f( cos(deg2rad*s.cam_yaw), 0, sin(deg2rad*s.cam_yaw),
- 0, 1, 0,
- -sin(deg2rad*s.cam_yaw), 0, cos(deg2rad*s.cam_yaw));
- R_GC = R_GC * Matx33f( 1, 0, 0,
- 0, cos(deg2rad*s.cam_pitch), sin(deg2rad*s.cam_pitch),
- 0, -sin(deg2rad*s.cam_pitch), cos(deg2rad*s.cam_pitch));
-
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- X_GH_0 = R_GC * X_MH;
-
- qDebug()<<"Tracker::apply ends";
-}
-
-void Tracker::reset()
-{
- QMutexLocker lock(&mutex);
- point_tracker.reset();
-}
-
-void Tracker::center()
-{
- point_tracker.reset(); // we also do a reset here since there is no reset shortkey yet
- QMutexLocker lock(&mutex);
- FrameTrafo X_CM_0 = point_tracker.get_pose();
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- X_GH_0 = R_GC * X_CM_0 * X_MH;
-}
-
-bool Tracker::get_frame_and_points(cv::Mat& frame_copy, boost::shared_ptr< std::vector<Vec2f> >& points)
-{
- QMutexLocker lock(&mutex);
- if (frame.empty()) return false;
-
- // copy the frame and points from the tracker thread
- frame_copy = frame.clone();
- points = boost::shared_ptr< vector<Vec2f> >(new vector<Vec2f>(point_extractor.get_points()));
- return true;
-}
-
-void Tracker::refreshVideo()
-{
- if (video_widget) video_widget->update_frame_and_points();
-}
-
-void Tracker::StartTracker(QFrame *parent_window)
-{
- this->video_frame = parent_window;
- video_frame->setAttribute(Qt::WA_NativeWindow);
- video_frame->show();
- video_widget = new PTVideoWidget(video_frame, this);
- QHBoxLayout* video_layout = new QHBoxLayout(parent_window);
- video_layout->setContentsMargins(0, 0, 0, 0);
- video_layout->addWidget(video_widget);
- video_frame->setLayout(video_layout);
- video_widget->resize(video_frame->width(), video_frame->height());
- camera.start();
- apply(s);
- start();
- reset_command(PAUSE);
-}
-
-#ifndef OPENTRACK_API
-void Tracker::StopTracker(bool exit)
-{
- set_command(PAUSE);
-}
-#endif
-
-#ifdef OPENTRACK_API
-#define THeadPoseData double
-#endif
-
-void Tracker::GetHeadPoseData(THeadPoseData *data)
-{
- {
- QMutexLocker lock(&mutex);
-
- if (!tracking_valid) return;
-
- FrameTrafo X_CM = point_tracker.get_pose();
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- FrameTrafo X_GH = R_GC * X_CM * X_MH;
- Matx33f R = X_GH.R * X_GH_0.R.t();
- Vec3f t = X_GH.t - X_GH_0.t;
-
- // get translation(s)
- if (s.bEnableX) data[TX] = t[0] / 10.0; // convert to cm
- if (s.bEnableY) data[TY] = t[1] / 10.0;
- if (s.bEnableZ) data[TZ] = t[2] / 10.0;
-
- // translate rotation matrix from opengl (G) to roll-pitch-yaw (E) frame
- // -z -> x, y -> z, x -> -y
- Matx33f R_EG( 0, 0,-1,
- -1, 0, 0,
- 0, 1, 0);
- R = R_EG * R * R_EG.t();
-
- // extract rotation angles
- float alpha, beta, gamma;
- beta = atan2( -R(2,0), sqrt(R(2,1)*R(2,1) + R(2,2)*R(2,2)) );
- alpha = atan2( R(1,0), R(0,0));
- gamma = atan2( R(2,1), R(2,2));
-
- if (s.bEnableYaw) data[Yaw] = rad2deg * alpha;
- if (s.bEnablePitch) data[Pitch] = - rad2deg * beta; // FTNoIR expects a minus here
- if (s.bEnableRoll) data[Roll] = rad2deg * gamma;
- }
-}
-
-//-----------------------------------------------------------------------------
-#ifdef OPENTRACK_API
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
-#else
-#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
-FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
-#endif
-{
- return new Tracker;
-}
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 <QHBoxLayout>
+#include <cmath>
+#include <QDebug>
+#include <QFile>
+#include <QCoreApplication>
+
+using namespace std;
+using namespace cv;
+
+//#define PT_PERF_LOG //log performance
+
+//-----------------------------------------------------------------------------
+Tracker::Tracker()
+ : mutex(QMutex::Recursive),
+ commands(0),
+ video_widget(NULL),
+ video_frame(NULL),
+ new_settings(nullptr)
+{
+}
+
+Tracker::~Tracker()
+{
+ set_command(ABORT);
+ wait();
+ delete video_widget;
+ video_widget = NULL;
+ if (video_frame->layout()) delete video_frame->layout();
+}
+
+void Tracker::set_command(Command command)
+{
+ //QMutexLocker lock(&mutex);
+ commands |= command;
+}
+
+void Tracker::reset_command(Command command)
+{
+ //QMutexLocker lock(&mutex);
+ commands &= ~command;
+}
+
+void Tracker::run()
+{
+#ifdef PT_PERF_LOG
+ QFile log_file(QCoreApplication::applicationDirPath() + "/PointTrackerPerformance.txt");
+ if (!log_file.open(QIODevice::WriteOnly | QIODevice::Text)) return;
+ QTextStream log_stream(&log_file);
+#endif
+ time.start();
+ while((commands & ABORT) == 0)
+ {
+ apply_inner();
+ const double dt = time.start() * 1e-9;
+ const bool new_frame = camera.get_frame(dt, &frame);
+
+ if (new_frame && !frame.empty())
+ {
+ QMutexLocker lock(&mutex);
+
+ frame = frame_rotation.rotate_frame(frame);
+ const std::vector<cv::Vec2f>& points = point_extractor.extract_points(frame);
+ for (auto p : points)
+ {
+ auto p2 = cv::Point(p[0] * frame.cols + frame.cols/2, -p[1] * frame.cols + frame.rows/2);
+ cv::Scalar color(0, 255, 0);
+ cv::line(frame,
+ cv::Point(p2.x - 20, p2.y),
+ cv::Point(p2.x + 20, p2.y),
+ color,
+ 4);
+ cv::line(frame,
+ cv::Point(p2.x, p2.y - 20),
+ cv::Point(p2.x, p2.y + 20),
+ color,
+ 4);
+ }
+ if (points.size() == PointModel::N_POINTS)
+ point_tracker.track(points, model);
+ video_widget->update_image(frame);
+ }
+#ifdef PT_PERF_LOG
+ log_stream<<"dt: "<<dt;
+ if (!frame.empty()) log_stream<<" fps: "<<camera.get_info().fps;
+ log_stream<<"\n";
+#endif
+ }
+
+ qDebug()<<"Tracker:: Thread stopping";
+}
+void Tracker::apply(settings& s)
+{
+ // caller guarantees object lifetime
+ new_settings = &s;
+}
+
+void Tracker::apply_inner()
+{
+ settings* tmp = new_settings.exchange(nullptr);
+ if (tmp == nullptr)
+ return;
+ reset();
+ auto& s = *tmp;
+ qDebug()<<"Tracker:: Applying settings";
+
+ {
+ cv::Vec3f M01(s.m01_x, s.m01_y, s.m01_z);
+ cv::Vec3f M02(s.m02_x, s.m02_y, s.m02_z);
+ model = PointModel(M01, M02);
+ }
+ camera.set_device_index(s.cam_index);
+ camera.set_res(s.cam_res_x, s.cam_res_y);
+ camera.set_fps(s.cam_fps);
+ frame_rotation.rotation = static_cast<RotationType>(static_cast<int>(s.cam_roll));
+ point_extractor.threshold_val = s.threshold;
+ point_extractor.threshold_secondary_val = s.threshold_secondary;
+ point_extractor.min_size = s.min_point_size;
+ point_extractor.max_size = s.max_point_size;
+ t_MH = cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z);
+ R_GC = Matx33f( cos(deg2rad*s.cam_yaw), 0, sin(deg2rad*s.cam_yaw),
+ 0, 1, 0,
+ -sin(deg2rad*s.cam_yaw), 0, cos(deg2rad*s.cam_yaw));
+ R_GC = R_GC * Matx33f( 1, 0, 0,
+ 0, cos(deg2rad*s.cam_pitch), sin(deg2rad*s.cam_pitch),
+ 0, -sin(deg2rad*s.cam_pitch), cos(deg2rad*s.cam_pitch));
+
+ FrameTrafo X_MH(Matx33f::eye(), t_MH);
+ X_GH_0 = R_GC * X_MH;
+ qDebug()<<"Tracker::apply ends";
+}
+
+void Tracker::reset()
+{
+ QMutexLocker lock(&mutex);
+ point_tracker.reset();
+}
+
+void Tracker::center()
+{
+ point_tracker.reset(); // we also do a reset here since there is no reset shortkey yet
+ QMutexLocker lock(&mutex);
+ FrameTrafo X_CM_0 = point_tracker.get_pose();
+ FrameTrafo X_MH(Matx33f::eye(), t_MH);
+ X_GH_0 = R_GC * X_CM_0 * X_MH;
+}
+
+void Tracker::StartTracker(QFrame *parent_window)
+{
+ this->video_frame = parent_window;
+ video_frame->setAttribute(Qt::WA_NativeWindow);
+ video_frame->show();
+ video_widget = new PTVideoWidget(video_frame);
+ QHBoxLayout* video_layout = new QHBoxLayout(parent_window);
+ video_layout->setContentsMargins(0, 0, 0, 0);
+ video_layout->addWidget(video_widget);
+ video_frame->setLayout(video_layout);
+ video_widget->resize(video_frame->width(), video_frame->height());
+ camera.start();
+ apply(s);
+ start();
+}
+
+#ifndef OPENTRACK_API
+void Tracker::StopTracker(bool exit)
+{
+ set_command(PAUSE);
+}
+#endif
+
+#ifdef OPENTRACK_API
+#define THeadPoseData double
+#endif
+
+void Tracker::GetHeadPoseData(THeadPoseData *data)
+{
+ {
+ QMutexLocker lock(&mutex);
+
+ FrameTrafo X_CM = point_tracker.get_pose();
+ FrameTrafo X_MH(Matx33f::eye(), t_MH);
+ FrameTrafo X_GH = R_GC * X_CM * X_MH;
+ Matx33f R = X_GH.R * X_GH_0.R.t();
+ Vec3f t = X_GH.t - X_GH_0.t;
+
+ // get translation(s)
+ data[TX] = t[0] / 10.0; // convert to cm
+ data[TY] = t[1] / 10.0;
+ data[TZ] = t[2] / 10.0;
+
+ // translate rotation matrix from opengl (G) to roll-pitch-yaw (E) frame
+ // -z -> x, y -> z, x -> -y
+ Matx33f R_EG( 0, 0,-1,
+ -1, 0, 0,
+ 0, 1, 0);
+ R = R_EG * R * R_EG.t();
+
+ // extract rotation angles
+ float alpha, beta, gamma;
+ beta = atan2( -R(2,0), sqrt(R(2,1)*R(2,1) + R(2,2)*R(2,2)) );
+ alpha = atan2( R(1,0), R(0,0));
+ gamma = atan2( R(2,1), R(2,2));
+
+ data[Yaw] = rad2deg * alpha;
+ data[Pitch] = - rad2deg * beta; // FTNoIR expects a minus here
+ data[Roll] = rad2deg * gamma;
+ }
+}
+
+//-----------------------------------------------------------------------------
+#ifdef OPENTRACK_API
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
+#else
+#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
+OPENTRACK_EXPORT ITrackerPtr __stdcall GetTracker()
+#endif
+{
+ return new Tracker;
+}
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.h b/ftnoir_tracker_pt/ftnoir_tracker_pt.h
new file mode 100644
index 00000000..fff8d4ab
--- /dev/null
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.h
@@ -0,0 +1,91 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef FTNOIR_TRACKER_PT_H
+#define FTNOIR_TRACKER_PT_H
+
+#ifdef OPENTRACK_API
+# include "facetracknoir/plugin-api.hpp"
+#endif
+#include "ftnoir_tracker_pt_settings.h"
+#include "camera.h"
+#include "point_extractor.h"
+#include "point_tracker.h"
+#include "pt_video_widget.h"
+#include "facetracknoir/timer.hpp"
+
+#include <QThread>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QTime>
+#include <opencv2/core/core.hpp>
+#include <atomic>
+#ifndef OPENTRACK_API
+# include <boost/shared_ptr.hpp>
+#else
+# include <memory>
+#endif
+#include <vector>
+
+//-----------------------------------------------------------------------------
+// Constantly processes the tracking chain in a separate thread
+class Tracker : public ITracker, protected QThread
+{
+public:
+ Tracker();
+ ~Tracker() override;
+ void StartTracker(QFrame* parent_window) override;
+ void GetHeadPoseData(double* data) override;
+
+ void apply(settings& s);
+ void apply_inner();
+ void center();
+ void reset(); // reset the trackers internal state variables
+
+ void get_pose(FrameTrafo* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.get_pose(); }
+ int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); }
+ void get_cam_info(CamInfo* info) { QMutexLocker lock(&mutex); *info = camera.get_info(); }
+protected:
+ void run() override;
+private:
+ QMutex mutex;
+ // thread commands
+ enum Command {
+ ABORT = 1<<0
+ };
+ void set_command(Command command);
+ void reset_command(Command command);
+ volatile int commands;
+
+ CVCamera camera;
+ FrameRotation frame_rotation;
+ PointExtractor point_extractor;
+ PointTracker point_tracker;
+
+ FrameTrafo X_GH_0; // for centering
+ cv::Vec3f t_MH; // translation from model frame to head frame
+ cv::Matx33f R_GC; // rotation from opengl reference frame to camera frame
+
+ // --- ui ---
+ cv::Mat frame; // the output frame for display
+
+ PTVideoWidget* video_widget;
+ QFrame* video_frame;
+
+ settings s;
+ std::atomic<settings*> new_settings;
+ Timer time;
+
+ static constexpr double rad2deg = 180.0/3.14159265;
+ static constexpr double deg2rad = 3.14159265/180.0;
+
+ PointModel model;
+};
+
+#undef VideoWidget
+
+#endif // FTNOIR_TRACKER_PT_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.qrc b/ftnoir_tracker_pt/ftnoir_tracker_pt.qrc
index a8f9a1af..a8f9a1af 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.qrc
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.qrc
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp
new file mode 100644
index 00000000..981cbea0
--- /dev/null
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp
@@ -0,0 +1,258 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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_dialog.h"
+
+#include <QMessageBox>
+#include <QDebug>
+#include <opencv2/core/core.hpp>
+#ifndef OPENTRACK_API
+# include <boost/shared_ptr.hpp>
+#else
+# include <memory>
+#endif
+#include <vector>
+
+using namespace std;
+
+//-----------------------------------------------------------------------------
+TrackerDialog::TrackerDialog()
+ : tracker(NULL),
+ timer(this),
+ trans_calib_running(false)
+{
+ ui.setupUi( this );
+
+ vector<string> device_names;
+ get_camera_device_names(device_names);
+ for (vector<string>::iterator iter = device_names.begin(); iter != device_names.end(); ++iter)
+ {
+ ui.camdevice_combo->addItem(iter->c_str());
+ }
+
+ ui.camroll_combo->addItem("-90");
+ ui.camroll_combo->addItem("0");
+ ui.camroll_combo->addItem("90");
+
+ tie_setting(s.cam_index, ui.camdevice_combo);
+ tie_setting(s.cam_res_x, ui.res_x_spin);
+ tie_setting(s.cam_res_y, ui.res_y_spin);
+ tie_setting(s.cam_fps, ui.fps_spin);
+ tie_setting(s.cam_roll, ui.camroll_combo);
+ tie_setting(s.cam_pitch, ui.campitch_spin);
+ tie_setting(s.cam_yaw, ui.camyaw_spin);
+
+ tie_setting(s.threshold_secondary, ui.threshold_secondary_slider);
+ tie_setting(s.threshold, ui.threshold_slider);
+
+ tie_setting(s.min_point_size, ui.mindiam_spin);
+ tie_setting(s.max_point_size, ui.maxdiam_spin);
+
+ tie_setting(s.clip_by, ui.clip_bheight_spin);
+ tie_setting(s.clip_bz, ui.clip_blength_spin);
+ tie_setting(s.clip_ty, ui.clip_theight_spin);
+ tie_setting(s.clip_tz, ui.clip_tlength_spin);
+
+ tie_setting(s.cap_x, ui.cap_width_spin);
+ tie_setting(s.cap_y, ui.cap_height_spin);
+ tie_setting(s.cap_z, ui.cap_length_spin);
+
+ tie_setting(s.m01_x, ui.m1x_spin);
+ tie_setting(s.m01_y, ui.m1y_spin);
+ tie_setting(s.m01_z, ui.m1z_spin);
+
+ tie_setting(s.m02_x, ui.m2x_spin);
+ tie_setting(s.m02_y, ui.m2y_spin);
+ tie_setting(s.m02_z, ui.m2z_spin);
+
+ tie_setting(s.t_MH_x, ui.tx_spin);
+ tie_setting(s.t_MH_y, ui.ty_spin);
+ tie_setting(s.t_MH_z, ui.tz_spin);
+
+ connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) );
+
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
+
+ ui.model_tabs->setCurrentIndex(s.active_model_panel);
+
+ connect(ui.model_tabs, SIGNAL(currentChanged(int)), this, SLOT(set_model(int)));
+ connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info()));
+ timer.start(100);
+
+ connect(ui.buttonBox_2, SIGNAL(clicked(QAbstractButton*)), this, SLOT(do_apply_without_saving(QAbstractButton*)));
+}
+
+void TrackerDialog::set_model_clip()
+{
+ s.m01_x = 0;
+ s.m01_y = static_cast<double>(s.clip_ty);
+ s.m01_z = -static_cast<double>(s.clip_tz);
+ s.m02_x = 0;
+ s.m02_y = -static_cast<double>(s.clip_by);
+ s.m02_z = -static_cast<double>(s.clip_bz);
+
+ settings_changed();
+}
+
+void TrackerDialog::set_model_cap()
+{
+ s.m01_x = -static_cast<double>(s.cap_x);
+ s.m01_y = -static_cast<double>(s.cap_y);
+ s.m01_z = -static_cast<double>(s.cap_z);
+ s.m02_x = static_cast<double>(s.cap_x);
+ s.m02_y = -static_cast<double>(s.cap_y);
+ s.m02_z = -static_cast<double>(s.cap_z);
+
+ settings_changed();
+}
+
+void TrackerDialog::set_model_custom()
+{
+ settings_changed();
+}
+
+void TrackerDialog::set_model(int val)
+{
+ s.active_model_panel = val;
+}
+
+void TrackerDialog::startstop_trans_calib(bool start)
+{
+ if (start)
+ {
+ qDebug()<<"TrackerDialog:: Starting translation calibration";
+ trans_calib.reset();
+ trans_calib_running = true;
+ }
+ else
+ {
+ qDebug()<<"TrackerDialog:: Stoppping translation calibration";
+ trans_calib_running = false;
+ {
+ auto tmp = trans_calib.get_estimate();
+ s.t_MH_x = tmp[0];
+ s.t_MH_y = tmp[1];
+ s.t_MH_z = tmp[2];
+ }
+ settings_changed();
+ }
+}
+
+void TrackerDialog::poll_tracker_info()
+{
+ if (tracker)
+ {
+ QString to_print;
+
+ // display caminfo
+ CamInfo info;
+ tracker->get_cam_info(&info);
+ to_print = QString::number(info.res_x)+"x"+QString::number(info.res_y)+" @ "+QString::number(info.fps)+" FPS";
+ ui.caminfo_label->setText(to_print);
+
+ // display pointinfo
+ int n_points = tracker->get_n_points();
+ to_print = QString::number(n_points);
+ if (n_points == 3)
+ to_print += " OK!";
+ else
+ to_print += " BAD!";
+ ui.pointinfo_label->setText(to_print);
+
+ // update calibration
+ if (trans_calib_running) trans_calib_step();
+ }
+ else
+ {
+ QString to_print = "Tracker offline";
+ ui.caminfo_label->setText(to_print);
+ ui.pointinfo_label->setText(to_print);
+ }
+}
+
+void TrackerDialog::trans_calib_step()
+{
+ if (tracker)
+ {
+ FrameTrafo X_CM;
+ tracker->get_pose(&X_CM);
+ trans_calib.update(X_CM.R, X_CM.t);
+ cv::Vec3f t_MH = trans_calib.get_estimate();
+ s.t_MH_x = t_MH[0];
+ s.t_MH_y = t_MH[1];
+ s.t_MH_z = t_MH[2];
+ }
+}
+
+void TrackerDialog::settings_changed()
+{
+ if (tracker) tracker->apply(s);
+}
+
+void TrackerDialog::save()
+{
+ do_apply_without_saving(nullptr);
+ s.b->save();
+}
+
+void TrackerDialog::doOK()
+{
+ save();
+ close();
+}
+
+void TrackerDialog::do_apply_without_saving(QAbstractButton*)
+{
+ switch (s.active_model_panel) {
+ default:
+ case 0:
+ set_model_clip();
+ break;
+ case 1:
+ set_model_cap();
+ break;
+ case 2:
+ set_model_custom();
+ break;
+ }
+ if (tracker) tracker->apply(s);
+}
+
+void TrackerDialog::doApply()
+{
+ save();
+}
+
+void TrackerDialog::doCancel()
+{
+ s.b->reload();
+ close();
+}
+
+void TrackerDialog::registerTracker(ITracker *t)
+{
+ qDebug()<<"TrackerDialog:: Tracker registered";
+ tracker = static_cast<Tracker*>(t);
+ if (isVisible() & s.b->modifiedp())
+ tracker->apply(s);
+ ui.tcalib_button->setEnabled(true);
+ //ui.center_button->setEnabled(true);
+}
+
+void TrackerDialog::unRegisterTracker()
+{
+ qDebug()<<"TrackerDialog:: Tracker un-registered";
+ tracker = NULL;
+ ui.tcalib_button->setEnabled(false);
+ //ui.center_button->setEnabled(false);
+}
+
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
+{
+ return new TrackerDialog;
+}
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h
index 0325160d..bff12dd0 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h
@@ -1,70 +1,62 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef FTNOIR_TRACKER_PT_DIALOG_H
-#define FTNOIR_TRACKER_PT_DIALOG_H
-
-#ifdef OPENTRACK_API
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#else
-#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
-#endif
-#include "ftnoir_tracker_pt_settings.h"
-#include "ftnoir_tracker_pt.h"
-#include "trans_calib.h"
-#include "pt_video_widget.h"
-#include "ui_FTNoIR_PT_Controls.h"
-
-#include <QTimer>
-
-//-----------------------------------------------------------------------------
-// The dialog that shows up when the user presses "Settings"
-class TrackerDialog : public QWidget, Ui::UICPTClientControls, public ITrackerDialog
-{
- Q_OBJECT
-public:
- TrackerDialog();
- void registerTracker(ITracker *tracker);
- void unRegisterTracker();
- void save();
- void trans_calib_step();
-
-public slots:
- void doCenter();
- void doReset();
- void doOK();
- void doApply();
- void doCancel();
- void do_apply_without_saving();
-
- void startstop_trans_calib(bool start);
- void widget_destroyed(QObject* obj);
- void create_video_widget();
- void poll_tracker_info();
- void set_model(int idx);
-
-protected:
- void destroy_video_widget(bool do_delete = true);
-
- void set_model_clip();
- void set_model_cap();
- void set_model_custom();
-
- void settings_changed();
-
- settings s;
- Tracker* tracker;
- VideoWidgetDialog* video_widget_dialog;
- QTimer timer;
-
- TranslationCalibrator trans_calib;
- bool trans_calib_running;
-
- Ui::UICPTClientControls ui;
-};
-
-#endif //FTNOIR_TRACKER_PT_DIALOG_H
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef FTNOIR_TRACKER_PT_DIALOG_H
+#define FTNOIR_TRACKER_PT_DIALOG_H
+
+#ifdef OPENTRACK_API
+# include "facetracknoir/plugin-api.hpp"
+#else
+#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
+#endif
+#include "ftnoir_tracker_pt_settings.h"
+#include "ftnoir_tracker_pt.h"
+#include "trans_calib.h"
+#include "pt_video_widget.h"
+#include "ui_FTNoIR_PT_Controls.h"
+
+#include <QTimer>
+
+//-----------------------------------------------------------------------------
+// The dialog that shows up when the user presses "Settings"
+class TrackerDialog : public QWidget, public ITrackerDialog
+{
+ Q_OBJECT
+public:
+ TrackerDialog();
+ void registerTracker(ITracker *tracker) override;
+ void unRegisterTracker() override;
+ void save();
+ void trans_calib_step();
+
+public slots:
+ void doOK();
+ void doCancel();
+ void doApply();
+ void do_apply_without_saving(QAbstractButton *);
+
+ void startstop_trans_calib(bool start);
+ void poll_tracker_info();
+ void set_model(int idx);
+private:
+ void set_model_clip();
+ void set_model_cap();
+ void set_model_custom();
+
+ void settings_changed();
+
+ settings s;
+ Tracker* tracker;
+ QTimer timer;
+
+ TranslationCalibrator trans_calib;
+ bool trans_calib_running;
+
+ Ui::UICPTClientControls ui;
+};
+
+#endif //FTNOIR_TRACKER_PT_DIALOG_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp
index f3fbbef7..fb756a86 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.cpp
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp
@@ -1,42 +1,42 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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_dll.h"
-#include <QIcon>
-
-//-----------------------------------------------------------------------------
-void TrackerDll::getFullName(QString *strToBeFilled)
-{
- *strToBeFilled = "PointTracker 1.1";
-}
-
-void TrackerDll::getShortName(QString *strToBeFilled)
-{
- *strToBeFilled = "PointTracker";
-}
-
-void TrackerDll::getDescription(QString *strToBeFilled)
-{
- *strToBeFilled = "Tracks a 3-point model with know geometry like Freetrack / TrackIR";
-}
-
-void TrackerDll::getIcon(QIcon *icon)
-{
- *icon = QIcon(":/Resources/Logo_IR.png");
-}
-
-
-#ifdef OPENTRACK_API
-# include "facetracknoir/global-settings.h"
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
-#else
-# pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
-FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
-#endif
-{
- return new TrackerDll;
-}
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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_dll.h"
+#include <QIcon>
+
+//-----------------------------------------------------------------------------
+void TrackerDll::getFullName(QString *strToBeFilled)
+{
+ *strToBeFilled = "PointTracker 1.1";
+}
+
+void TrackerDll::getShortName(QString *strToBeFilled)
+{
+ *strToBeFilled = "PointTracker";
+}
+
+void TrackerDll::getDescription(QString *strToBeFilled)
+{
+ *strToBeFilled = "Tracks a 3-point model with know geometry like Freetrack / TrackIR";
+}
+
+void TrackerDll::getIcon(QIcon *icon)
+{
+ *icon = QIcon(":/Resources/Logo_IR.png");
+}
+
+
+#ifdef OPENTRACK_API
+# include "facetracknoir/plugin-support.h"
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
+#else
+# pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
+OPENTRACK_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
+#endif
+{
+ return new TrackerDll;
+}
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h
index 1d30e7e5..50f66a35 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h
@@ -1,27 +1,26 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#if defined(OPENTRACK_API)
-# include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-# include "facetracknoir/global-settings.h"
-#else
-# include "../ftnoir_tracker_base/ftnoir_tracker_base.h"
-#endif
-
-//-----------------------------------------------------------------------------
-class TrackerDll :
-#if defined(OPENTRACK_API)
- public Metadata
-#else
- public ITrackerDll
-#endif
-{
- void getFullName(QString *strToBeFilled);
- void getShortName(QString *strToBeFilled);
- void getDescription(QString *strToBeFilled);
- void getIcon(QIcon *icon);
-};
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#if defined(OPENTRACK_API)
+# include "facetracknoir/plugin-api.hpp"
+#else
+# include "../ftnoir_tracker_base/ftnoir_tracker_base.h"
+#endif
+
+//-----------------------------------------------------------------------------
+class TrackerDll :
+#if defined(OPENTRACK_API)
+ public Metadata
+#else
+ public ITrackerDll
+#endif
+{
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
+};
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_settings.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h
index 109090b3..e8cac679 100644
--- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_settings.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h
@@ -1,90 +1,75 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- */
-
-#ifndef FTNOIR_TRACKER_PT_SETTINGS_H
-#define FTNOIR_TRACKER_PT_SETTINGS_H
-
-#include <opencv2/opencv.hpp>
-#include "point_tracker.h"
-
-#include "facetracknoir/options.h"
-using namespace options;
-
-struct settings
-{
- pbundle b;
- value<int> cam_index,
- cam_res_x,
- cam_res_y,
- cam_fps,
- cam_roll,
- cam_pitch,
- cam_yaw,
- threshold,
- threshold_secondary,
- min_point_size,
- max_point_size;
- value<double> cam_f;
-
- value<int> m01_x, m01_y, m01_z;
- value<int> m02_x, m02_y, m02_z;
- value<bool> dyn_pose_res, video_widget;
-
- value<int> t_MH_x, t_MH_y, t_MH_z;
-
- value<int> reset_time;
-
- value<bool> bEnableYaw, bEnablePitch, bEnableRoll;
- value<bool> bEnableX, bEnableY, bEnableZ;
-
- value<int> clip_ty, clip_tz, clip_by, clip_bz;
- value<int> active_model_panel, cap_x, cap_y, cap_z;
-
- settings() :
- b(bundle("tracker-pt")),
- cam_index(b, "camera-index", 0),
- cam_res_x(b, "camera-res-width", 640),
- cam_res_y(b, "camera-res-height", 480),
- cam_fps(b, "camera-fps", 30),
- cam_roll(b, "camera-roll", 1),
- cam_pitch(b, "camera-pitch", 0),
- cam_yaw(b, "camera-yaw", 0),
- threshold(b, "threshold-primary", 128),
- threshold_secondary(b, "threshold-secondary", 128),
- min_point_size(b, "min-point-size", 10),
- max_point_size(b, "max-point-size", 50),
- cam_f(b, "camera-focal-length", 1),
- m01_x(b, "m_01-x", 0),
- m01_y(b, "m_01-y", 0),
- m01_z(b, "m_01-z", 0),
- m02_x(b, "m_02-x", 0),
- m02_y(b, "m_02-y", 0),
- m02_z(b, "m_02-z", 0),
- dyn_pose_res(b, "dynamic-pose-resolution", false),
- video_widget(b, "video-widget", true),
- t_MH_x(b, "model-centroid-x", 0),
- t_MH_y(b, "model-centroid-y", 0),
- t_MH_z(b, "model-centroid-z", 0),
- reset_time(b, "reset-time", 2000),
- bEnableYaw(b, "enable-yaw", true),
- bEnablePitch(b, "enable-pitch", true),
- bEnableRoll(b, "enable-roll", true),
- bEnableX(b, "enable-x", true),
- bEnableY(b, "enable-y", true),
- bEnableZ(b, "enable-z", true),
- clip_ty(b, "clip-ty", 0),
- clip_tz(b, "clip-tz", 0),
- clip_by(b, "clip-by", 0),
- clip_bz(b, "clip-bz", 0),
- active_model_panel(b, "active-model-panel", 0),
- cap_x(b, "cap-x", 0),
- cap_y(b, "cap-y", 0),
- cap_z(b, "cap-z", 0)
- {}
-};
-
-#endif //FTNOIR_TRACKER_PT_SETTINGS_H
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef FTNOIR_TRACKER_PT_SETTINGS_H
+#define FTNOIR_TRACKER_PT_SETTINGS_H
+
+#include <opencv2/core/core.hpp>
+#include "point_tracker.h"
+
+#include "facetracknoir/options.h"
+using namespace options;
+
+struct settings
+{
+ pbundle b;
+ value<int> cam_index,
+ cam_res_x,
+ cam_res_y,
+ cam_fps,
+ cam_roll,
+ cam_pitch,
+ cam_yaw,
+ threshold,
+ threshold_secondary,
+ min_point_size,
+ max_point_size;
+
+ value<int> m01_x, m01_y, m01_z;
+ value<int> m02_x, m02_y, m02_z;
+
+ value<int> t_MH_x, t_MH_y, t_MH_z;
+
+ value<int> clip_ty, clip_tz, clip_by, clip_bz;
+ value<int> active_model_panel, cap_x, cap_y, cap_z;
+
+ // XXX todo red channel only, good for crapola CCD sensors -sh 20140922
+
+ settings() :
+ b(bundle("tracker-pt")),
+ cam_index(b, "camera-index", 0),
+ cam_res_x(b, "camera-res-width", 640),
+ cam_res_y(b, "camera-res-height", 480),
+ cam_fps(b, "camera-fps", 30),
+ cam_roll(b, "camera-roll", 1),
+ cam_pitch(b, "camera-pitch", 0),
+ cam_yaw(b, "camera-yaw", 0),
+ threshold(b, "threshold-primary", 128),
+ threshold_secondary(b, "threshold-secondary", 128),
+ min_point_size(b, "min-point-size", 10),
+ max_point_size(b, "max-point-size", 50),
+ m01_x(b, "m_01-x", 0),
+ m01_y(b, "m_01-y", 0),
+ m01_z(b, "m_01-z", 0),
+ m02_x(b, "m_02-x", 0),
+ m02_y(b, "m_02-y", 0),
+ m02_z(b, "m_02-z", 0),
+ t_MH_x(b, "model-centroid-x", 0),
+ t_MH_y(b, "model-centroid-y", 0),
+ t_MH_z(b, "model-centroid-z", 0),
+ clip_ty(b, "clip-ty", 0),
+ clip_tz(b, "clip-tz", 0),
+ clip_by(b, "clip-by", 0),
+ clip_bz(b, "clip-bz", 0),
+ active_model_panel(b, "active-model-panel", 0),
+ cap_x(b, "cap-x", 0),
+ cap_y(b, "cap-y", 0),
+ cap_z(b, "cap-z", 0)
+ {}
+};
+
+#endif //FTNOIR_TRACKER_PT_SETTINGS_H
diff --git a/FTNoIR_Tracker_PT/point_extractor.cpp b/ftnoir_tracker_pt/point_extractor.cpp
index d9ff0a5b..819bf5e8 100644
--- a/FTNoIR_Tracker_PT/point_extractor.cpp
+++ b/ftnoir_tracker_pt/point_extractor.cpp
@@ -1,163 +1,161 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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 "point_extractor.h"
-#include <QDebug>
-
-
-using namespace cv;
-using namespace std;
-
-
-PointExtractor::PointExtractor(){
- //if (!AllocConsole()){}
- //else SetConsoleTitle("debug");
- //freopen("CON", "w", stdout);
- //freopen("CON", "w", stderr);
-}
-// ----------------------------------------------------------------------------
-const vector<Vec2f>& PointExtractor::extract_points(Mat frame, float dt, bool draw_output)
-{
- const int W = frame.cols;
- const int H = frame.rows;
-
- if (frame_last.cols != W || frame_last.rows != H)
- {
- frame_last = cv::Mat();
- }
-
- // clear old points
- points.clear();
-
- // convert to grayscale
- Mat frame_gray;
- cvtColor(frame, frame_gray, CV_RGB2GRAY);
-
- int secondary = threshold_secondary_val;
-
- // mask for everything that passes the threshold (or: the upper threshold of the hysteresis)
- Mat frame_bin;
- // only used if draw_output
- Mat frame_bin_copy;
- // mask for everything that passes
- Mat frame_bin_low;
- // mask for lower-threshold && combined result of last, needs to remain in scope until drawing, but is only used if secondary != 0
- Mat frame_last_and_low;
-
- if(secondary==0){
- threshold(frame_gray, frame_bin, threshold_val, 255, THRESH_BINARY);
- }else{
- // we recombine a number of buffers, this might be slower than a single loop of per-pixel logic
- // but it might as well be faster if openCV makes good use of SIMD
- float t = threshold_val;
- //float hyst = float(threshold_secondary_val)/512.;
- //threshold(frame_gray, frame_bin, (t + ((255.-t)*hyst)), 255, THRESH_BINARY);
- float hyst = float(threshold_secondary_val)/256.;
- threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY);
- threshold(frame_gray, frame_bin_low,std::max(float(1), t - (t*hyst)), 255, THRESH_BINARY);
-
- if(draw_output) frame_bin.copyTo(frame_bin_copy);
- if(frame_last.empty()){
- frame_bin.copyTo(frame_last);
- }else{
- // keep pixels from last if they are above lower threshold
- bitwise_and(frame_last, frame_bin_low, frame_last_and_low);
- // union of pixels >= higher threshold and pixels >= lower threshold
- bitwise_or(frame_bin, frame_last_and_low, frame_last);
- frame_last.copyTo(frame_bin);
- }
- }
- unsigned int region_size_min = 3.14*min_size*min_size/4.0;
- unsigned int region_size_max = 3.14*max_size*max_size/4.0;
-
- int blob_index = 1;
- for (int y=0; y<H; y++)
- {
- if (blob_index >= 255) break;
- for (int x=0; x<W; x++)
- {
- if (blob_index >= 255) break;
-
- // find connected components with floodfill
- if (frame_bin.at<unsigned char>(y,x) != 255) continue;
- Rect rect;
-
- floodFill(frame_bin, Point(x,y), Scalar(blob_index), &rect, Scalar(0), Scalar(0), FLOODFILL_FIXED_RANGE);
- blob_index++;
-
- // calculate the size of the connected component
- unsigned int region_size = 0;
- for (int i=rect.y; i < (rect.y+rect.height); i++)
- {
- for (int j=rect.x; j < (rect.x+rect.width); j++)
- {
- if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
- region_size++;
- }
- }
-
- if (region_size < region_size_min || region_size > region_size_max) continue;
-
- // calculate the center of mass:
- // mx = (sum_ij j*f(frame_grey_ij)) / (sum_ij f(frame_grey_ij))
- // my = ...
- // f maps from [threshold,256] -> [0, 1], lower values are mapped to 0
- float m = 0;
- float mx = 0;
- float my = 0;
- for (int i=rect.y; i < (rect.y+rect.height); i++)
- {
- for (int j=rect.x; j < (rect.x+rect.width); j++)
- {
- if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
- float val;
-
- if(secondary==0){
- val = frame_gray.at<unsigned char>(i,j);
- val = float(val - threshold_val)/(256 - threshold_val);
- val = val*val; // makes it more stable (less emphasis on low values, more on the peak)
- }else{
- //hysteresis point detection gets stability from ignoring pixel noise so we decidedly leave the actual pixel values out of the picture
- val = frame_last.at<unsigned char>(i,j) / 256.;
- }
-
- m += val;
- mx += j * val;
- my += i * val;
- }
- }
-
- // convert to centered camera coordinate system with y axis upwards
- Vec2f c;
- c[0] = (mx/m - W/2)/W;
- c[1] = -(my/m - H/2)/W;
- //qDebug()<<blob_index<<" => "<<c[0]<<" "<<c[1];
- points.push_back(c);
- }
- }
-
- // draw output image
- if (draw_output) {
- vector<Mat> channels;
- if(secondary==0){
- frame_bin.setTo(170, frame_bin);
- channels.push_back(frame_gray + frame_bin);
- channels.push_back(frame_gray - frame_bin);
- channels.push_back(frame_gray - frame_bin);
- }else{
- frame_bin_copy.setTo(120, frame_bin_copy);
- frame_bin_low.setTo(90, frame_bin_low);
- channels.push_back(frame_gray + frame_bin_copy);
- channels.push_back(frame_gray + frame_last_and_low);
- channels.push_back(frame_gray + frame_bin_low);
- //channels.push_back(frame_gray + frame_bin);
- }
- merge(channels, frame);
- }
-
- return points;
-}
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 "point_extractor.h"
+#include <QDebug>
+
+
+using namespace cv;
+using namespace std;
+
+
+PointExtractor::PointExtractor(){
+ //if (!AllocConsole()){}
+ //else SetConsoleTitle("debug");
+ //freopen("CON", "w", stdout);
+ //freopen("CON", "w", stderr);
+}
+// ----------------------------------------------------------------------------
+const vector<Vec2f>& PointExtractor::extract_points(Mat& frame)
+{
+ const int W = frame.cols;
+ const int H = frame.rows;
+
+ if (frame_last.cols != W || frame_last.rows != H)
+ {
+ frame_last = cv::Mat();
+ }
+
+ // clear old points
+ points.clear();
+
+ // convert to grayscale
+ Mat frame_gray;
+ cvtColor(frame, frame_gray, CV_RGB2GRAY);
+
+ int secondary = threshold_secondary_val;
+
+ // mask for everything that passes the threshold (or: the upper threshold of the hysteresis)
+ Mat frame_bin;
+ // only used if draw_output
+ Mat frame_bin_copy;
+ // mask for everything that passes
+ Mat frame_bin_low;
+ // mask for lower-threshold && combined result of last, needs to remain in scope until drawing, but is only used if secondary != 0
+ Mat frame_last_and_low;
+
+ if(secondary==0){
+ threshold(frame_gray, frame_bin, threshold_val, 255, THRESH_BINARY);
+ }else{
+ // we recombine a number of buffers, this might be slower than a single loop of per-pixel logic
+ // but it might as well be faster if openCV makes good use of SIMD
+ float t = threshold_val;
+ //float hyst = float(threshold_secondary_val)/512.;
+ //threshold(frame_gray, frame_bin, (t + ((255.-t)*hyst)), 255, THRESH_BINARY);
+ float hyst = float(threshold_secondary_val)/256.;
+ threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY);
+ threshold(frame_gray, frame_bin_low,std::max(float(1), t - (t*hyst)), 255, THRESH_BINARY);
+
+ frame_bin.copyTo(frame_bin_copy);
+ if(frame_last.empty()){
+ frame_bin.copyTo(frame_last);
+ }else{
+ // keep pixels from last if they are above lower threshold
+ bitwise_and(frame_last, frame_bin_low, frame_last_and_low);
+ // union of pixels >= higher threshold and pixels >= lower threshold
+ bitwise_or(frame_bin, frame_last_and_low, frame_last);
+ frame_last.copyTo(frame_bin);
+ }
+ }
+ unsigned int region_size_min = 3.14*min_size*min_size/4.0;
+ unsigned int region_size_max = 3.14*max_size*max_size/4.0;
+
+ int blob_index = 1;
+ for (int y=0; y<H; y++)
+ {
+ if (blob_index >= 255) break;
+ for (int x=0; x<W; x++)
+ {
+ if (blob_index >= 255) break;
+
+ // find connected components with floodfill
+ if (frame_bin.at<unsigned char>(y,x) != 255) continue;
+ Rect rect;
+
+ floodFill(frame_bin, Point(x,y), Scalar(blob_index), &rect, Scalar(0), Scalar(0), FLOODFILL_FIXED_RANGE);
+ blob_index++;
+
+ // calculate the size of the connected component
+ unsigned int region_size = 0;
+ for (int i=rect.y; i < (rect.y+rect.height); i++)
+ {
+ for (int j=rect.x; j < (rect.x+rect.width); j++)
+ {
+ if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
+ region_size++;
+ }
+ }
+
+ if (region_size < region_size_min || region_size > region_size_max) continue;
+
+ // calculate the center of mass:
+ // mx = (sum_ij j*f(frame_grey_ij)) / (sum_ij f(frame_grey_ij))
+ // my = ...
+ // f maps from [threshold,256] -> [0, 1], lower values are mapped to 0
+ float m = 0;
+ float mx = 0;
+ float my = 0;
+ for (int i=rect.y; i < (rect.y+rect.height); i++)
+ {
+ for (int j=rect.x; j < (rect.x+rect.width); j++)
+ {
+ if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
+ float val;
+
+ if(secondary==0){
+ val = frame_gray.at<unsigned char>(i,j);
+ val = float(val - threshold_val)/(256 - threshold_val);
+ val = val*val; // makes it more stable (less emphasis on low values, more on the peak)
+ }else{
+ //hysteresis point detection gets stability from ignoring pixel noise so we decidedly leave the actual pixel values out of the picture
+ val = frame_last.at<unsigned char>(i,j) / 256.;
+ }
+
+ m += val;
+ mx += j * val;
+ my += i * val;
+ }
+ }
+
+ // convert to centered camera coordinate system with y axis upwards
+ Vec2f c;
+ c[0] = (mx/m - W/2)/W;
+ c[1] = -(my/m - H/2)/W;
+ //qDebug()<<blob_index<<" => "<<c[0]<<" "<<c[1];
+ points.push_back(c);
+ }
+ }
+
+ // draw output image
+ vector<Mat> channels;
+ if(secondary==0){
+ frame_bin.setTo(170, frame_bin);
+ channels.push_back(frame_gray + frame_bin);
+ channels.push_back(frame_gray - frame_bin);
+ channels.push_back(frame_gray - frame_bin);
+ }else{
+ frame_bin_copy.setTo(120, frame_bin_copy);
+ frame_bin_low.setTo(90, frame_bin_low);
+ channels.push_back(frame_gray + frame_bin_copy);
+ channels.push_back(frame_gray + frame_last_and_low);
+ channels.push_back(frame_gray + frame_bin_low);
+ //channels.push_back(frame_gray + frame_bin);
+ }
+ merge(channels, frame);
+
+ return points;
+}
diff --git a/ftnoir_tracker_pt/point_extractor.h b/ftnoir_tracker_pt/point_extractor.h
new file mode 100644
index 00000000..5252b68d
--- /dev/null
+++ b/ftnoir_tracker_pt/point_extractor.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef POINTEXTRACTOR_H
+#define POINTEXTRACTOR_H
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+// ----------------------------------------------------------------------------
+// Extracts points from an opencv image
+class PointExtractor
+{
+public:
+ // extracts points from frame and draws some processing info into frame, if draw_output is set
+ // dt: time since last call in seconds
+ // WARNING: returned reference is valid as long as object
+ const std::vector<cv::Vec2f>& extract_points(cv::Mat &frame);
+ const std::vector<cv::Vec2f>& get_points() { return points; }
+ PointExtractor();
+
+ int threshold_val;
+ int threshold_secondary_val;
+ int min_size, max_size;
+
+private:
+ std::vector<cv::Vec2f> points;
+ cv::Mat frame_last;
+};
+
+#endif //POINTEXTRACTOR_H
diff --git a/ftnoir_tracker_pt/point_tracker.cpp b/ftnoir_tracker_pt/point_tracker.cpp
new file mode 100644
index 00000000..8a633c5d
--- /dev/null
+++ b/ftnoir_tracker_pt/point_tracker.cpp
@@ -0,0 +1,289 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 "point_tracker.h"
+
+#include <vector>
+#include <algorithm>
+#include <cmath>
+
+#include <QDebug>
+
+using namespace cv;
+using namespace std;
+
+const float PI = 3.14159265358979323846f;
+
+// ----------------------------------------------------------------------------
+static void get_row(const Matx33f& m, int i, Vec3f& v)
+{
+ v[0] = m(i,0);
+ v[1] = m(i,1);
+ v[2] = m(i,2);
+}
+
+static void set_row(Matx33f& m, int i, const Vec3f& v)
+{
+ m(i,0) = v[0];
+ m(i,1) = v[1];
+ m(i,2) = v[2];
+}
+
+PointModel::PointModel() :
+ M01 { 0, 0, 0 },
+ M02 { 0, 0, 0 }
+{
+}
+
+PointModel::PointModel(Vec3f M01, Vec3f M02)
+ : M01(M01), M02(M02)
+{
+ // calculate u
+ u = M01.cross(M02);
+ u /= norm(u);
+
+ // calculate projection matrix on M01,M02 plane
+ float s11 = M01.dot(M01);
+ float s12 = M01.dot(M02);
+ float s22 = M02.dot(M02);
+ P = 1.0/(s11*s22-s12*s12) * Matx22f(s22, -s12,
+ -s12, s11);
+ // calculate d and d_order for simple freetrack-like point correspondence
+ vector<Vec2f> points;
+ points.push_back(Vec2f(0,0));
+ points.push_back(Vec2f(M01[0], M01[1]));
+ points.push_back(Vec2f(M02[0], M02[1]));
+ // fit line to orthographically projected points
+ // ERROR: yields wrong results with colinear points?!
+ /*
+ Vec4f line;
+ fitLine(points, line, CV_DIST_L2, 0, 0.01, 0.01);
+ d[0] = line[0]; d[1] = line[1];
+ */
+ // TODO: fix this
+ d = Vec2f(M01[0]-M02[0], M01[1]-M02[1]);
+
+ // sort model points
+ get_d_order(points, d_order);
+}
+
+#ifdef OPENTRACK_API
+static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b)
+{
+ return a.first < b.first;
+}
+#endif
+
+void PointModel::get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const
+{
+ // get sort indices with respect to d scalar product
+ vector< pair<float,int> > d_vals;
+ for (unsigned i = 0; i<points.size(); ++i)
+ d_vals.push_back(pair<float, int>(d.dot(points[i]), i));
+
+ std::sort(d_vals.begin(),
+ d_vals.end(),
+#ifdef OPENTRACK_API
+ d_vals_sort
+#else
+ comp
+#endif
+ );
+
+ for (unsigned i = 0; i<points.size(); ++i)
+ d_order[i] = d_vals[i].second;
+}
+
+
+// ----------------------------------------------------------------------------
+PointTracker::PointTracker()
+{
+ X_CM.t[2] = 1000; // default position: 1 m away from cam;
+}
+
+void PointTracker::reset()
+{
+ // enter init phase
+ X_CM = FrameTrafo();
+}
+
+void PointTracker::track(const vector<Vec2f>& projected_points, const PointModel& model)
+{
+ const PointOrder& order = find_correspondences(projected_points, model);
+ int iters = POSIT(model, order);
+ qDebug()<<"POSIT iterations:"<<iters;
+}
+
+PointTracker::PointOrder PointTracker::find_correspondences(const std::vector<cv::Vec2f>& projected_points, const PointModel& model)
+{
+ // ... otherwise we look at the distance to the projection of the expected model points
+ // project model points under current pose
+ Vec2f p_exp[3];
+ p_exp[0] = project(Vec3f(0,0,0));
+ p_exp[1] = project(model.get_M01());
+ p_exp[2] = project(model.get_M02());
+
+ // set correspondences by minimum distance to projected model point
+ bool point_taken[PointModel::N_POINTS];
+ for (int i=0; i<PointModel::N_POINTS; ++i)
+ point_taken[i] = false;
+
+ PointOrder p;
+ for (int i=0; i<PointModel::N_POINTS; ++i)
+ p.points[i] = Vec2f(0, 0);
+
+ for (int i=0; i<PointModel::N_POINTS; ++i)
+ {
+ float min_sdist = 1e4;
+ int min_idx = 0;
+ // find closest point to projected model point i
+ for (int j=0; j<PointModel::N_POINTS; ++j)
+ {
+ Vec2f d = p_exp[i]-projected_points[j];
+ float sdist = d.dot(d);
+ if (sdist < min_sdist)
+ {
+ min_idx = j;
+ min_sdist = sdist;
+ }
+ }
+ // if one point is closest to more than one model point, abort
+ if (point_taken[min_idx]) return p;
+ point_taken[min_idx] = true;
+ p.points[i] = projected_points[min_idx];
+ }
+ return p;
+}
+
+
+
+int PointTracker::POSIT(const PointModel& model, const PointOrder& order_)
+{
+ // POSIT algorithm for coplanar points as presented in
+ // [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
+ // we use the same notation as in the paper here
+
+ // The expected rotation used for resolving the ambiguity in POSIT:
+ // In every iteration step the rotation closer to R_expected is taken
+ Matx33f R_expected;
+ R_expected = X_CM.R; // later we want to be close to the last (predicted) rotation
+
+ // initial pose = last (predicted) pose
+ Vec3f k;
+ get_row(R_expected, 2, k);
+ float Z0 = std::abs(X_CM.t[2]) < 1e-3 ? 1e3 : X_CM.t[2];
+
+ float old_epsilon_1 = 0;
+ float old_epsilon_2 = 0;
+ float epsilon_1 = 1;
+ float epsilon_2 = 1;
+
+ Vec3f I0, J0;
+ Vec2f I0_coeff, J0_coeff;
+
+ Vec3f I_1, J_1, I_2, J_2;
+ Matx33f R_1, R_2;
+ Matx33f* R_current;
+
+ const int MAX_ITER = 100;
+ const float EPS_THRESHOLD = 1e-4;
+
+ const cv::Vec2f* order = order_.points;
+
+ int i=1;
+ for (; i<MAX_ITER; ++i)
+ {
+ epsilon_1 = k.dot(model.M01)/Z0;
+ epsilon_2 = k.dot(model.M02)/Z0;
+
+ // vector of scalar products <I0, M0i> and <J0, M0i>
+ Vec2f I0_M0i(order[1][0]*(1.0 + epsilon_1) - order[0][0],
+ order[2][0]*(1.0 + epsilon_2) - order[0][0]);
+ Vec2f J0_M0i(order[1][1]*(1.0 + epsilon_1) - order[0][1],
+ order[2][1]*(1.0 + epsilon_2) - order[0][1]);
+
+ // construct projection of I, J onto M0i plane: I0 and J0
+ I0_coeff = model.P * I0_M0i;
+ J0_coeff = model.P * J0_M0i;
+ I0 = I0_coeff[0]*model.M01 + I0_coeff[1]*model.M02;
+ J0 = J0_coeff[0]*model.M01 + J0_coeff[1]*model.M02;
+
+ // calculate u component of I, J
+ float II0 = I0.dot(I0);
+ float IJ0 = I0.dot(J0);
+ float JJ0 = J0.dot(J0);
+ float rho, theta;
+ if (JJ0 == II0) {
+ rho = sqrt(abs(2*IJ0));
+ theta = -PI/4;
+ if (IJ0<0) theta *= -1;
+ }
+ else {
+ rho = sqrt(sqrt( (JJ0-II0)*(JJ0-II0) + 4*IJ0*IJ0 ));
+ theta = atan( -2*IJ0 / (JJ0-II0) );
+ if (JJ0 - II0 < 0) theta += PI;
+ theta /= 2;
+ }
+
+ // construct the two solutions
+ I_1 = I0 + rho*cos(theta)*model.u;
+ I_2 = I0 - rho*cos(theta)*model.u;
+
+ J_1 = J0 + rho*sin(theta)*model.u;
+ J_2 = J0 - rho*sin(theta)*model.u;
+
+ float norm_const = 1.0/norm(I_1); // all have the same norm
+
+ // create rotation matrices
+ I_1 *= norm_const; J_1 *= norm_const;
+ I_2 *= norm_const; J_2 *= norm_const;
+
+ set_row(R_1, 0, I_1);
+ set_row(R_1, 1, J_1);
+ set_row(R_1, 2, I_1.cross(J_1));
+
+ set_row(R_2, 0, I_2);
+ set_row(R_2, 1, J_2);
+ set_row(R_2, 2, I_2.cross(J_2));
+
+ // the single translation solution
+ Z0 = norm_const * focal_length;
+
+ // pick the rotation solution closer to the expected one
+ // in simple metric d(A,B) = || I - A * B^T ||
+ float R_1_deviation = norm(Matx33f::eye() - R_expected * R_1.t());
+ float R_2_deviation = norm(Matx33f::eye() - R_expected * R_2.t());
+
+ if (R_1_deviation < R_2_deviation)
+ R_current = &R_1;
+ else
+ R_current = &R_2;
+
+ get_row(*R_current, 2, k);
+
+ // check for convergence condition
+ if (abs(epsilon_1 - old_epsilon_1) + abs(epsilon_2 - old_epsilon_2) < EPS_THRESHOLD)
+ break;
+ old_epsilon_1 = epsilon_1;
+ old_epsilon_2 = epsilon_2;
+ }
+
+ // apply results
+ X_CM.R = *R_current;
+ X_CM.t[0] = order[0][0] * Z0/focal_length;
+ X_CM.t[1] = order[0][1] * Z0/focal_length;
+ X_CM.t[2] = Z0;
+
+ return i;
+
+ //Rodrigues(X_CM.R, r);
+ //qDebug()<<"iter: "<<i;
+ //qDebug()<<"t: "<<X_CM.t[0]<<' '<<X_CM.t[1]<<' '<<X_CM.t[2];
+ //Vec3f r;
+ //
+ //qDebug()<<"r: "<<r[0]<<' '<<r[1]<<' '<<r[2]<<'\n';
+}
diff --git a/ftnoir_tracker_pt/point_tracker.h b/ftnoir_tracker_pt/point_tracker.h
new file mode 100644
index 00000000..d65494a4
--- /dev/null
+++ b/ftnoir_tracker_pt/point_tracker.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef POINTTRACKER_H
+#define POINTTRACKER_H
+
+#include <opencv2/core/core.hpp>
+#ifndef OPENTRACK_API
+# include <boost/shared_ptr.hpp>
+#else
+# include <memory>
+#endif
+#include <vector>
+
+// ----------------------------------------------------------------------------
+// Affine frame trafo
+class FrameTrafo
+{
+public:
+ FrameTrafo() : R(cv::Matx33f::eye()), t(0,0,0) {}
+ FrameTrafo(const cv::Matx33f& R, const cv::Vec3f& t) : R(R),t(t) {}
+
+ cv::Matx33f R;
+ cv::Vec3f t;
+};
+
+inline FrameTrafo operator*(const FrameTrafo& X, const FrameTrafo& Y)
+{
+ return FrameTrafo(X.R*Y.R, X.R*Y.t + X.t);
+}
+
+inline FrameTrafo operator*(const cv::Matx33f& X, const FrameTrafo& Y)
+{
+ return FrameTrafo(X*Y.R, X*Y.t);
+}
+
+inline FrameTrafo operator*(const FrameTrafo& X, const cv::Matx33f& Y)
+{
+ return FrameTrafo(X.R*Y, X.t);
+}
+
+inline cv::Vec3f operator*(const FrameTrafo& X, const cv::Vec3f& v)
+{
+ return X.R*v + X.t;
+}
+
+
+// ----------------------------------------------------------------------------
+// Describes a 3-point model
+// nomenclature as in
+// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
+class PointModel
+{
+ friend class PointTracker;
+public:
+ static constexpr int N_POINTS = 3;
+
+ PointModel(cv::Vec3f M01, cv::Vec3f M02);
+ PointModel();
+
+ inline const cv::Vec3f& get_M01() const { return M01; }
+ inline const cv::Vec3f& get_M02() const { return M02; }
+
+private:
+ cv::Vec3f M01; // M01 in model frame
+ cv::Vec3f M02; // M02 in model frame
+
+ cv::Vec3f u; // unit vector perpendicular to M01,M02-plane
+
+ cv::Matx22f P;
+
+ cv::Vec2f d; // determinant vector for point correspondence
+ int d_order[3]; // sorting of projected model points with respect to d scalar product
+
+ void get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const;
+};
+
+// ----------------------------------------------------------------------------
+// Tracks a 3-point model
+// implementing the POSIT algorithm for coplanar points as presented in
+// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
+class PointTracker
+{
+public:
+ PointTracker();
+ // track the pose using the set of normalized point coordinates (x pos in range -0.5:0.5)
+ // f : (focal length)/(sensor width)
+ // dt : time since last call
+ void track(const std::vector<cv::Vec2f>& projected_points, const PointModel& model);
+ FrameTrafo get_pose() const { return X_CM; }
+ void reset();
+
+private:
+ // the points in model order
+ typedef struct { cv::Vec2f points[PointModel::N_POINTS]; } PointOrder;
+ static constexpr float focal_length = 1.0f;
+
+ inline cv::Vec2f project(const cv::Vec3f& v_M)
+ {
+ cv::Vec3f v_C = X_CM * v_M;
+ return cv::Vec2f(focal_length*v_C[0]/v_C[2], focal_length*v_C[1]/v_C[2]);
+ }
+
+ PointOrder find_correspondences(const std::vector<cv::Vec2f>& projected_points, const PointModel &model);
+ int POSIT(const PointModel& point_model, const PointOrder& order); // The POSIT algorithm, returns the number of iterations
+
+ FrameTrafo X_CM; // trafo from model to camera
+};
+
+#endif //POINTTRACKER_H
diff --git a/FTNoIR_Tracker_PT/pt_video_widget.cpp b/ftnoir_tracker_pt/pt_video_widget.cpp
index 02817cbf..aefb8199 100644
--- a/FTNoIR_Tracker_PT/pt_video_widget.cpp
+++ b/ftnoir_tracker_pt/pt_video_widget.cpp
@@ -1,64 +1,46 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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.
- *
- * 20130312, WVR: Add 7 lines to resizeGL after resize_frame. This should lower CPU-load.
- */
-
-#include "pt_video_widget.h"
-
-#include <QDebug>
-#include <QHBoxLayout>
-
-using namespace cv;
-using namespace std;
-
-void PTVideoWidget::update_image(const cv::Mat& frame)
-{
- QMutexLocker foo(&mtx);
- _frame = frame.clone();
- freshp = true;
-}
-
-// ----------------------------------------------------------------------------
-VideoWidgetDialog::VideoWidgetDialog(QWidget *parent, FrameProvider* provider)
- : QDialog(parent),
- video_widget(NULL)
-{
- const int VIDEO_FRAME_WIDTH = 640;
- const int VIDEO_FRAME_HEIGHT = 480;
-
- video_widget = new PTVideoWidget(this, provider);
-
- QHBoxLayout* layout = new QHBoxLayout();
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(video_widget);
- if (this->layout()) delete this->layout();
- setLayout(layout);
- resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT);
-}
-
-void PTVideoWidget::update_and_repaint()
-{
- QMutexLocker foo(&mtx);
- if (_frame.empty() || !freshp)
- return;
- freshp = false;
- QImage qframe = QImage(_frame.cols, _frame.rows, QImage::Format_RGB888);
- uchar* data = qframe.bits();
- const int pitch = qframe.bytesPerLine();
- for (int y = 0; y < _frame.rows; y++)
- for (int x = 0; x < _frame.cols; x++)
- {
- const auto& elt = _frame.at<Vec3b>(y, x);
- const cv::Scalar elt2 = static_cast<cv::Scalar>(elt);
- data[y * pitch + x * 3 + 0] = elt2.val[2];
- data[y * pitch + x * 3 + 1] = elt2.val[1];
- data[y * pitch + x * 3 + 2] = elt2.val[0];
- }
- qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
- texture = qframe;
- update();
-}
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ *
+ * 20130312, WVR: Add 7 lines to resizeGL after resize_frame. This should lower CPU-load.
+ */
+
+#include "pt_video_widget.h"
+
+#include <QDebug>
+#include <QHBoxLayout>
+
+using namespace cv;
+using namespace std;
+
+void PTVideoWidget::update_image(const cv::Mat& frame)
+{
+ QMutexLocker foo(&mtx);
+ _frame = frame.clone();
+ freshp = true;
+}
+
+void PTVideoWidget::update_and_repaint()
+{
+ QMutexLocker foo(&mtx);
+ if (_frame.empty() || !freshp)
+ return;
+ freshp = false;
+ QImage qframe = QImage(_frame.cols, _frame.rows, QImage::Format_RGB888);
+ uchar* data = qframe.bits();
+ const int pitch = qframe.bytesPerLine();
+ for (int y = 0; y < _frame.rows; y++)
+ for (int x = 0; x < _frame.cols; x++)
+ {
+ const auto& elt = _frame.at<Vec3b>(y, x);
+ const cv::Scalar elt2 = static_cast<cv::Scalar>(elt);
+ data[y * pitch + x * 3 + 0] = elt2.val[2];
+ data[y * pitch + x * 3 + 1] = elt2.val[1];
+ data[y * pitch + x * 3 + 2] = elt2.val[0];
+ }
+ qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
+ texture = qframe;
+ update();
+}
diff --git a/FTNoIR_Tracker_PT/pt_video_widget.h b/ftnoir_tracker_pt/pt_video_widget.h
index 25d593c3..f2b41d63 100644
--- a/FTNoIR_Tracker_PT/pt_video_widget.h
+++ b/ftnoir_tracker_pt/pt_video_widget.h
@@ -1,71 +1,56 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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 "frame_observer.h"
-#include <QObject>
-#include <QTime>
-#include <QDialog>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <QGLWidget>
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-# if defined(_WIN32)
-# include <dshow.h>
-# endif
-#endif
-#include <QPainter>
-#include <QPaintEvent>
-#include <QTimer>
-
-class PTVideoWidget : public QWidget, public FrameObserver
-{
- Q_OBJECT
-
-public:
- PTVideoWidget(QWidget *parent, FrameProvider* provider) :
- QWidget(parent),
- /* to avoid linker errors */ FrameObserver(provider),
- freshp(false)
- {
- connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()));
- timer.start(40);
- }
- void update_image(const cv::Mat &frame);
- void update_frame_and_points() {}
-protected slots:
- void paintEvent( QPaintEvent* e ) {
- QMutexLocker foo(&mtx);
- QPainter painter(this);
- painter.drawImage(e->rect(), texture);
- }
- void update_and_repaint();
-private:
- QMutex mtx;
- QImage texture;
- QTimer timer;
- cv::Mat _frame;
- bool freshp;
-};
-
-// ----------------------------------------------------------------------------
-// A VideoWidget embedded in a dialog frame
-class VideoWidgetDialog : public QDialog
-{
- Q_OBJECT
-public:
- VideoWidgetDialog(QWidget *parent, FrameProvider* provider);
- virtual ~VideoWidgetDialog() {}
-
- PTVideoWidget* get_video_widget() { return video_widget; }
-
-private:
- PTVideoWidget* video_widget;
-};
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 <QObject>
+#include <QTime>
+#include <QDialog>
+#include <opencv2/core/core.hpp>
+#ifndef OPENTRACK_API
+# include <QGLWidget>
+# include <boost/shared_ptr.hpp>
+#else
+# include <memory>
+# if defined(_WIN32)
+# include <dshow.h>
+# endif
+#endif
+#include <QPainter>
+#include <QPaintEvent>
+#include <QTimer>
+#include <QMutex>
+#include <QMutexLocker>
+
+class PTVideoWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PTVideoWidget(QWidget *parent) :
+ QWidget(parent),
+ freshp(false)
+ {
+ connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()));
+ timer.start(40);
+ }
+ void update_image(const cv::Mat &frame);
+ void update_frame_and_points() {}
+protected slots:
+ void paintEvent( QPaintEvent* e ) {
+ QMutexLocker foo(&mtx);
+ QPainter painter(this);
+ painter.drawImage(e->rect(), texture);
+ }
+ void update_and_repaint();
+private:
+ QMutex mtx;
+ QImage texture;
+ QTimer timer;
+ cv::Mat _frame;
+ volatile bool freshp;
+};
diff --git a/FTNoIR_Tracker_PT/trans_calib.cpp b/ftnoir_tracker_pt/trans_calib.cpp
index 9b75a1b6..729a0b7f 100644
--- a/FTNoIR_Tracker_PT/trans_calib.cpp
+++ b/ftnoir_tracker_pt/trans_calib.cpp
@@ -1,44 +1,44 @@
-/* Copyright (c) 2012 Patrick Ruoff
- *
- * 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 "trans_calib.h"
-
-using namespace cv;
-
-//-----------------------------------------------------------------------------
-TranslationCalibrator::TranslationCalibrator()
-{
- reset();
-}
-
-void TranslationCalibrator::reset()
-{
- P = Matx66f::zeros();
- y = Vec6f(0,0,0, 0,0,0);
-}
-
-void TranslationCalibrator::update(const Matx33f& R_CM_k, const Vec3f& t_CM_k)
-{
- Matx<float, 6,3> H_k_T = Matx<float, 6,3>::zeros();
- for (int i=0; i<3; ++i) {
- for (int j=0; j<3; ++j) {
- H_k_T(i,j) = R_CM_k(j,i);
- }
- }
- for (int i=0; i<3; ++i)
- {
- H_k_T(3+i,i) = 1.0;
- }
- P += H_k_T * H_k_T.t();
- y += H_k_T * t_CM_k;
-}
-
-Vec3f TranslationCalibrator::get_estimate()
-{
- Vec6f x = P.inv() * y;
- return Vec3f(-x[0], -x[1], -x[2]);
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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 "trans_calib.h"
+
+using namespace cv;
+
+//-----------------------------------------------------------------------------
+TranslationCalibrator::TranslationCalibrator()
+{
+ reset();
+}
+
+void TranslationCalibrator::reset()
+{
+ P = Matx66f::zeros();
+ y = Vec6f(0,0,0, 0,0,0);
+}
+
+void TranslationCalibrator::update(const Matx33f& R_CM_k, const Vec3f& t_CM_k)
+{
+ Matx<float, 6,3> H_k_T = Matx<float, 6,3>::zeros();
+ for (int i=0; i<3; ++i) {
+ for (int j=0; j<3; ++j) {
+ H_k_T(i,j) = R_CM_k(j,i);
+ }
+ }
+ for (int i=0; i<3; ++i)
+ {
+ H_k_T(3+i,i) = 1.0;
+ }
+ P += H_k_T * H_k_T.t();
+ y += H_k_T * t_CM_k;
+}
+
+Vec3f TranslationCalibrator::get_estimate()
+{
+ Vec6f x = P.inv() * y;
+ return Vec3f(-x[0], -x[1], -x[2]);
} \ No newline at end of file
diff --git a/ftnoir_tracker_pt/trans_calib.h b/ftnoir_tracker_pt/trans_calib.h
new file mode 100644
index 00000000..c2c02b38
--- /dev/null
+++ b/ftnoir_tracker_pt/trans_calib.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * 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.
+ */
+
+#ifndef TRANSCALIB_H
+#define TRANSCALIB_H
+
+#include <opencv2/core/core.hpp>
+
+//-----------------------------------------------------------------------------
+// Calibrates the translation from head to model = t_MH
+// by recursive least squares /
+// kalman filter in information form with identity noise covariance
+// measurement equation when head position = t_CH is fixed:
+// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k
+
+class TranslationCalibrator
+{
+public:
+ TranslationCalibrator();
+
+ // reset the calibration process
+ void reset();
+
+ // update the current estimate
+ void update(const cv::Matx33f& R_CM_k, const cv::Vec3f& t_CM_k);
+
+ // get the current estimate for t_MH
+ cv::Vec3f get_estimate();
+
+private:
+ cv::Matx66f P; // normalized precision matrix = inverse covariance
+ cv::Vec6f y; // P*(-t_MH, t_CH)
+};
+
+#endif //TRANSCALIB_H
diff --git a/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui b/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui
index a9168239..20c8f00b 100644
--- a/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui
+++ b/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui
@@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>209</width>
- <height>288</height>
+ <width>218</width>
+ <height>200</height>
</rect>
</property>
<property name="sizePolicy">
@@ -34,126 +34,6 @@
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Pitch:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_9">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Yaw:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Roll:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Yaw spring</string>
@@ -271,7 +151,7 @@
</layout>
</widget>
</item>
- <item row="2" column="0">
+ <item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp
index b548db71..68a520ad 100644
--- a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp
+++ b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp
@@ -1,92 +1,74 @@
/* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */
#include "ftnoir_tracker_rift.h"
-#include "facetracknoir/global-settings.h"
-#include "OVR.h"
+#include "facetracknoir/plugin-support.h"
+#include "OVR_CAPI.h"
+#include "Kernel/OVR_Math.h"
#include <cstdio>
using namespace OVR;
-Rift_Tracker::Rift_Tracker()
+Rift_Tracker::Rift_Tracker() : old_yaw(0), hmd(nullptr)
{
- should_quit = false;
- pManager = NULL;
- pSensor = NULL;
- pSFusion = NULL;
- old_yaw = 0;
}
Rift_Tracker::~Rift_Tracker()
{
- if (pSensor)
- pSensor->Release();
- if (pSFusion)
- delete pSFusion;
- if (pManager)
- pManager->Release();
- System::Destroy();
+ ovrHmd_Destroy(hmd);
+ ovr_Shutdown();
}
void Rift_Tracker::StartTracker(QFrame*)
{
- System::Init(Log::ConfigureDefaultLog(LogMask_All));
- pManager = DeviceManager::Create();
- if (pManager != NULL)
+ ovr_Initialize();
+ hmd = ovrHmd_Create(0);
+ if (hmd)
{
- DeviceEnumerator<OVR::SensorDevice> enumerator = pManager->EnumerateDevices<OVR::SensorDevice>();
- if (enumerator.IsAvailable())
- {
- pSensor = enumerator.CreateDevice();
-
- if (pSensor){
- pSFusion = new OVR::SensorFusion();
- pSFusion->Reset();
- pSFusion->AttachToSensor(pSensor);
- }else{
- QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to create Rift sensor",QMessageBox::Ok,QMessageBox::NoButton);
- }
-
- }else{
- QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to enumerate Rift tracker",QMessageBox::Ok,QMessageBox::NoButton);
- }
- }else{
- QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to start Rift tracker",QMessageBox::Ok,QMessageBox::NoButton);
- }
+ ovrHmd_ConfigureTracking(hmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, ovrTrackingCap_Orientation);
+ }
+ else
+ {
+ // XXX need change ITracker et al api to allow for failure reporting
+ // this qmessagebox doesn't give any relevant details either -sh 20141012
+ QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to start Rift tracker",QMessageBox::Ok,QMessageBox::NoButton);
+ }
}
void Rift_Tracker::GetHeadPoseData(double *data)
{
- if (pSFusion != NULL && pSensor != NULL) {
- Quatf hmdOrient = pSFusion->GetOrientation();
- double newHeadPose[6];
-
- float yaw = 0.0f;
- float pitch = 0.0f;
- float roll = 0.0f;
- hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch , &roll);
- newHeadPose[Pitch] = pitch;
- newHeadPose[Roll] = roll;
- newHeadPose[Yaw] = yaw;
- if (s.useYawSpring)
- {
- newHeadPose[Yaw] = old_yaw*s.persistence + (yaw-old_yaw);
- if(newHeadPose[Yaw]>s.deadzone)newHeadPose[Yaw]-= s.constant_drift;
- if(newHeadPose[Yaw]<-s.deadzone)newHeadPose[Yaw]+= s.constant_drift;
- old_yaw=yaw;
- }
- if (s.bEnableYaw) {
- data[Yaw] = newHeadPose[Yaw] * 57.295781f;
- }
- if (s.bEnablePitch) {
- data[Pitch] = newHeadPose[Pitch] * 57.295781f;
- }
- if (s.bEnableRoll) {
- data[Roll] = newHeadPose[Roll] * 57.295781f;
+ if (hmd)
+ {
+ ovrHSWDisplayState hsw;
+ if (ovrHmd_GetHSWDisplayState(hmd, &hsw), hsw.Displayed)
+ ovrHmd_DismissHSWDisplay(hmd);
+ ovrTrackingState ss = ovrHmd_GetTrackingState(hmd, 0);
+ if(ss.StatusFlags & ovrStatus_OrientationTracked) {
+ auto pose = ss.HeadPose.ThePose;
+ Quatf quat = pose.Orientation;
+ float yaw, pitch, roll;
+ quat.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);
+ // XXX TODO move to core
+ if (s.useYawSpring)
+ {
+ yaw = old_yaw*s.persistence + (yaw-old_yaw);
+ if(yaw > s.deadzone)
+ yaw -= s.constant_drift;
+ if(yaw < -s.deadzone)
+ yaw += s.constant_drift;
+ old_yaw=yaw;
+ }
+ constexpr double d2r = 57.295781;
+ data[Yaw] = yaw * d2r;
+ data[Pitch] = pitch * -d2r;
+ data[Roll] = roll * d2r;
+ data[TX] = pose.Position.x * -1e2;
+ data[TY] = pose.Position.y * 1e2;
+ data[TZ] = pose.Position.z * 1e2;
}
}
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new Rift_Tracker;
}
diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift.h b/ftnoir_tracker_rift/ftnoir_tracker_rift.h
index 7162b7ca..b862555c 100644
--- a/ftnoir_tracker_rift/ftnoir_tracker_rift.h
+++ b/ftnoir_tracker_rift/ftnoir_tracker_rift.h
@@ -1,10 +1,9 @@
#pragma once
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
#include "ui_ftnoir_rift_clientcontrols.h"
#include <QMessageBox>
#include <QWaitCondition>
#include <cmath>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-api.hpp"
#include "OVR.h"
#include <memory>
#include "facetracknoir/options.h"
@@ -12,13 +11,10 @@ using namespace options;
struct settings {
pbundle b;
- value<bool> bEnableYaw, bEnablePitch, bEnableRoll, useYawSpring;
+ value<bool> useYawSpring;
value<double> constant_drift, persistence, deadzone;
settings() :
b(bundle("Rift")),
- bEnableYaw(b, "EnableYaw", true),
- bEnablePitch(b, "EnablePitch", true),
- bEnableRoll(b, "EnableRoll", true),
useYawSpring(b, "yaw-spring", false),
constant_drift(b, "constant-drift", 0.000005),
persistence(b, "persistence", 0.99999),
@@ -29,55 +25,46 @@ struct settings {
class Rift_Tracker : public ITracker
{
public:
- Rift_Tracker();
- virtual ~Rift_Tracker() virt_override;
-
- void StartTracker(QFrame *) virt_override;
- void GetHeadPoseData(double *data) virt_override;
- virtual int preferredHz() virt_override { return 250; }
- volatile bool should_quit;
-protected:
- void run(); // qthread override run method
-
+ Rift_Tracker();
+ ~Rift_Tracker() override;
+ void StartTracker(QFrame *) override;
+ void GetHeadPoseData(double *data) override;
private:
- static bool isInitialised;
- OVR::DeviceManager* pManager;
- OVR::SensorDevice* pSensor;
- OVR::SensorFusion* pSFusion;
- settings s;
double old_yaw;
+ ovrHmd hmd;
+ settings s;
};
class TrackerControls: public QWidget, public ITrackerDialog
{
Q_OBJECT
public:
- explicit TrackerControls();
+ explicit TrackerControls();
void registerTracker(ITracker *) {}
- void unRegisterTracker() {}
+ void unRegisterTracker() {}
private:
- Ui::UIRiftControls ui;
+ Ui::UIRiftControls ui;
settings s;
private slots:
- void doOK();
- void doCancel();
+ void doOK();
+ void doCancel();
};
class FTNoIR_TrackerDll : public Metadata
{
public:
- FTNoIR_TrackerDll();
- ~FTNoIR_TrackerDll();
- void getFullName(QString *strToBeFilled);
- void getShortName(QString *strToBeFilled);
- void getDescription(QString *strToBeFilled);
- void getIcon(QIcon *icon);
+ FTNoIR_TrackerDll();
+ ~FTNoIR_TrackerDll();
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
private:
- QString trackerFullName; // Trackers' name and description
- QString trackerShortName;
- QString trackerDescription;
+ QString trackerFullName; // Trackers' name and description
+ QString trackerShortName;
+ QString trackerDescription;
};
diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp
index ad532100..38c7457e 100644
--- a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp
+++ b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp
@@ -1,19 +1,14 @@
#include "ftnoir_tracker_rift.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
TrackerControls::TrackerControls() :
QWidget()
{
- ui.setupUi( this );
+ ui.setupUi( this );
- // Connect Qt signals to member-functions
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- tie_setting(s.bEnableYaw, ui.chkEnableYaw);
- tie_setting(s.bEnablePitch, ui.chkEnablePitch);
- tie_setting(s.bEnableRoll, ui.chkEnableRoll);
-
tie_setting(s.constant_drift, ui.constantDrift);
tie_setting(s.deadzone, ui.deadzone);
tie_setting(s.persistence, ui.persistence);
@@ -26,11 +21,11 @@ void TrackerControls::doOK() {
}
void TrackerControls::doCancel() {
- s.b->revert();
+ s.b->reload();
close();
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog()
{
return new TrackerControls;
}
diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp
index 2b24411c..902c8051 100644
--- a/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp
+++ b/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp
@@ -1,7 +1,7 @@
/* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */
#include "ftnoir_tracker_rift.h"
#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
FTNoIR_TrackerDll::FTNoIR_TrackerDll() {
//populate the description strings
@@ -35,7 +35,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)
*icon = QIcon(":/images/rift_tiny.png");
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_TrackerDll;
}
diff --git a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui
index 5c602792..4a5624cf 100644
--- a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui
+++ b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui
@@ -1,384 +1,66 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTNClientControls</class>
- <widget class="QWidget" name="UICFTNClientControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>411</width>
- <height>232</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>UDP tracker settings</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>5550</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
- </property>
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <widget class="QWidget" name="layoutWidget">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>20</y>
- <width>147</width>
- <height>68</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Roll:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Pitch:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Yaw:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>X:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QCheckBox" name="chkEnableX">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Y:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QCheckBox" name="chkEnableY">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QCheckBox" name="chkEnableZ">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Enter the port-number for the remote PC.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Remember: you may have to change firewall-settings too!</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinPortNumber</tabstop>
- <tabstop>btnOK</tabstop>
- <tabstop>btnCancel</tabstop>
- </tabstops>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICFTNClientControls</class>
+ <widget class="QWidget" name="UICFTNClientControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>216</width>
+ <height>71</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>UDP tracker settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="spinPortNumber">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinPortNumber</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp
index 02ae21f0..136e075d 100644
--- a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp
+++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp
@@ -1,37 +1,7 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage: http://facetracknoir.sourceforge.net/home/default.htm *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#include "ftnoir_tracker_udp.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
-FTNoIR_Tracker::FTNoIR_Tracker() : should_quit(false)
-{
- should_quit = false;
-
- for (int i = 0; i < 6; i++)
- newHeadPose[i] = 0;
-}
+FTNoIR_Tracker::FTNoIR_Tracker() : last_recv_pose { 0,0,0, 0,0,0 }, should_quit(false) {}
FTNoIR_Tracker::~FTNoIR_Tracker()
{
@@ -39,45 +9,34 @@ FTNoIR_Tracker::~FTNoIR_Tracker()
wait();
}
-/** QThread run @override **/
void FTNoIR_Tracker::run() {
- forever {
+ QByteArray datagram;
+ datagram.resize(sizeof(last_recv_pose));
+ for (;;) {
if (should_quit)
break;
- while (inSocket.hasPendingDatagrams()) {
- QMutexLocker foo(&mutex);
- QByteArray datagram;
- datagram.resize(sizeof(newHeadPose));
- inSocket.readDatagram((char * ) newHeadPose, sizeof(double[6]));
+ QMutexLocker foo(&mutex);
+ while (sock.hasPendingDatagrams()) {
+ sock.readDatagram((char * ) last_recv_pose, sizeof(double[6]));
}
- usleep(10000);
- }
+ msleep(1);
+ }
}
void FTNoIR_Tracker::StartTracker(QFrame*)
{
- (void) inSocket.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
+ (void) sock.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
start();
}
void FTNoIR_Tracker::GetHeadPoseData(double *data)
{
QMutexLocker foo(&mutex);
- if (s.enable_x)
- data[TX] = newHeadPose[TX];
- if (s.enable_y)
- data[TY] = newHeadPose[TY];
- if (s.enable_z)
- data[TZ] = newHeadPose[TZ];
- if (s.enable_yaw)
- data[Yaw] = newHeadPose[Yaw];
- if (s.enable_pitch)
- data[Pitch] = newHeadPose[Pitch];
- if (s.enable_roll)
- data[Roll] = newHeadPose[Roll];
+ for (int i = 0; i < 6; i++)
+ data[i] = last_recv_pose[i];
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
{
return new FTNoIR_Tracker;
}
diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.h b/ftnoir_tracker_udp/ftnoir_tracker_udp.h
index 62eb67df..a6f2e6d3 100644
--- a/ftnoir_tracker_udp/ftnoir_tracker_udp.h
+++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.h
@@ -1,58 +1,43 @@
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
+#pragma once
#include "ui_ftnoir_ftnclientcontrols.h"
-#include <QThread>
#include <QUdpSocket>
-#include <QMessageBox>
-#include <QMutex>
-#include <QWaitCondition>
-#include <math.h>
-#include "facetracknoir/global-settings.h"
+#include <QThread>
+#include <cmath>
+#include "facetracknoir/plugin-api.hpp"
#include "facetracknoir/options.h"
using namespace options;
struct settings {
pbundle b;
value<int> port;
- value<bool> enable_roll, enable_pitch, enable_yaw,
- enable_x, enable_y, enable_z;
settings() :
b(bundle("udp-tracker")),
- port(b, "port", 4242),
- enable_roll(b, "enable-roll", true),
- enable_pitch(b, "enable-pitch", true),
- enable_yaw(b, "enable-yaw", true),
- enable_x(b, "enable-x", true),
- enable_y(b, "enable-y", true),
- enable_z(b, "enable-y", true)
+ port(b, "port", 4242)
{}
};
-class FTNoIR_Tracker : public ITracker, public QThread
+class FTNoIR_Tracker : public ITracker, protected QThread
{
public:
FTNoIR_Tracker();
~FTNoIR_Tracker();
void StartTracker(QFrame *);
void GetHeadPoseData(double *data);
- volatile bool should_quit;
protected:
- void run(); // qthread override run method
+ void run() override;
private:
- QUdpSocket inSocket;
- QHostAddress destIP;
- QHostAddress srcIP;
- double newHeadPose[6];
+ QUdpSocket sock;
+ double last_recv_pose[6];
QMutex mutex;
settings s;
+ volatile bool should_quit;
};
-// Widget that has controls for FTNoIR protocol client-settings.
class TrackerControls: public QWidget, public ITrackerDialog
{
Q_OBJECT
public:
-
- explicit TrackerControls();
+ TrackerControls();
void registerTracker(ITracker *) {}
void unRegisterTracker() {}
private:
@@ -63,9 +48,6 @@ private slots:
void doCancel();
};
-//*******************************************************************************************************
-// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker
-//*******************************************************************************************************
class FTNoIR_TrackerDll : public Metadata
{
public:
@@ -74,4 +56,3 @@ public:
void getDescription(QString *strToBeFilled);
void getIcon(QIcon *icon);
};
-
diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp
index 8d1b99f2..062b1899 100644
--- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp
+++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp
@@ -1,44 +1,14 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage: http://facetracknoir.sourceforge.net/home/default.htm *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#include "ftnoir_tracker_udp.h"
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
TrackerControls::TrackerControls() :
QWidget()
{
ui.setupUi( this );
- connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
- connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- tie_setting(s.enable_x, ui.chkEnableX);
- tie_setting(s.enable_y, ui.chkEnableY);
- tie_setting(s.enable_z, ui.chkEnableZ);
- tie_setting(s.enable_yaw, ui.chkEnableYaw);
- tie_setting(s.enable_pitch, ui.chkEnablePitch);
- tie_setting(s.enable_roll, ui.chkEnableRoll);
tie_setting(s.port, ui.spinPortNumber);
}
@@ -48,11 +18,11 @@ void TrackerControls::doOK() {
}
void TrackerControls::doCancel() {
- s.b->revert();
+ s.b->reload();
this->close();
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
{
return new TrackerControls;
}
diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp
index 22dc7daa..7cd23552 100644
--- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp
+++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp
@@ -1,30 +1,5 @@
-/********************************************************************************
-* FaceTrackNoIR This program is a private project of some enthusiastic *
-* gamers from Holland, who don't like to pay much for *
-* head-tracking. *
-* *
-* Copyright (C) 2012 Wim Vriend (Developing) *
-* Ron Hendriks (Researching and Testing) *
-* *
-* Homepage *
-* *
-* This program is free software; you can redistribute it and/or modify it *
-* under the terms of the GNU General Public License as published by the *
-* Free Software Foundation; either version 3 of the License, or (at your *
-* option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, but *
-* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
-* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
-* more details. *
-* *
-* You should have received a copy of the GNU General Public License along *
-* with this program; if not, see <http://www.gnu.org/licenses/>. *
-* *
-********************************************************************************/
#include "ftnoir_tracker_udp.h"
-#include <QDebug>
-#include "facetracknoir/global-settings.h"
+#include "facetracknoir/plugin-support.h"
void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled)
{
@@ -46,7 +21,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon)
*icon = QIcon(":/images/facetracknoir.png");
}
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
{
return new FTNoIR_TrackerDll;
}
diff --git a/make-tar.sh b/make-tar.sh
new file mode 100644
index 00000000..26b65dcb
--- /dev/null
+++ b/make-tar.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+prefix="$1"
+filename="$2"
+
+if : &&
+ make install &&
+ cd $(dirname -- "${prefix}") &&
+ tar Jcf "${filename}" $(basename "${prefix}")
+then
+ ls -lh -- "${filename}"
+else
+ rm -fv -- "${filename}"
+ exit 1
+fi
+
+exit 0
diff --git a/opentrack-api/context.cpp b/opentrack-api/context.cpp
deleted file mode 100644
index 04fa5ac2..00000000
--- a/opentrack-api/context.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "opentrack-guts.h"
-#include "opentrack.h"
-
-#if defined(__APPLE__)
-# define SONAME "dylib"
-#elif defined(_WIN32)
-# define SONAME "dll"
-#else
-# define SONAME "so"
-#endif
-
-#include <iostream>
-
-#ifdef _MSC_VER
-# define LIB_PREFIX ""
-#else
-# define LIB_PREFIX "lib"
-#endif
-
-static Metadata* get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon)
-{
- Metadata* meta;
- if (!lib->Metadata || ((meta = lib->Metadata()), !meta))
- return NULL;
- meta->getFullName(&longName);
- meta->getIcon(&icon);
- return meta;
-}
-
-static QList<opentrack_meta> list_files(QString filter)
-{
- QList<opentrack_meta> ret;
- QStringList filenames = QDir((qApp->applicationDirPath())).entryList(
- QStringList() << (LIB_PREFIX + filter + ("*." SONAME)),
- QDir::Files, QDir::Name );
- for ( int i = 0; i < filenames.size(); i++) {
- QIcon icon;
- QString long_name;
- QString str = filenames.at(i);
- DynamicLibrary* lib = new DynamicLibrary(str);
- qDebug() << "Loading" << str;
- std::cout.flush();
- Metadata* meta;
- if (!(meta = get_metadata(lib, long_name, icon)))
- {
- delete lib;
- continue;
- }
- /* TODO perhaps return full name and somesuch */
- delete meta;
- QString prefix(LIB_PREFIX + filter);
- QString suffix("." SONAME);
- if (str.size() > prefix.size() + suffix.size() && str.startsWith(prefix) && str.endsWith(suffix))
- {
- auto str2 = str.mid(prefix.size(), str.size() - prefix.size() - suffix.size());
- opentrack_meta item(str2, lib);
- ret.push_back(item);
- }
- }
-
- return ret;
-}
-
-opentrack_ctx::opentrack_ctx(int argc, char** argv, void* window_parent) :
- app(argc, argv),
- meta_list(list_files("opentrack-tracker-")),
- fake_frame(window_parent)
-{
- const int count = meta_list.size();
- list = new char*[count + 1];
- for (int i = 0; i < count; i++)
- {
- QByteArray tmp = meta_list.at(i).path.toUtf8();
- int len = tmp.size();
- auto foo = new char[len+1];
- for (int j = 0; j < len; j++)
- foo[j] = tmp.at(j);
- foo[len] = '\0';
- list[i] = foo;
- }
- list[count] = NULL;
-}
-
-opentrack_ctx::~opentrack_ctx()
-{
- for (int i = 0; list[i]; i++)
- {
- delete[] list[i];
- }
- delete[] list;
-}
-
-extern "C"
-{
-
-OPENTRACK_EXPORT const char** opentrack_enum_trackers(opentrack ctx)
-{
- return const_cast<const char**>(ctx->list);
-}
-
-OPENTRACK_EXPORT opentrack opentrack_make_ctx(int argc, char** argv, void* window_parent)
-{
- return new opentrack_ctx(argc, argv, window_parent);
-}
-
-OPENTRACK_EXPORT void opentrack_finalize_ctx(opentrack foo)
-{
- delete foo;
-}
-
-}
-
diff --git a/opentrack-api/gnuc-version-script.txt b/opentrack-api/gnuc-version-script.txt
deleted file mode 100644
index cd3a568d..00000000
--- a/opentrack-api/gnuc-version-script.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- global:
- opentrack_make_ctx;
- opentrack_finalize_ctx;
- opentrack_enum_trackers;
- opentrack_make_tracker;
- opentrack_tracker_start;
- opentrack_tracker_tick;
- opentrack_finalize_tracker;
- local:
- *;
-};
diff --git a/opentrack-api/opentrack-guts.h b/opentrack-api/opentrack-guts.h
deleted file mode 100644
index c8e3309a..00000000
--- a/opentrack-api/opentrack-guts.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#pragma once
-
-#include <QFrame>
-#include <QDir>
-#include <QList>
-#include <QStringList>
-#include <QDebug>
-#include <QIcon>
-#include <QShowEvent>
-#include <iostream>
-#include <cstring>
-#include <QString>
-#include <QApplication>
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include "facetracknoir/global-settings.h"
-#include <memory>
-
-typedef ITracker* opentrack_tracker;
-
-class opentrack_meta {
-public:
- QString path;
- std::shared_ptr<DynamicLibrary> lib;
-
- opentrack_meta(QString& path, DynamicLibrary* lib) :
- path(path), lib(lib)
- {}
-};
-
-class MyFrame : public QFrame {
- Q_OBJECT
-public:
- MyFrame(void* parent)
- {
- if (parent == (void*) -1)
- {
- show();
- setVisible(false);
- hide();
- }
- else
- {
- create((WId) parent);
- }
- }
- explicit MyFrame() {}
-};
-
-typedef class opentrack_ctx {
-public:
- QApplication app;
- char** list;
- QList<opentrack_meta> meta_list;
- MyFrame fake_frame;
- opentrack_ctx(int argc, char** argv, void* window_parent);
- ~opentrack_ctx();
-} *opentrack;
diff --git a/opentrack-api/opentrack.h b/opentrack-api/opentrack.h
deleted file mode 100644
index 88ba6cf0..00000000
--- a/opentrack-api/opentrack.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef IN_OPENTRACK
-/* opaque pointers, forward definitions */
-struct opentrack_opaque_ctx;
-typedef struct opentrack_opaque_ctx* opentrack;
-struct opentrack_opaque_tracker;
-typedef struct opentrack_opaque_tracker* opentrack_tracker;
-#endif
-
-#ifdef IN_OPENTRACK
-# ifdef _WIN32
-# define OPENTRACK_EXPORT __declspec(dllexport)
-# else
-# define OPENTRACK_EXPORT
-# endif
-#else
-# ifdef _WIN32
-# define OPENTRACK_EXPORT __declspec(dllimport)
-# else
-# define OPENTRACK_EXPORT
-# endif
-#endif
-
-/* for `opentrack_tracker_tick', individual headpose elts */
-#ifndef IN_OPENTRACK
-enum opentrack_dof {
- TX = 0,
- TY,
- TZ,
- Yaw,
- Pitch,
- Roll,
- DOF_count
-};
-#endif
-
-OPENTRACK_EXPORT opentrack opentrack_make_ctx(int argc, char** argv, void* window_parent);
-OPENTRACK_EXPORT void opentrack_finalize_ctx(opentrack self);
-
-/* no need to free the return value; invalid to modify it */
-OPENTRACK_EXPORT const char** opentrack_enum_trackers(opentrack self);
-
-/*
- * don't `opentrack_tracker_tick an unstarted tracker, it's invalid to do so
- * it's also invalid to start a finalized tracker
- */
-OPENTRACK_EXPORT opentrack_tracker opentrack_make_tracker(opentrack ctx, const char* name);
-OPENTRACK_EXPORT void opentrack_tracker_start(opentrack self, opentrack_tracker tracker);
-OPENTRACK_EXPORT void opentrack_tracker_tick(opentrack_tracker tracker, double* headpose);
-OPENTRACK_EXPORT void opentrack_finalize_tracker(opentrack_tracker tracker);
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/opentrack-api/trackers.cpp b/opentrack-api/trackers.cpp
deleted file mode 100644
index 5027ec1d..00000000
--- a/opentrack-api/trackers.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "opentrack-guts.h"
-#include "opentrack.h"
-
-extern "C" {
-
-opentrack_tracker OPENTRACK_EXPORT opentrack_make_tracker(opentrack ctx, const char* name)
-{
- for (int i = 0; i < ctx->meta_list.size(); i++)
- {
- auto meta = ctx->meta_list.at(i);
- if (ctx->meta_list.at(i).path == name)
- {
- ITracker* foo = static_cast<ITracker*>(meta.lib->Constructor());
- return foo;
- }
- }
- return NULL;
-}
-
-void OPENTRACK_EXPORT opentrack_finalize_tracker(opentrack_tracker tracker)
-{
- delete tracker;
-}
-
-void OPENTRACK_EXPORT opentrack_tracker_start(opentrack self, opentrack_tracker tracker)
-{
- // hot damn, this is problematic!
- // need to pass QFrame from somewhere
- return tracker->StartTracker(&self->fake_frame);
-}
-
-void OPENTRACK_EXPORT opentrack_tracker_tick(opentrack_tracker tracker, double* headpose)
-{
- tracker->GetHeadPoseData(headpose);
- QApplication::processEvents(0, 5);
-}
-
-}
diff --git a/opentrack-version.h b/opentrack-version.h
deleted file mode 100644
index f31d5edf..00000000
--- a/opentrack-version.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef OPENTRACK_VERSION
-# define OPENTRACK_VERSION @OPENTRACK_COMMIT_VERSION@
-#else
-# ifndef OPENTRACK_VERSION
-# define OPENTRACK_VERSION "Mourns-For-Trees"
-# endif
-#endif
diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp
index 97a6db24..a4d03ed8 100644
--- a/qfunctionconfigurator/functionconfig.cpp
+++ b/qfunctionconfigurator/functionconfig.cpp
@@ -1,11 +1,3 @@
-/* Copyright (c) 2012, 2013 Stanisław 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 <QMutexLocker>
#include <QCoreApplication>
#include <QPointF>
@@ -14,259 +6,193 @@
#include <QtAlgorithms>
#include <QtAlgorithms>
#include <QSettings>
-#include <math.h>
#include <QPixmap>
+#include <algorithm>
-//
-// Constructor with List of Points in argument.
-//
-FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) :
- _mutex(QMutex::Recursive)
-{
- _title = title;
- _points = QList<QPointF>();
- _data = 0;
- _size = 0;
- lastValueTracked = QPointF(0,0);
- _tracking_active = false;
- _max_Input = intMaxInput; // Added WVR 20120805
- _max_Output = intMaxOutput;
- QSettings settings("opentrack"); // Registry settings (in HK_USER)
- QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings iniFile( currentFile, QSettings::IniFormat );
- loadSettings(iniFile);
- reload();
-}
-
-void FunctionConfig::setTrackingActive(bool blnActive)
+void Map::setTrackingActive(bool blnActive)
{
- _tracking_active = blnActive;
+ activep = blnActive;
}
-FunctionConfig::FunctionConfig() :
+Map::Map() :
_mutex(QMutex::Recursive),
- _data(0),
- _size(0),
- _tracking_active(false),
- _max_Input(0),
- _max_Output(0)
+ activep(false),
+ max_x(0),
+ max_y(0)
{
}
-//
-// Calculate the value of the function, given the input 'x'.
-// Used to draw the curve and, most importantly, to translate input to output.
-// The return-value is also stored internally, so the Widget can show the current value, when the Tracker is running.
-//
-float FunctionConfig::getValue(float x) {
+float Map::getValue(float x) {
QMutexLocker foo(&_mutex);
- int x2 = (int) (std::min<float>(std::max<float>(x, -360), 360) * MEMOIZE_PRECISION);
+ int x2 = x * (double) MEMOIZE_PRECISION;
float ret = getValueInternal(x2);
- lastValueTracked.setX(x);
- lastValueTracked.setY(ret);
- return ret;
+ last_input_value.setX(x);
+ last_input_value.setY(ret);
+ return ret;
}
-//
-// The return-value is also stored internally, so the Widget can show the current value, when the Tracker is running.
-//
-bool FunctionConfig::getLastPoint(QPointF& point ) {
+bool Map::getLastPoint(QPointF& point ) {
QMutexLocker foo(&_mutex);
- point = lastValueTracked;
- return _tracking_active;
+ point = last_input_value;
+ return activep;
}
-float FunctionConfig::getValueInternal(int x) {
+float Map::getValueInternal(int x) {
float sign = x < 0 ? -1 : 1;
- x = x < 0 ? -x : x;
+ x = std::abs(x);
float ret;
- if (!_data)
- ret = 0;
- else if (_size == 0)
- ret = 0;
- else if (x < 0)
- ret = 0;
- else if (x < _size && x >= 0)
- ret = _data[x];
- else
- ret = _data[_size - 1];
- return ret * sign;
+ int sz = cur.data.size();
+ if (sz == 0)
+ ret = 0;
+ else
+ ret = cur.data[std::max(std::min(x, sz-1), 0)];
+ return ret * sign;
}
static __inline QPointF ensureInBounds(QList<QPointF> points, int i) {
- int siz = points.size();
- if (siz == 0 || i < 0)
- return QPointF(0, 0);
- if (siz > i)
- return points[i];
- return points[siz - 1];
+ int siz = points.size();
+ if (siz == 0 || i < 0)
+ return QPointF(0, 0);
+ if (siz > i)
+ return points[i];
+ return points[siz - 1];
}
static bool sortFn(const QPointF& one, const QPointF& two) {
- return one.x() < two.x();
+ return one.x() < two.x();
}
-void FunctionConfig::reload() {
- _size = 0;
-
- if (_points.size())
- qStableSort(_points.begin(), _points.end(), sortFn);
-
- if (_data)
- delete[] _data;
- _data = NULL;
- if (_points.size()) {
- _data = new float[_size = MEMOIZE_PRECISION * _points[_points.size() - 1].x()];
-
- for (int i = 0; i < _size; i++)
- _data[i] = -1e6;
-
- for (int k = 0; k < _points[0].x() * MEMOIZE_PRECISION; k++) {
- if (k < _size)
- _data[k] = _points[0].y() * k / (_points[0].x() * MEMOIZE_PRECISION);
+void Map::reload() {
+ if (cur.input.size())
+ {
+ auto& input = cur.input;
+ auto& data = cur.data;
+
+ qStableSort(input.begin(), input.end(), sortFn);
+ data = std::vector<float>(MEMOIZE_PRECISION * input[input.size() - 1].x());
+
+ const int sz = data.size();
+
+ for (int i = 0; i < sz; i++)
+ data[i] = -1;
+
+ for (int k = 0; k < input[0].x() * MEMOIZE_PRECISION; k++) {
+ if (k < sz)
+ data[k] = input[0].y() * k / (input[0].x() * MEMOIZE_PRECISION);
}
-
- for (int i = 0; i < _points.size(); i++) {
- QPointF p0 = ensureInBounds(_points, i - 1);
- QPointF p1 = ensureInBounds(_points, i);
- QPointF p2 = ensureInBounds(_points, i + 1);
- QPointF p3 = ensureInBounds(_points, i + 2);
-
- int end = p2.x() * MEMOIZE_PRECISION;
+
+ for (int i = 0; i < sz; i++) {
+ QPointF p0 = ensureInBounds(input, i - 1);
+ QPointF p1 = ensureInBounds(input, i);
+ QPointF p2 = ensureInBounds(input, i + 1);
+ QPointF p3 = ensureInBounds(input, i + 2);
+
+ int end = std::min<int>(sz, p2.x() * MEMOIZE_PRECISION);
int start = p1.x() * MEMOIZE_PRECISION;
-
- for (int j = start; j < end && j < _size; j++) {
+
+ for (int j = start; j < end; j++) {
double t = (j - start) / (double) (end - start);
double t2 = t*t;
double t3 = t*t*t;
-
+
int x = .5 * ((2. * p1.x()) +
(-p0.x() + p2.x()) * t +
(2. * p0.x() - 5. * p1.x() + 4. * p2.x() - p3.x()) * t2 +
(-p0.x() + 3. * p1.x() - 3. * p2.x() + p3.x()) * t3)
* MEMOIZE_PRECISION;
-
+
float y = .5 * ((2. * p1.y()) +
- (-p0.y() + p2.y()) * t +
- (2. * p0.y() - 5. * p1.y() + 4. * p2.y() - p3.y()) * t2 +
- (-p0.y() + 3. * p1.y() - 3. * p2.y() + p3.y()) * t3);
-
- if (x >= 0 && x < _size)
- _data[x] = y;
+ (-p0.y() + p2.y()) * t +
+ (2. * p0.y() - 5. * p1.y() + 4. * p2.y() - p3.y()) * t2 +
+ (-p0.y() + 3. * p1.y() - 3. * p2.y() + p3.y()) * t3);
+
+ if (x >= 0 && x < sz)
+ data[x] = y;
}
- }
-
- float last = 0;
-
- for (int i = 0; i < _size; i++)
- {
- if (_data[i] == -1e6)
- _data[i] = last;
- last = _data[i];
- }
- }
-}
-
-FunctionConfig::~FunctionConfig() {
- if (_data)
- delete[] _data;
+ }
+
+ float last = 0;
+ for (int i = 0; i < sz; i++)
+ {
+ if (data[i] <= 0)
+ data[i] = last;
+ last = data[i];
+ }
+ }
+ else
+ cur.data.clear();
}
-//
-// Remove a Point from the Function.
-// Used by the Widget.
-//
-void FunctionConfig::removePoint(int i) {
+void Map::removePoint(int i) {
QMutexLocker foo(&_mutex);
- if (i >= 0 && i < _points.size())
+ if (i >= 0 && i < cur.input.size())
{
- _points.removeAt(i);
+ cur.input.removeAt(i);
reload();
}
}
-//
-// Add a Point to the Function.
-// Used by the Widget and by loadSettings.
-//
-void FunctionConfig::addPoint(QPointF pt) {
+void Map::addPoint(QPointF pt) {
QMutexLocker foo(&_mutex);
- _points.append(pt);
- reload();
+ cur.input.append(pt);
+ reload();
}
-//
-// Move a Function Point.
-// Used by the Widget.
-//
-void FunctionConfig::movePoint(int idx, QPointF pt) {
+void Map::movePoint(int idx, QPointF pt) {
QMutexLocker foo(&_mutex);
- if (idx >= 0 && idx < _points.size())
+ if (idx >= 0 && idx < cur.input.size())
{
- _points[idx] = pt;
+ cur.input[idx] = pt;
reload();
}
}
-//
-// Return the List of Points.
-// Used by the Widget.
-//
-QList<QPointF> FunctionConfig::getPoints() {
- QList<QPointF> ret;
+const QList<QPointF> Map::getPoints() {
QMutexLocker foo(&_mutex);
- for (int i = 0; i < _points.size(); i++) {
- ret.append(_points[i]);
- }
- return ret;
+ return cur.input;
+}
+
+void Map::invalidate_unsaved_settings()
+{
+ cur = saved;
+ reload();
}
-//
-// Load the Points for the Function from the INI-file designated by settings.
-// Settings for a specific Curve are loaded from their own Group in the INI-file.
-//
-void FunctionConfig::loadSettings(QSettings& settings) {
+void Map::loadSettings(QSettings& settings, const QString& title) {
QMutexLocker foo(&_mutex);
QPointF newPoint;
+ QList<QPointF> points;
+ settings.beginGroup(QString("Curves-%1").arg(title));
- QList<QPointF> points;
- settings.beginGroup(QString("Curves-%1").arg(_title));
-
int max = settings.value("point-count", 0).toInt();
- for (int i = 0; i < max; i++) {
- newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), 0).toFloat(),
- settings.value(QString("point-%1-y").arg(i), 0).toFloat());
- //
- // Make sure the new Point fits in the Function Range.
- // Maybe this can be improved?
- //
- if (newPoint.x() > _max_Input) {
- newPoint.setX(_max_Input);
- }
- if (newPoint.y() > _max_Output) {
- newPoint.setY(_max_Output);
- }
- points.append(newPoint);
- }
+ for (int i = 0; i < max; i++) {
+ newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), 0).toFloat(),
+ settings.value(QString("point-%1-y").arg(i), 0).toFloat());
+ if (newPoint.x() > max_x) {
+ newPoint.setX(max_x);
+ }
+ if (newPoint.y() > max_y) {
+ newPoint.setY(max_y);
+ }
+ points.append(newPoint);
+ }
+
settings.endGroup();
- _points = points;
- reload();
+ cur.input = points;
+ reload();
+ saved = cur;
}
-//
-// Save the Points for the Function to the INI-file designated by settings.
-// Settings for a specific Curve are saved in their own Group in the INI-file.
-// The number of Points is also saved, to make loading more convenient.
-//
-void FunctionConfig::saveSettings(QSettings& settings) {
+void Map::saveSettings(QSettings& settings, const QString& title) {
QMutexLocker foo(&_mutex);
- settings.beginGroup(QString("Curves-%1").arg(_title));
- int max = _points.size();
- settings.setValue("point-count", max);
- for (int i = 0; i < max; i++) {
- settings.setValue(QString("point-%1-x").arg(i), _points[i].x());
- settings.setValue(QString("point-%1-y").arg(i), _points[i].y());
+ settings.beginGroup(QString("Curves-%1").arg(title));
+ int max = cur.input.size();
+ settings.setValue("point-count", max);
+
+ for (int i = 0; i < max; i++) {
+ settings.setValue(QString("point-%1-x").arg(i), cur.input[i].x());
+ settings.setValue(QString("point-%1-y").arg(i), cur.input[i].y());
}
for (int i = max; true; i++)
@@ -277,5 +203,8 @@ void FunctionConfig::saveSettings(QSettings& settings) {
settings.remove(x);
settings.remove(QString("point-%1-y").arg(i));
}
- settings.endGroup();
+
+ saved = cur;
+
+ settings.endGroup();
}
diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h
index 4d771dfd..e24f54cf 100644
--- a/qfunctionconfigurator/functionconfig.h
+++ b/qfunctionconfigurator/functionconfig.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>
+/* Copyright (c) 2011-2014, 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,
@@ -13,63 +13,61 @@
#include <QString>
#include <QSettings>
#include <QMutex>
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
+#include <vector>
+#include "../facetracknoir/plugin-api.hpp"
+#include "../facetracknoir/qcopyable-mutex.hpp"
-#define MEMOIZE_PRECISION 100
-class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig {
+class OPENTRACK_EXPORT Map {
private:
- QMutex _mutex;
- QList<QPointF> _points;
- void reload();
- float* _data;
- int _size;
- QString _title;
+ struct State {
+ QList<QPointF> input;
+ std::vector<float> data;
+ };
+
+ static constexpr long MEMOIZE_PRECISION = 25;
+ void reload();
float getValueInternal(int x);
- QPointF lastValueTracked; // The last input value requested by the Tracker, with it's output-value.
- volatile bool _tracking_active;
- int _max_Input;
- int _max_Output;
- FunctionConfig(const FunctionConfig&) = delete;
+
+ MyMutex _mutex;
+ QPointF last_input_value;
+ volatile bool activep;
+ int max_x;
+ int max_y;
+
+ State cur, saved;
public:
- int maxInput() const { return _max_Input; }
- int maxOutput() const { return _max_Output; }
- //
- // Contructor(s) and destructor
- //
- FunctionConfig();
- FunctionConfig(QString title, int intMaxInput, int intMaxOutput);
- ~FunctionConfig();
+ int maxInput() const { return max_x; }
+ int maxOutput() const { return max_y; }
+ Map();
+ Map(int maxx, int maxy)
+ {
+ setMaxInput(maxx);
+ setMaxOutput(maxy);
+ }
float getValue(float x);
- bool getLastPoint(QPointF& point); // Get the last Point that was requested.
-
- //
- // Functions to manipulate the Function
- //
- void removePoint(int i);
+ bool getLastPoint(QPointF& point);
+ void removePoint(int i);
void removeAllPoints() {
QMutexLocker foo(&_mutex);
- _points.clear();
+ cur.input.clear();
reload();
}
- void addPoint(QPointF pt);
- void movePoint(int idx, QPointF pt);
- QList<QPointF> getPoints();
- void setMaxInput(int MaxInput) {
- _max_Input = MaxInput;
- }
- void setMaxOutput(int MaxOutput) {
- _max_Output = MaxOutput;
- }
+ void addPoint(QPointF pt);
+ void movePoint(int idx, QPointF pt);
+ const QList<QPointF> getPoints();
+ void setMaxInput(int MaxInput) {
+ max_x = MaxInput;
+ }
+ void setMaxOutput(int MaxOutput) {
+ max_y = MaxOutput;
+ }
- //
- // Functions to load/save the Function-Points to an INI-file
- //
- void saveSettings(QSettings& settings);
- void loadSettings(QSettings& settings);
+ void saveSettings(QSettings& settings, const QString& title);
+ void loadSettings(QSettings& settings, const QString& title);
+ void invalidate_unsaved_settings();
- void setTrackingActive(bool blnActive);
- QString getTitle() { return _title; }
+ void setTrackingActive(bool blnActive);
};
diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp
index 55d1e1bc..94a31be5 100644
--- a/qfunctionconfigurator/qfunctionconfigurator.cpp
+++ b/qfunctionconfigurator/qfunctionconfigurator.cpp
@@ -1,71 +1,47 @@
-/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl>
- * Adapted to FaceTrackNoIR by Wim Vriend.
- * 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 "qfunctionconfigurator/qfunctionconfigurator.h"
#include <QPainter>
#include <QPaintEvent>
-#include <QPainterPathStroker>
-#include <QPainterPath>
-#include <QBrush>
-#include <QFileDialog>
#include <QPen>
-#include <QMessageBox>
-#include <QImage>
#include <QPixmap>
#include <QTimer>
-#include <QtDebug>
#include <cmath>
-#include <QTabWidget>
-#include <QTabBar>
-#include <QFontMetrics>
+#include <algorithm>
static const int pointSize = 5;
-QFunctionConfigurator::QFunctionConfigurator(QWidget *parent)
- : QWidget(parent)
+QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) :
+ QWidget(parent),
+ _config(nullptr),
+ moving_control_point_idx(-1),
+ _draw_function(true)
{
- movingPoint = -1; // Index of that same point
- _config = 0;
- _draw_background = true;
- _draw_function = true;
update_range();
setMouseTracking(true);
}
-void QFunctionConfigurator::setConfig(FunctionConfig* config) {
- QSettings settings("opentrack"); // Registry settings (in HK_USER)
+void QFunctionConfigurator::setConfig(Map* config, const QString& name) {
+ QSettings settings("opentrack");
QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+ QSettings iniFile( currentFile, QSettings::IniFormat );
- config->loadSettings(iniFile);
+ config->loadSettings(iniFile, name);
_config = config;
- _draw_function = _draw_background = true;
+ _draw_function = true;
update_range();
update();
}
-void QFunctionConfigurator::saveSettings(QString settingsFile) {
- QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file)
-
- if (_config) {
- _config->saveSettings(iniFile);
- }
-}
-
void QFunctionConfigurator::drawBackground()
{
if (!_config)
return;
_background = QPixmap(width(), height());
+
QPainter painter(&_background);
painter.fillRect(rect(), QColor::fromRgb(204, 204, 204));
- painter.setRenderHint(QPainter::Antialiasing);
+
QColor bg_color(112, 154, 209);
- painter.fillRect(range, bg_color);
+ painter.fillRect(pixel_bounds, bg_color);
QFont font;
font.setPointSize(8);
@@ -79,61 +55,59 @@ void QFunctionConfigurator::drawBackground()
const int maxy = _config->maxOutput();
// horizontal grid
-
for (int i = 0; i < maxy; i += xstep)
{
- double y = range.height() - i * c.y() + range.y();
+ double y = pixel_bounds.height() - i * c.y() + pixel_bounds.y();
drawLine(&painter,
- QPointF(range.x(), y),
- QPointF(range.x() + range.width(), y),
+ QPointF(pixel_bounds.x(), y),
+ QPointF(pixel_bounds.x() + pixel_bounds.width(), y),
pen);
painter.drawText(QRectF(10,
y - metrics.height()/2,
- range.left(),
+ pixel_bounds.left(),
metrics.height()),
QString::number(i));
}
{
const int i = maxy;
- double y = range.height() - i * c.y() + range.y();
+ double y = pixel_bounds.height() - i * c.y() + pixel_bounds.y();
drawLine(&painter,
- QPointF(range.x(), y),
- QPointF(range.x() + range.width(), y),
+ QPointF(pixel_bounds.x(), y),
+ QPointF(pixel_bounds.x() + pixel_bounds.width(), y),
pen);
painter.drawText(QRectF(10,
y - metrics.height()/2,
- range.x() - 10,
+ pixel_bounds.x() - 10,
metrics.height()),
QString::number(i));
}
// vertical grid
-
for (int i = 0; i < maxx; i += ystep)
{
- double x = range.x() + i * c.x();
+ double x = pixel_bounds.x() + i * c.x();
drawLine(&painter,
- QPointF(x, range.y()),
- QPointF(x, range.y() + range.height()),
+ QPointF(x, pixel_bounds.y()),
+ QPointF(x, pixel_bounds.y() + pixel_bounds.height()),
pen);
const QString text = QString::number(i);
painter.drawText(QRectF(x - metrics.width(text)/2,
- range.height() + 10 + metrics.height(),
+ pixel_bounds.height() + 10 + metrics.height(),
metrics.width(text),
metrics.height()),
text);
}
{
const int i = maxx;
- double x = range.x() + i * c.x();
+ double x = pixel_bounds.x() + i * c.x();
drawLine(&painter,
- QPointF(x, range.y()),
- QPointF(x, range.y() + range.height()),
+ QPointF(x, pixel_bounds.y()),
+ QPointF(x, pixel_bounds.y() + pixel_bounds.height()),
pen);
const QString text = QString::number(i);
painter.drawText(QRectF(x - metrics.width(text)/2,
- range.height() + 10 + metrics.height(),
+ pixel_bounds.height() + 10 + metrics.height(),
metrics.width(text),
metrics.height()),
text);
@@ -144,102 +118,82 @@ void QFunctionConfigurator::drawFunction()
{
if (!_config)
return;
- int i;
- QPointF prevPoint;
- QPointF currentPoint;
_function = QPixmap(_background);
QPainter painter(&_function);
-
- painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);
QList<QPointF> points = _config->getPoints();
- for (i = 0; i < points.size(); i++) {
- currentPoint = point_to_pixel( points[i] ); // Get the next point and convert it to Widget measures
- drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120));
- lastPoint = currentPoint; // Remember which point is the rightmost in the graph
+ for (int i = 0; i < points.size(); i++) {
+ drawPoint(&painter,
+ point_to_pixel(points[i]),
+ QColor(200, 200, 210, 120));
}
+ QPen pen(spline_color, 1.2, Qt::SolidLine);
- QPen pen(colBezier, 1.2, Qt::SolidLine);
-
- prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis
- double max = _config->maxInput();
+ static constexpr double step = 1.02;
+ const double max = _config->maxInput();
+
QPointF prev = point_to_pixel(QPointF(0, 0));
- const double step = 1.01;
for (double i = 0; i < max; i += step) {
double val = _config->getValue(i);
QPointF cur = point_to_pixel(QPointF(i, val));
drawLine(&painter, prev, cur, pen);
prev = cur;
}
- painter.restore();
}
void QFunctionConfigurator::paintEvent(QPaintEvent *e)
{
- QPointF prevPoint;
- QPointF currentPoint;
- QPointF actualPos;
- int i;
-
QPainter p(this);
- p.setRenderHint(QPainter::Antialiasing);
- if (_draw_background) {
+ if (_background.isNull())
drawBackground();
- _draw_background = false;
- }
- p.drawPixmap(e->rect(), _background);
if (_draw_function) {
- drawFunction(); // Draw the Function on a Pixmap
_draw_function = false;
+ drawFunction();
}
- p.drawPixmap(e->rect(), _function); // Always draw the background and the function
+
+ p.drawPixmap(e->rect(), _function);
if (_config) {
QPen pen(Qt::white, 1, Qt::SolidLine);
QList<QPointF> points = _config->getPoints();
- if (movingPoint >= 0 && movingPoint < points.size()) {
- prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis
- for (i = 0; i < points.size(); i++) {
- currentPoint = point_to_pixel( points[i] ); // Get the next point and convert it to Widget measures
- drawLine(&p, prevPoint, currentPoint, pen);
- prevPoint = currentPoint;
+ if (points.size() && moving_control_point_idx >= 0 && moving_control_point_idx < points.size()) {
+ QPointF prev = points[0];
+ for (int i = 1; i < points.size(); i++) {
+ auto tmp = point_to_pixel(points[i]);
+ drawLine(&p, prev, tmp, pen);
+ prev = tmp;
}
pen.setWidth(1);
pen.setColor( Qt::white );
pen.setStyle( Qt::DashLine );
- actualPos = point_to_pixel(points[movingPoint]);
- drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
- drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.height() + range.top()), pen);
+ QPointF pixel_pos = point_to_pixel(points[moving_control_point_idx]);
+ drawLine(&p, QPoint(pixel_bounds.left(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_pos.y()), pen);
+ drawLine(&p, QPoint(pixel_pos.x(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_bounds.height() + pixel_bounds.top()), pen);
}
- //
// If the Tracker is active, the 'Last Point' it requested is recorded.
// Show that point on the graph, with some lines to assist.
// This new feature is very handy for tweaking the curves!
- //
- if (_config->getLastPoint( currentPoint )) {
- actualPos = point_to_pixel( QPointF(fabs(currentPoint.x()), fabs(currentPoint.y())) );
- drawPoint(&p, actualPos, QColor(255, 0, 0, 120));
+ QPointF last;
+ if (_config->getLastPoint(last)) {
+ QPointF pixel_pos = point_to_pixel( QPointF(fabs(last.x()), fabs(last.y())) );
+ drawPoint(&p, pixel_pos, QColor(255, 0, 0, 120));
pen.setWidth(1);
pen.setColor( Qt::black );
pen.setStyle( Qt::SolidLine );
- drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
- drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.width()), pen);
+ drawLine(&p, QPoint(pixel_bounds.left(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_pos.y()), pen);
+ drawLine(&p, QPoint(pixel_pos.x(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_bounds.width()), pen);
}
-
}
}
-//
-// Draw the handle, to move the Bezier-curve.
-//
void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG )
{
painter->save();
@@ -251,7 +205,7 @@ void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QCo
painter->restore();
}
-void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen)
+void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen &pen)
{
painter->save();
painter->setPen(pen);
@@ -267,19 +221,17 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e)
QList<QPointF> points = _config->getPoints();
if (e->button() == Qt::LeftButton) {
bool bTouchingPoint = false;
- movingPoint = -1;
+ moving_control_point_idx = -1;
if (_config) {
for (int i = 0; i < points.size(); i++) {
- if ( point_within_pixel(points[i], e->pos() ) ) {
+ if (point_within_pixel(points[i], e->pos())) {
bTouchingPoint = true;
- movingPoint = i;
- timer.restart();
+ moving_control_point_idx = i;
break;
}
}
if (!bTouchingPoint) {
_config->addPoint(pixel_coord_to_point(e->pos()));
- emit CurveChanged( true );
}
}
}
@@ -288,7 +240,7 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e)
if (_config) {
int found_pt = -1;
for (int i = 0; i < points.size(); i++) {
- if ( point_within_pixel(points[i], e->pos() ) ) {
+ if (point_within_pixel(points[i], e->pos())) {
found_pt = i;
break;
}
@@ -296,9 +248,8 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e)
if (found_pt != -1) {
_config->removePoint(found_pt);
- emit CurveChanged( true );
}
- movingPoint = -1;
+ moving_control_point_idx = -1;
}
}
_draw_function = true;
@@ -309,29 +260,43 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e)
{
if (!_config)
return;
+
+ static constexpr int min_refresh_delay = 12;
+
+ if (timer.isValid() && timer.elapsed() < min_refresh_delay)
+ return;
+
+ static constexpr int refresh_delay = 17;
QList<QPointF> points = _config->getPoints();
- const int refresh_delay = 50;
- if (movingPoint >= 0 && movingPoint < points.size()) {
+ if (moving_control_point_idx != -1 && moving_control_point_idx < points.size()) {
setCursor(Qt::ClosedHandCursor);
-
- if (timer.isValid() && timer.elapsed() > refresh_delay)
+
+ bool overlap = false;
+
+ QPointF new_pt = pixel_coord_to_point(e->pos());
+
+ if (moving_control_point_idx + 1 < points.size())
+ overlap |= new_pt.x() > points[moving_control_point_idx+1].x();
+ if (moving_control_point_idx != 0)
+ overlap |= new_pt.x() < points[moving_control_point_idx-1].x();
+
+ if (overlap)
+ moving_control_point_idx = -1;
+ else if (timer.isValid() && timer.elapsed() > refresh_delay)
{
timer.restart();
- QPointF new_pt = pixel_coord_to_point(e->pos());
- points[movingPoint] = new_pt;
- _config->movePoint(movingPoint, new_pt);
+ points[moving_control_point_idx] = new_pt;
+ _config->movePoint(moving_control_point_idx, new_pt);
_draw_function = true;
update();
}
}
else {
bool bTouchingPoint = false;
- if (_config) {
- for (int i = 0; i < points.size(); i++) {
- if ( point_within_pixel(points[i], e->pos() ) ) {
- bTouchingPoint = true;
- }
+ for (int i = 0; i < points.size(); i++) {
+ if ( point_within_pixel(points[i], e->pos() ) ) {
+ bTouchingPoint = true;
}
}
@@ -348,38 +313,54 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e)
{
if (!_config)
return;
- QList<QPointF> points = _config->getPoints();
if (e->button() == Qt::LeftButton) {
- timer.invalidate();
- if (movingPoint >= 0 && movingPoint < points.size()) {
- emit CurveChanged( true );
+ QList<QPointF> points = _config->getPoints();
+ if (moving_control_point_idx >= 0 && moving_control_point_idx < points.size()) {
if (_config) {
- _config->movePoint(movingPoint, pixel_coord_to_point(e->pos()));
+ _config->movePoint(moving_control_point_idx, pixel_coord_to_point(e->pos()));
}
}
setCursor(Qt::ArrowCursor);
- movingPoint = -1;
+ moving_control_point_idx = -1;
+
+ _draw_function = true;
+ update();
}
+}
+void QFunctionConfigurator::update_range()
+{
+ if (!_config)
+ return;
+
+ const double w = width(), h = height();
+ const double mwl = 40, mhl = 20;
+ const double mwr = 15, mhr = 35;
+
+ pixel_bounds = QRectF(mwl, mhl, (w - mwl - mwr), (h - mhl - mhr));
+ c = QPointF(pixel_bounds.width() / _config->maxInput(), pixel_bounds.height() / _config->maxOutput());
_draw_function = true;
- update();
+
+ _background = QPixmap();
+ _function = QPixmap();
}
-bool QFunctionConfigurator::point_within_pixel(QPointF pt, QPointF pixel) const
+bool QFunctionConfigurator::point_within_pixel(const QPointF &pt, const QPointF &pixel)
{
- QPointF pixel2(range.x() + pt.x() * c.x(), (range.y() + range.height() - pt.y() * c.y()));
+ QPointF pixel2(pixel_bounds.x() + pt.x() * c.x(),
+ (pixel_bounds.y() + pixel_bounds.height() - pt.y() * c.y()));
return pixel2.x() >= pixel.x() - pointSize && pixel2.x() < pixel.x() + pointSize &&
pixel2.y() >= pixel.y() - pointSize && pixel2.y() < pixel.y() + pointSize;
}
-QPointF QFunctionConfigurator::pixel_coord_to_point(QPointF point) const
+QPointF QFunctionConfigurator::pixel_coord_to_point(const QPointF& point)
{
if (!_config)
return QPointF(-1, -1);
- double x = (point.x() - range.x()) / c.x();
- double y = (range.height() - point.y() + range.y()) / c.y();
+ double x = (point.x() - pixel_bounds.x()) / c.x();
+ double y = (pixel_bounds.height() - point.y() + pixel_bounds.y()) / c.y();
if (x < 0)
x = 0;
@@ -394,20 +375,14 @@ QPointF QFunctionConfigurator::pixel_coord_to_point(QPointF point) const
return QPointF(x, y);
}
-QPointF QFunctionConfigurator::point_to_pixel(QPointF point) const
-{
- return QPointF(range.x() + point.x() * c.x(),
- range.y() + range.height() - point.y() * c.y());
-}
-
-void QFunctionConfigurator::setColorBezier(QColor color)
+QPointF QFunctionConfigurator::point_to_pixel(const QPointF& point)
{
- colBezier = color;
- update();
+ return QPointF(pixel_bounds.x() + point.x() * c.x(),
+ pixel_bounds.y() + pixel_bounds.height() - point.y() * c.y());
}
void QFunctionConfigurator::resizeEvent(QResizeEvent *)
{
update_range();
- repaint();
+ update();
}
diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h
index 1f6b4f78..229d9977 100644
--- a/qfunctionconfigurator/qfunctionconfigurator.h
+++ b/qfunctionconfigurator/qfunctionconfigurator.h
@@ -1,92 +1,71 @@
-/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl>
- * Adapted to FaceTrackNoIR by Wim Vriend.
+/* Copyright (c) 2011-2014 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.
*/
-#ifndef QFUNCTIONCONFIGURATOR_H
-#define QFUNCTIONCONFIGURATOR_H
+
+// Adapted to FaceTrackNoIR by Wim Vriend.
+
+#pragma once
#include <QWidget>
#include <QtGui>
#include <QPointF>
#include <QElapsedTimer>
#include "qfunctionconfigurator/functionconfig.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-
-//
-// The FunctionConfigurator Widget is used to display and configure a function (curve).
-// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function.
-//
-// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the
-// Widget and the Widget used to change the Function.
-//
+#include "facetracknoir/plugin-api.hpp"
-class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget
+class OPENTRACK_EXPORT QFunctionConfigurator : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier)
+public:
+ QFunctionConfigurator(QWidget *parent = 0);
+
+ Map* config();
+ void setConfig(Map* config, const QString &name);
+
QColor colorBezier() const
{
- return colBezier;
+ return spline_color;
+ }
+ void setColorBezier(QColor color)
+ {
+ spline_color = color;
+ update();
}
-public:
- QFunctionConfigurator(QWidget *parent = 0);
- FunctionConfig* config();
-
- void setConfig(FunctionConfig* config);
- void saveSettings(QString settingsFile);
-
-signals:
- void CurveChanged(bool);
-
-public slots:
- void setColorBezier(QColor);
protected slots:
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
-
-protected:
+private:
void drawBackground();
void drawFunction();
void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG );
- void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen);
- bool point_within_pixel(QPointF pt, QPointF pixel) const;
-
+ void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen& pen);
+ bool point_within_pixel(const QPointF& pt, const QPointF& pixel);
protected:
- virtual void resizeEvent(QResizeEvent *);
-
+ void resizeEvent(QResizeEvent *) override;
private:
- void update_range() {
- if (!_config)
- return;
- double w = width(), h = height();
- const double mwl = 40, mhl = 20;
- const double mwr = 15, mhr = 35;
- range = QRectF(mwl, mhl, (w - mwl - mwr), (h - mhl - mhr));
- c = QPointF(range.width() / _config->maxInput(), range.height() / _config->maxOutput());
- _draw_function = _draw_background = true;
- }
+ void update_range();
- QRectF range; // The actual rectangle for the Bezier-curve
- QPointF lastPoint; // The right-most point of the Function
- QPointF pixel_coord_to_point (QPointF point) const; // Convert the graphical Point to a real-life Point
- QPointF point_to_pixel (QPointF point) const; // Convert the Point to a graphical Point
+ QPointF pixel_coord_to_point (const QPointF& point);
+ QPointF point_to_pixel (const QPointF& point);
- int movingPoint;
+ Map* _config;
+
+ // bounds of the rectangle user can interact with
+ QRectF pixel_bounds;
+
+ int moving_control_point_idx;
QElapsedTimer timer;
QPointF c;
- QColor colBezier; // Color of Bezier curve
-
- bool _draw_background; // Flag to determine if the background should be (re-)drawn on the QPixmap
- QPixmap _background; // Image of the static parts (axis, lines, etc.)
- bool _draw_function; // Flag to determine if the function should be (re-)drawn on the QPixmap
- QPixmap _function; // Image of the function (static unless edited by the user)
-
- FunctionConfig* _config;
+ QColor spline_color;
+
+ QPixmap _background;
+ QPixmap _function;
+ bool _draw_function;
};
-
-#endif // QFUNCTIONCONFIGURATOR_H
diff --git a/qxt-mini/plat/qxtglobalshortcut_mac.cpp b/qxt-mini/plat/qxtglobalshortcut_mac.cpp
index f43c773a..fbf86a94 100644
--- a/qxt-mini/plat/qxtglobalshortcut_mac.cpp
+++ b/qxt-mini/plat/qxtglobalshortcut_mac.cpp
@@ -1,4 +1,4 @@
-#include <Carbon/Carbon.h>
+#include <Carbon/Carbon.h>
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
@@ -29,235 +29,235 @@
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
-#include "qxtglobalshortcut_p.h"
-#include <QMap>
-#include <QHash>
-#include <QtDebug>
-#include <QApplication>
-
-typedef QPair<uint, uint> Identifier;
-static QMap<quint32, EventHotKeyRef> keyRefs;
-static QHash<Identifier, quint32> keyIDs;
-static quint32 hotKeySerial = 0;
-static bool qxt_mac_handler_installed = false;
-
-OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
-{
- Q_UNUSED(nextHandler);
- Q_UNUSED(data);
- if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
- {
- EventHotKeyID keyID;
- GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
- Identifier id = keyIDs.key(keyID.id);
+#include "qxtglobalshortcut_p.h"
+#include <QMap>
+#include <QHash>
+#include <QtDebug>
+#include <QApplication>
+
+typedef QPair<uint, uint> Identifier;
+static QMap<quint32, EventHotKeyRef> keyRefs;
+static QHash<Identifier, quint32> keyIDs;
+static quint32 hotKeySerial = 0;
+static bool qxt_mac_handler_installed = false;
+
+OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
+{
+ Q_UNUSED(nextHandler);
+ Q_UNUSED(data);
+ if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
+ {
+ EventHotKeyID keyID;
+ GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
+ Identifier id = keyIDs.key(keyID.id);
if(id != Identifier())
- QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
- }
- return noErr;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= shiftKey;
- if (modifiers & Qt::ControlModifier)
- native |= cmdKey;
- if (modifiers & Qt::AltModifier)
- native |= optionKey;
- if (modifiers & Qt::MetaModifier)
- native |= controlKey;
- if (modifiers & Qt::KeypadModifier)
- native |= kEventKeyModifierNumLockMask;
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- UTF16Char ch;
- // Constants found in NSEvent.h from AppKit.framework
- switch (key)
- {
- case Qt::Key_Return:
- return kVK_Return;
- case Qt::Key_Enter:
- return kVK_ANSI_KeypadEnter;
- case Qt::Key_Tab:
- return kVK_Tab;
- case Qt::Key_Space:
- return kVK_Space;
- case Qt::Key_Backspace:
- return kVK_Delete;
- case Qt::Key_Control:
- return kVK_Command;
- case Qt::Key_Shift:
- return kVK_Shift;
- case Qt::Key_CapsLock:
- return kVK_CapsLock;
- case Qt::Key_Option:
- return kVK_Option;
- case Qt::Key_Meta:
- return kVK_Control;
- case Qt::Key_F17:
- return kVK_F17;
- case Qt::Key_VolumeUp:
- return kVK_VolumeUp;
- case Qt::Key_VolumeDown:
- return kVK_VolumeDown;
- case Qt::Key_F18:
- return kVK_F18;
- case Qt::Key_F19:
- return kVK_F19;
- case Qt::Key_F20:
- return kVK_F20;
- case Qt::Key_F5:
- return kVK_F5;
- case Qt::Key_F6:
- return kVK_F6;
- case Qt::Key_F7:
- return kVK_F7;
- case Qt::Key_F3:
- return kVK_F3;
- case Qt::Key_F8:
- return kVK_F8;
- case Qt::Key_F9:
- return kVK_F9;
- case Qt::Key_F11:
- return kVK_F11;
- case Qt::Key_F13:
- return kVK_F13;
- case Qt::Key_F16:
- return kVK_F16;
- case Qt::Key_F14:
- return kVK_F14;
- case Qt::Key_F10:
- return kVK_F10;
- case Qt::Key_F12:
- return kVK_F12;
- case Qt::Key_F15:
- return kVK_F15;
- case Qt::Key_Help:
- return kVK_Help;
- case Qt::Key_Home:
- return kVK_Home;
- case Qt::Key_PageUp:
- return kVK_PageUp;
- case Qt::Key_Delete:
- return kVK_ForwardDelete;
- case Qt::Key_F4:
- return kVK_F4;
- case Qt::Key_End:
- return kVK_End;
- case Qt::Key_F2:
- return kVK_F2;
- case Qt::Key_PageDown:
- return kVK_PageDown;
- case Qt::Key_F1:
- return kVK_F1;
- case Qt::Key_Left:
- return kVK_LeftArrow;
- case Qt::Key_Right:
- return kVK_RightArrow;
- case Qt::Key_Down:
- return kVK_DownArrow;
- case Qt::Key_Up:
- return kVK_UpArrow;
- default:
- ;
- }
-
- if (key == Qt::Key_Escape) ch = 27;
- else if (key == Qt::Key_Return) ch = 13;
- else if (key == Qt::Key_Enter) ch = 3;
- else if (key == Qt::Key_Tab) ch = 9;
- else ch = key;
-
- CFDataRef currentLayoutData;
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
-
- if (currentKeyboard == NULL)
- return 0;
-
- currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
- CFRelease(currentKeyboard);
- if (currentLayoutData == NULL)
- return 0;
-
- UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
- UCKeyboardTypeHeader* table = header->keyboardTypeList;
-
- uint8_t *data = (uint8_t*)header;
- // God, would a little documentation for this shit kill you...
- for (quint32 i=0; i < header->keyboardTypeCount; i++)
- {
- UCKeyStateRecordsIndex* stateRec = 0;
- if (table[i].keyStateRecordsIndexOffset != 0)
- {
- stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
- if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
- }
-
- UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
- if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
-
- for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
- {
- UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
- for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
- {
- if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
- {
- long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
- if (stateRec && idx < stateRec->keyStateRecordCount)
- {
- UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
- if (rec->stateZeroCharData == ch) return k;
- }
- }
- else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
- {
- if (keyToChar[k] == ch) return k;
- }
- } // for k
- } // for j
- } // for i
- return 0;
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- if (!qxt_mac_handler_installed)
- {
+ QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
+ }
+ return noErr;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= shiftKey;
+ if (modifiers & Qt::ControlModifier)
+ native |= cmdKey;
+ if (modifiers & Qt::AltModifier)
+ native |= optionKey;
+ if (modifiers & Qt::MetaModifier)
+ native |= controlKey;
+ if (modifiers & Qt::KeypadModifier)
+ native |= kEventKeyModifierNumLockMask;
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ UTF16Char ch;
+ // Constants found in NSEvent.h from AppKit.framework
+ switch (key)
+ {
+ case Qt::Key_Return:
+ return kVK_Return;
+ case Qt::Key_Enter:
+ return kVK_ANSI_KeypadEnter;
+ case Qt::Key_Tab:
+ return kVK_Tab;
+ case Qt::Key_Space:
+ return kVK_Space;
+ case Qt::Key_Backspace:
+ return kVK_Delete;
+ case Qt::Key_Control:
+ return kVK_Command;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_CapsLock:
+ return kVK_CapsLock;
+ case Qt::Key_Option:
+ return kVK_Option;
+ case Qt::Key_Meta:
+ return kVK_Control;
+ case Qt::Key_F17:
+ return kVK_F17;
+ case Qt::Key_VolumeUp:
+ return kVK_VolumeUp;
+ case Qt::Key_VolumeDown:
+ return kVK_VolumeDown;
+ case Qt::Key_F18:
+ return kVK_F18;
+ case Qt::Key_F19:
+ return kVK_F19;
+ case Qt::Key_F20:
+ return kVK_F20;
+ case Qt::Key_F5:
+ return kVK_F5;
+ case Qt::Key_F6:
+ return kVK_F6;
+ case Qt::Key_F7:
+ return kVK_F7;
+ case Qt::Key_F3:
+ return kVK_F3;
+ case Qt::Key_F8:
+ return kVK_F8;
+ case Qt::Key_F9:
+ return kVK_F9;
+ case Qt::Key_F11:
+ return kVK_F11;
+ case Qt::Key_F13:
+ return kVK_F13;
+ case Qt::Key_F16:
+ return kVK_F16;
+ case Qt::Key_F14:
+ return kVK_F14;
+ case Qt::Key_F10:
+ return kVK_F10;
+ case Qt::Key_F12:
+ return kVK_F12;
+ case Qt::Key_F15:
+ return kVK_F15;
+ case Qt::Key_Help:
+ return kVK_Help;
+ case Qt::Key_Home:
+ return kVK_Home;
+ case Qt::Key_PageUp:
+ return kVK_PageUp;
+ case Qt::Key_Delete:
+ return kVK_ForwardDelete;
+ case Qt::Key_F4:
+ return kVK_F4;
+ case Qt::Key_End:
+ return kVK_End;
+ case Qt::Key_F2:
+ return kVK_F2;
+ case Qt::Key_PageDown:
+ return kVK_PageDown;
+ case Qt::Key_F1:
+ return kVK_F1;
+ case Qt::Key_Left:
+ return kVK_LeftArrow;
+ case Qt::Key_Right:
+ return kVK_RightArrow;
+ case Qt::Key_Down:
+ return kVK_DownArrow;
+ case Qt::Key_Up:
+ return kVK_UpArrow;
+ default:
+ ;
+ }
+
+ if (key == Qt::Key_Escape) ch = 27;
+ else if (key == Qt::Key_Return) ch = 13;
+ else if (key == Qt::Key_Enter) ch = 3;
+ else if (key == Qt::Key_Tab) ch = 9;
+ else ch = key;
+
+ CFDataRef currentLayoutData;
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+
+ if (currentKeyboard == NULL)
+ return 0;
+
+ currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+ CFRelease(currentKeyboard);
+ if (currentLayoutData == NULL)
+ return 0;
+
+ UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
+ UCKeyboardTypeHeader* table = header->keyboardTypeList;
+
+ uint8_t *data = (uint8_t*)header;
+ // God, would a little documentation for this shit kill you...
+ for (quint32 i=0; i < header->keyboardTypeCount; i++)
+ {
+ UCKeyStateRecordsIndex* stateRec = 0;
+ if (table[i].keyStateRecordsIndexOffset != 0)
+ {
+ stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
+ if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
+ }
+
+ UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
+ if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
+
+ for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
+ {
+ UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
+ for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
+ {
+ if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
+ {
+ long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
+ if (stateRec && idx < stateRec->keyStateRecordCount)
+ {
+ UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
+ if (rec->stateZeroCharData == ch) return k;
+ }
+ }
+ else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
+ {
+ if (keyToChar[k] == ch) return k;
+ }
+ } // for k
+ } // for j
+ } // for i
+ return 0;
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ if (!qxt_mac_handler_installed)
+ {
qxt_mac_handler_installed = true;
- EventTypeSpec t;
- t.eventClass = kEventClassKeyboard;
- t.eventKind = kEventHotKeyPressed;
- InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
- }
-
- EventHotKeyID keyID;
- keyID.signature = 'cute';
- keyID.id = ++hotKeySerial;
-
- EventHotKeyRef ref = 0;
- bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
- if (rv)
- {
- keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
- keyRefs.insert(keyID.id, ref);
- }
- return rv;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- Identifier id(nativeMods, nativeKey);
- if (!keyIDs.contains(id)) return false;
-
- EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
- keyIDs.remove(id);
- return !UnregisterEventHotKey(ref);
-}
+ EventTypeSpec t;
+ t.eventClass = kEventClassKeyboard;
+ t.eventKind = kEventHotKeyPressed;
+ InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
+ }
+
+ EventHotKeyID keyID;
+ keyID.signature = 'cute';
+ keyID.id = ++hotKeySerial;
+
+ EventHotKeyRef ref = 0;
+ bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
+ if (rv)
+ {
+ keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
+ keyRefs.insert(keyID.id, ref);
+ }
+ return rv;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Identifier id(nativeMods, nativeKey);
+ if (!keyIDs.contains(id)) return false;
+
+ EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
+ keyIDs.remove(id);
+ return !UnregisterEventHotKey(ref);
+}
bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
void *message, long *result)
{
diff --git a/qxt-mini/plat/qxtglobalshortcut_x11.cpp b/qxt-mini/plat/qxtglobalshortcut_x11.cpp
index 0c203dd8..f18f86db 100644
--- a/qxt-mini/plat/qxtglobalshortcut_x11.cpp
+++ b/qxt-mini/plat/qxtglobalshortcut_x11.cpp
@@ -1,235 +1,235 @@
-#include "../qxtglobalshortcut_p.h"
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#include <QVector>
-#include <QApplication>
-// include private header for great justice -sh 20131015
-#include <X11/Xlib.h>
-#include <xcb/xcb.h>
-#include "qplatformnativeinterface.h"
-
-namespace {
-
-const QVector<quint32> maskModifiers = QVector<quint32>()
- << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
-
-typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);
-
-class QxtX11ErrorHandler {
-public:
- static bool error;
-
- static int qxtX11ErrorHandler(Display *display, XErrorEvent *event)
- {
- Q_UNUSED(display);
- switch (event->error_code)
- {
- case BadAccess:
- case BadValue:
- case BadWindow:
- if (event->request_code == 33 /* X_GrabKey */ ||
- event->request_code == 34 /* X_UngrabKey */)
- {
- error = true;
- //TODO:
- //char errstr[256];
- //XGetErrorText(dpy, err->error_code, errstr, 256);
- }
- }
- return 0;
- }
-
- QxtX11ErrorHandler()
- {
- error = false;
- m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
- }
-
- ~QxtX11ErrorHandler()
- {
- XSetErrorHandler(m_previousErrorHandler);
- }
-
-private:
- X11ErrorHandler m_previousErrorHandler;
-};
-
-bool QxtX11ErrorHandler::error = false;
-
-class QxtX11Data {
-public:
- QxtX11Data()
- {
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- m_display = QX11Info::display();
-#else
- QPlatformNativeInterface *native = qApp->platformNativeInterface();
- void *display = native->nativeResourceForScreen(QByteArray("display"),
- QGuiApplication::primaryScreen());
- m_display = reinterpret_cast<Display *>(display);
-#endif
- }
-
- bool isValid()
- {
- return m_display != 0;
- }
-
- Display *display()
- {
- Q_ASSERT(isValid());
- return m_display;
- }
-
- Window rootWindow()
- {
- return DefaultRootWindow(display());
- }
-
- bool grabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) {
- XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True,
- GrabModeAsync, GrabModeAsync);
- }
-
- if (errorHandler.error) {
- ungrabKey(keycode, modifiers, window);
- return false;
- }
-
- return true;
- }
-
- bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- foreach (quint32 maskMods, maskModifiers) {
- XUngrabKey(display(), keycode, modifiers | maskMods, window);
- }
-
- return !errorHandler.error;
- }
-
-private:
- Display *m_display;
-};
-
-} // namespace
-
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
-bool QxtGlobalShortcutPrivate::eventFilter(void *message)
-{
- XEvent *event = static_cast<XEvent *>(message);
- if (event->type == KeyPress)
- {
- XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event);
- unsigned int keycode = key->keycode;
- unsigned int keystate = key->state;
-#else
-bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
- void *message, long *result)
-{
- Q_UNUSED(result);
-
- xcb_key_press_event_t *kev = 0;
- if (eventType == "xcb_generic_event_t") {
- xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
- if ((ev->response_type & 127) == XCB_KEY_PRESS)
- kev = static_cast<xcb_key_press_event_t *>(message);
- }
-
- if (kev != 0) {
- unsigned int keycode = kev->detail;
- unsigned int keystate = 0;
- if(kev->state & XCB_MOD_MASK_1)
- keystate |= Mod1Mask;
- if(kev->state & XCB_MOD_MASK_CONTROL)
- keystate |= ControlMask;
- if(kev->state & XCB_MOD_MASK_4)
- keystate |= Mod4Mask;
- if(kev->state & XCB_MOD_MASK_SHIFT)
- keystate |= ShiftMask;
-#endif
- activateShortcut(keycode,
- // Mod1Mask == Alt, Mod4Mask == Meta
- keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
- }
- return false;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= ShiftMask;
- if (modifiers & Qt::ControlModifier)
- native |= ControlMask;
- if (modifiers & Qt::AltModifier)
- native |= Mod1Mask;
- if (modifiers & Qt::MetaModifier)
- native |= Mod4Mask;
-
- // TODO: resolve these?
- //if (modifiers & Qt::MetaModifier)
- //if (modifiers & Qt::KeypadModifier)
- //if (modifiers & Qt::GroupSwitchModifier)
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- QxtX11Data x11;
- if (!x11.isValid())
- return 0;
-
- KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
- if (keysym == NoSymbol)
- keysym = static_cast<ushort>(key);
-
- return XKeysymToKeycode(x11.display(), keysym);
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow());
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow());
-}
+#include "../qxtglobalshortcut_p.h"
+/****************************************************************************
+** Copyright (c) 2006 - 2011, the LibQxt project.
+** See the Qxt AUTHORS file for a list of authors and copyright holders.
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the LibQxt project nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+** <http://libqxt.org> <foundation@libqxt.org>
+*****************************************************************************/
+
+#include <QVector>
+#include <QApplication>
+// include private header for great justice -sh 20131015
+#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+#include "qplatformnativeinterface.h"
+
+namespace {
+
+const QVector<quint32> maskModifiers = QVector<quint32>()
+ << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
+
+typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);
+
+class QxtX11ErrorHandler {
+public:
+ static bool error;
+
+ static int qxtX11ErrorHandler(Display *display, XErrorEvent *event)
+ {
+ Q_UNUSED(display);
+ switch (event->error_code)
+ {
+ case BadAccess:
+ case BadValue:
+ case BadWindow:
+ if (event->request_code == 33 /* X_GrabKey */ ||
+ event->request_code == 34 /* X_UngrabKey */)
+ {
+ error = true;
+ //TODO:
+ //char errstr[256];
+ //XGetErrorText(dpy, err->error_code, errstr, 256);
+ }
+ }
+ return 0;
+ }
+
+ QxtX11ErrorHandler()
+ {
+ error = false;
+ m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
+ }
+
+ ~QxtX11ErrorHandler()
+ {
+ XSetErrorHandler(m_previousErrorHandler);
+ }
+
+private:
+ X11ErrorHandler m_previousErrorHandler;
+};
+
+bool QxtX11ErrorHandler::error = false;
+
+class QxtX11Data {
+public:
+ QxtX11Data()
+ {
+#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+ m_display = QX11Info::display();
+#else
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ void *display = native->nativeResourceForScreen(QByteArray("display"),
+ QGuiApplication::primaryScreen());
+ m_display = reinterpret_cast<Display *>(display);
+#endif
+ }
+
+ bool isValid()
+ {
+ return m_display != 0;
+ }
+
+ Display *display()
+ {
+ Q_ASSERT(isValid());
+ return m_display;
+ }
+
+ Window rootWindow()
+ {
+ return DefaultRootWindow(display());
+ }
+
+ bool grabKey(quint32 keycode, quint32 modifiers, Window window)
+ {
+ QxtX11ErrorHandler errorHandler;
+
+ for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) {
+ XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True,
+ GrabModeAsync, GrabModeAsync);
+ }
+
+ if (errorHandler.error) {
+ ungrabKey(keycode, modifiers, window);
+ return false;
+ }
+
+ return true;
+ }
+
+ bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
+ {
+ QxtX11ErrorHandler errorHandler;
+
+ foreach (quint32 maskMods, maskModifiers) {
+ XUngrabKey(display(), keycode, modifiers | maskMods, window);
+ }
+
+ return !errorHandler.error;
+ }
+
+private:
+ Display *m_display;
+};
+
+} // namespace
+
+#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+bool QxtGlobalShortcutPrivate::eventFilter(void *message)
+{
+ XEvent *event = static_cast<XEvent *>(message);
+ if (event->type == KeyPress)
+ {
+ XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event);
+ unsigned int keycode = key->keycode;
+ unsigned int keystate = key->state;
+#else
+bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
+ void *message, long *result)
+{
+ Q_UNUSED(result);
+
+ xcb_key_press_event_t *kev = 0;
+ if (eventType == "xcb_generic_event_t") {
+ xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
+ if ((ev->response_type & 127) == XCB_KEY_PRESS)
+ kev = static_cast<xcb_key_press_event_t *>(message);
+ }
+
+ if (kev != 0) {
+ unsigned int keycode = kev->detail;
+ unsigned int keystate = 0;
+ if(kev->state & XCB_MOD_MASK_1)
+ keystate |= Mod1Mask;
+ if(kev->state & XCB_MOD_MASK_CONTROL)
+ keystate |= ControlMask;
+ if(kev->state & XCB_MOD_MASK_4)
+ keystate |= Mod4Mask;
+ if(kev->state & XCB_MOD_MASK_SHIFT)
+ keystate |= ShiftMask;
+#endif
+ activateShortcut(keycode,
+ // Mod1Mask == Alt, Mod4Mask == Meta
+ keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= ShiftMask;
+ if (modifiers & Qt::ControlModifier)
+ native |= ControlMask;
+ if (modifiers & Qt::AltModifier)
+ native |= Mod1Mask;
+ if (modifiers & Qt::MetaModifier)
+ native |= Mod4Mask;
+
+ // TODO: resolve these?
+ //if (modifiers & Qt::MetaModifier)
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ QxtX11Data x11;
+ if (!x11.isValid())
+ return 0;
+
+ KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
+ if (keysym == NoSymbol)
+ keysym = static_cast<ushort>(key);
+
+ return XKeysymToKeycode(x11.display(), keysym);
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ QxtX11Data x11;
+ return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow());
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ QxtX11Data x11;
+ return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow());
+}
diff --git a/qxt-mini/qxtglobalshortcut.cpp b/qxt-mini/qxtglobalshortcut.cpp
index 8515a6b2..45576d37 100644
--- a/qxt-mini/qxtglobalshortcut.cpp
+++ b/qxt-mini/qxtglobalshortcut.cpp
@@ -1,224 +1,224 @@
-#include "qxtglobalshortcut.h"
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#include "qxtglobalshortcut_p.h"
-#include <QAbstractEventDispatcher>
-#include <QtDebug>
-
-#ifndef Q_OS_MAC
-int QxtGlobalShortcutPrivate::ref = 0;
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
-QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
-# endif
-#endif // Q_OS_MAC
-QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
-
-QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
-{
-#ifndef Q_OS_MAC
- if (ref == 0) {
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
-# else
- QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
-#endif
- }
- ++ref;
-#endif // Q_OS_MAC
-}
-
-QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
-{
-#ifndef Q_OS_MAC
- --ref;
- if (ref == 0) {
- QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
- if (ed != 0) {
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- ed->setEventFilter(prevEventFilter);
-# else
- ed->removeNativeEventFilter(this);
-# endif
- }
- }
-#endif // Q_OS_MAC
-}
-
-bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
-{
- if (shortcut.toString() == "") return false;
- Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
- key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
- mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- const bool res = registerShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
- else
- qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
- return res;
-}
-
-bool QxtGlobalShortcutPrivate::unsetShortcut()
-{
- bool res = false;
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p())
- res = unregisterShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.remove(qMakePair(nativeKey, nativeMods));
- else
- qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
- key = Qt::Key(0);
- mods = Qt::KeyboardModifiers(0);
- return res;
-}
-
-void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
- if (shortcut && shortcut->isEnabled())
- emit shortcut->activated();
-}
-
-/*!
- \class QxtGlobalShortcut
- \inmodule QxtWidgets
- \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
-
- A global shortcut triggers even if the application is not active. This
- makes it easy to implement applications that react to certain shortcuts
- still if some other application is active or if the application is for
- example minimized to the system tray.
-
- Example usage:
- \code
- QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
- connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
- shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
- \endcode
-
- \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
- */
-
-/*!
- \fn QxtGlobalShortcut::activated()
-
- This signal is emitted when the user types the shortcut's key sequence.
-
- \sa shortcut
- */
-
-/*!
- Constructs a new QxtGlobalShortcut with \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
-}
-
-/*!
- Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
- setShortcut(shortcut);
-}
-
-/*!
- Destructs the QxtGlobalShortcut.
- */
-QxtGlobalShortcut::~QxtGlobalShortcut()
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
-}
-
-/*!
- \property QxtGlobalShortcut::shortcut
- \brief the shortcut key sequence
-
- \bold {Note:} Notice that corresponding key press and release events are not
- delivered for registered global shortcuts even if they are disabled.
- Also, comma separated key sequences are not supported.
- Only the first part is used:
-
- \code
- qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
- Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
- \endcode
- */
-QKeySequence QxtGlobalShortcut::shortcut() const
-{
- return QKeySequence(qxt_d().key | qxt_d().mods);
-}
-
-bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
- return qxt_d().setShortcut(shortcut);
-}
-
-/*!
- \property QxtGlobalShortcut::enabled
- \brief whether the shortcut is enabled
-
- A disabled shortcut does not get activated.
-
- The default value is \c true.
-
- \sa setDisabled()
- */
-bool QxtGlobalShortcut::isEnabled() const
-{
- return qxt_d().enabled;
-}
-
-void QxtGlobalShortcut::setEnabled(bool enabled)
-{
- qxt_d().enabled = enabled;
-}
-
-/*!
- Sets the shortcut \a disabled.
-
- \sa enabled
- */
-void QxtGlobalShortcut::setDisabled(bool disabled)
-{
- qxt_d().enabled = !disabled;
-}
+#include "qxtglobalshortcut.h"
+/****************************************************************************
+** Copyright (c) 2006 - 2011, the LibQxt project.
+** See the Qxt AUTHORS file for a list of authors and copyright holders.
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the LibQxt project nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+** <http://libqxt.org> <foundation@libqxt.org>
+*****************************************************************************/
+
+#include "qxtglobalshortcut_p.h"
+#include <QAbstractEventDispatcher>
+#include <QtDebug>
+
+#ifndef Q_OS_MAC
+int QxtGlobalShortcutPrivate::ref = 0;
+# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
+# endif
+#endif // Q_OS_MAC
+QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
+
+QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
+{
+#ifndef Q_OS_MAC
+ if (ref == 0) {
+# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+ prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
+# else
+ QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
+#endif
+ }
+ ++ref;
+#endif // Q_OS_MAC
+}
+
+QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
+{
+#ifndef Q_OS_MAC
+ --ref;
+ if (ref == 0) {
+ QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
+ if (ed != 0) {
+# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+ ed->setEventFilter(prevEventFilter);
+# else
+ ed->removeNativeEventFilter(this);
+# endif
+ }
+ }
+#endif // Q_OS_MAC
+}
+
+bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
+{
+ if (shortcut.toString() == "") return false;
+ Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
+ key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
+ mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = registerShortcut(nativeKey, nativeMods);
+ if (res)
+ shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
+ else
+ qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
+ return res;
+}
+
+bool QxtGlobalShortcutPrivate::unsetShortcut()
+{
+ bool res = false;
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p())
+ res = unregisterShortcut(nativeKey, nativeMods);
+ if (res)
+ shortcuts.remove(qMakePair(nativeKey, nativeMods));
+ else
+ qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
+ key = Qt::Key(0);
+ mods = Qt::KeyboardModifiers(0);
+ return res;
+}
+
+void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
+ if (shortcut && shortcut->isEnabled())
+ emit shortcut->activated();
+}
+
+/*!
+ \class QxtGlobalShortcut
+ \inmodule QxtWidgets
+ \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
+
+ A global shortcut triggers even if the application is not active. This
+ makes it easy to implement applications that react to certain shortcuts
+ still if some other application is active or if the application is for
+ example minimized to the system tray.
+
+ Example usage:
+ \code
+ QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
+ connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
+ shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
+ \endcode
+
+ \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
+ */
+
+/*!
+ \fn QxtGlobalShortcut::activated()
+
+ This signal is emitted when the user types the shortcut's key sequence.
+
+ \sa shortcut
+ */
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+}
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+ setShortcut(shortcut);
+}
+
+/*!
+ Destructs the QxtGlobalShortcut.
+ */
+QxtGlobalShortcut::~QxtGlobalShortcut()
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+}
+
+/*!
+ \property QxtGlobalShortcut::shortcut
+ \brief the shortcut key sequence
+
+ \bold {Note:} Notice that corresponding key press and release events are not
+ delivered for registered global shortcuts even if they are disabled.
+ Also, comma separated key sequences are not supported.
+ Only the first part is used:
+
+ \code
+ qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
+ Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
+ \endcode
+ */
+QKeySequence QxtGlobalShortcut::shortcut() const
+{
+ return QKeySequence(qxt_d().key | qxt_d().mods);
+}
+
+bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+ return qxt_d().setShortcut(shortcut);
+}
+
+/*!
+ \property QxtGlobalShortcut::enabled
+ \brief whether the shortcut is enabled
+
+ A disabled shortcut does not get activated.
+
+ The default value is \c true.
+
+ \sa setDisabled()
+ */
+bool QxtGlobalShortcut::isEnabled() const
+{
+ return qxt_d().enabled;
+}
+
+void QxtGlobalShortcut::setEnabled(bool enabled)
+{
+ qxt_d().enabled = enabled;
+}
+
+/*!
+ Sets the shortcut \a disabled.
+
+ \sa enabled
+ */
+void QxtGlobalShortcut::setDisabled(bool disabled)
+{
+ qxt_d().enabled = !disabled;
+}
diff --git a/qxt-mini/qxtglobalshortcut.h b/qxt-mini/qxtglobalshortcut.h
index a81942d2..641c07c9 100644
--- a/qxt-mini/qxtglobalshortcut.h
+++ b/qxt-mini/qxtglobalshortcut.h
@@ -1,64 +1,64 @@
-#ifndef QXTGLOBALSHORTCUT_H
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#define QXTGLOBALSHORTCUT_H
-
-#include "qxtglobal.h"
-#include <QObject>
-#include <QKeySequence>
-class QxtGlobalShortcutPrivate;
-
-class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject
-{
- Q_OBJECT
- QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
-
-public:
- explicit QxtGlobalShortcut(QObject* parent = 0);
- explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
- virtual ~QxtGlobalShortcut();
-
- QKeySequence shortcut() const;
- bool setShortcut(const QKeySequence& shortcut);
-
- bool isEnabled() const;
-
-public Q_SLOTS:
- void setEnabled(bool enabled = true);
- void setDisabled(bool disabled = true);
-
-Q_SIGNALS:
- void activated();
-};
-
-#endif // QXTGLOBALSHORTCUT_H
+#ifndef QXTGLOBALSHORTCUT_H
+/****************************************************************************
+** Copyright (c) 2006 - 2011, the LibQxt project.
+** See the Qxt AUTHORS file for a list of authors and copyright holders.
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the LibQxt project nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+** <http://libqxt.org> <foundation@libqxt.org>
+*****************************************************************************/
+
+#define QXTGLOBALSHORTCUT_H
+
+#include "qxtglobal.h"
+#include <QObject>
+#include <QKeySequence>
+class QxtGlobalShortcutPrivate;
+
+class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject
+{
+ Q_OBJECT
+ QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+
+public:
+ explicit QxtGlobalShortcut(QObject* parent = 0);
+ explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
+ virtual ~QxtGlobalShortcut();
+
+ QKeySequence shortcut() const;
+ bool setShortcut(const QKeySequence& shortcut);
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enabled = true);
+ void setDisabled(bool disabled = true);
+
+Q_SIGNALS:
+ void activated();
+};
+
+#endif // QXTGLOBALSHORTCUT_H
diff --git a/x-plane-plugin/plugin.c b/x-plane-plugin/plugin.c
index 62c9d6f0..3958c895 100644
--- a/x-plane-plugin/plugin.c
+++ b/x-plane-plugin/plugin.c
@@ -13,8 +13,6 @@
#include <XPLMCamera.h>
#include <XPLMProcessing.h>
-#include "ftnoir_tracker_base/ftnoir_tracker_types.h"
-
#ifndef PLUGIN_API
#define PLUGIN_API
#endif
@@ -23,6 +21,10 @@
#define WINE_SHM_NAME "facetracknoir-wine-shm"
#define WINE_MTX_NAME "facetracknoir-wine-mtx"
+enum Axis {
+ TX = 0, TY, TZ, Yaw, Pitch, Roll
+};
+
typedef struct PortableLockedShm {
void* mem;
int fd, size;