summaryrefslogtreecommitdiffhomepage
path: root/facetracknoir
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 /facetracknoir
parentd880464fbe9180aefde94594330126e115066dc3 (diff)
parent051a2e4392bc75b246cc5cb897ae0bbb1f92042e (diff)
Merge branch 'unstable' of https://github.com/opentrack/opentrack into dev/kalman
Conflicts: ftnoir_filter_kalman/ftnoir_filter_kalman.h
Diffstat (limited to 'facetracknoir')
-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
60 files changed, 6566 insertions, 4273 deletions
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