diff options
251 files changed, 14394 insertions, 15286 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..5f7a58f5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +*.cpp text=auto eol=lf +*.hpp text=auto eol=lf +*.c text=auto eol=lf +*.h text=auto eol=lf +*.cxx text=auto eol=lf +*.txt text=auto eol=lf +*.ui text=auto eol=lf +*.qrc text=auto eol=lf @@ -1,12 +1,6 @@ /CMakeLists.txt.user *~ /build* -/install -/bin/tracker-ht/headtracker-ftnoir.exe -/bin/tracker-ht/libgcc_s_dw2-1.dll -/bin/tracker-ht/libstdc++-6.dll -/bin/tracker-ht/bounding-box.raw -/bin/tracker-ht/flandmark_model.dat -/bin/tracker-ht/head.raw /installer/Output -/nbproject/ +# merely git cola saves there +/patches/ diff --git a/3rdparty-notices/FACETRACKNOIR-COPYING.txt b/3rdparty-notices/FACETRACKNOIR-COPYING.txt index befeafb5..1b2b7a07 100644 --- a/3rdparty-notices/FACETRACKNOIR-COPYING.txt +++ b/3rdparty-notices/FACETRACKNOIR-COPYING.txt @@ -1,3 +1,7 @@ +The opentrack project is a fork of "FaceTrackNoIR" software. + +Original project's site located at <http://facetracknoir.sourceforge.net/home/default.htm> + ******************************************************************************** * FaceTrackNoIR This program is a private project of the some enthusiastic * * gamers from Holland, who don't like to pay much for * diff --git a/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt b/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt deleted file mode 100644 index 80f54ae2..00000000 --- a/3rdparty-notices/GOOGLE-BREAKPAD-COPYING.txt +++ /dev/null @@ -1,29 +0,0 @@ -Copyright (c) 2006, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b2e9f99..2de8856d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,10 @@ project(opentrack) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.11) +cmake_policy(SET CMP0020 NEW) + +if(MSVC) + message(FATAL_ERROR "Support for MSVC removed due to incomplete C++11 support") +endif() include(CMakeParseArguments) @@ -32,7 +37,6 @@ if(APPLE) set(CMAKE_STATIC_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_STATIC_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_EXE_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS " ${apple-frameworks} ${CMAKE_MODULE_LINKER_FLAGS}") - set(CMAKE_CXX_FLAGS " -stdlib=libc++ -std=c++11 ${CMAKE_CXX_FLAGS} -fvisibility=hidden") endif() SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) @@ -44,48 +48,12 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -add_definitions(-DOPENTRACK_API -DIN_OPENTRACK) - -if(MSVC) - add_definitions(-DNOMINMAX) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) - add_definitions(-std=c++11) -endif() - -if(WIN32 AND MSVC) - set(SDK_GOOGLE_BREAKPAD "" CACHE PATH "google-breakpad for crash reporting") -endif() - -if(MINGW) - set(SDK_MINGW_PREFIX "" CACHE PATH "mingw prefix") -endif() - -if(SDK_GOOGLE_BREAKPAD AND WIN32) - add_definitions(-DOPENTRACK_BREAKPAD) - include_directories("${SDK_GOOGLE_BREAKPAD}/src/client/windows/handler") - include_directories("${SDK_GOOGLE_BREAKPAD}/src/") -endif() - -if(WIN32 AND DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700) - find_path (WIN8_SDK_ROOT_DIR - Include/um/windows.h - PATHS - "$ENV{ProgramFiles}/Windows Kits/8.0" - "$ENV{ProgramFiles(x86)}/Windows Kits/8.0" - DOC "Windows 8 SDK root directory" - ) +# note, hatire supports both ftnoir and opentrack +# don't remove without being sure as hell -sh 20140922 +add_definitions(-DOPENTRACK_API) - if(WIN8_SDK_ROOT_DIR) - SET(CMAKE_LIBRARY_PATH "${WIN8_SDK_ROOT_DIR}/Lib/win8/um/x86") - endif() -endif() - -if(WIN32 AND DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700) - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") - SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") - SET (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") +if(CMAKE_COMPILER_IS_GNUCXX OR APPLE) + set(CMAKE_CXX_FLAGS " -std=c++11 ${CMAKE_CXX_FLAGS} ") endif() if(UNIX) @@ -105,18 +73,9 @@ SET(SDK_RIFT "" CACHE PATH "libOVR path") include_directories(${CMAKE_SOURCE_DIR}) -if(MINGW) - # qt scripts are broken - set(Qt5Gui_user32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libuser32.a) - set(Qt5Gui_opengl32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libopengl32.a) - set(Qt5Gui_glu32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libglu32.a) - set(Qt5Gui_gdi32_LIBRARY ${SDK_MINGW_PREFIX}/mingw/lib/libgdi32.a) -endif() - find_package(OpenCV REQUIRED) find_package(Qt5 REQUIRED COMPONENTS Core Xml Network Widgets Gui ${maybe-serial-port} QUIET) -cmake_policy(SET CMP0020 NEW) include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}) add_definitions(${Qt5Core_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5Gui_DEFINITIONS} ${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS}) @@ -127,15 +86,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ftnoir_posewidget) set(SDK_ARUCO_LIBPATH "" CACHE FILEPATH "Path to Aruco static library") -SET(SDK_OPENCV_STATIC FALSE CACHE BOOL "Whether OpenCV is statically linked") if(WIN32) set(SDK_SIMCONNECT "" CACHE PATH "Path to SimConnect SDK") - set(SDK_DIRECTX "" CACHE PATH "Path to DirectX SDK") set(SDK_FSUIPC "" CACHE PATH "Path to FSUIPC") - if(SDK_DIRECTX) - include_directories("${SDK_DIRECTX}/Include") - link_directories("${SDK_DIRECTX}/Lib") - endif() endif() if(NOT WIN32) @@ -178,17 +131,9 @@ endif() set(EXTRA-MOCS "${CMAKE_SOURCE_DIR}/facetracknoir/options.h") function(link_with_dinput8 n) - if(WIN32) - if(MSVC) - target_link_libraries(${n} - "${CMAKE_SOURCE_DIR}/dinput/dinput8.lib" - "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib" - "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib" - uuid) - else() - target_link_libraries(${n} dinput8 dxguid strmiids) - endif() - endif() + if(WIN32) + target_link_libraries(${n} dinput8 dxguid strmiids) + endif() endfunction() macro(opentrack_module n dir) @@ -209,7 +154,7 @@ macro(opentrack_library n) if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) SET_TARGET_PROPERTIES(${n} PROPERTIES LINK_FLAGS "${foolib_LINK} -Wl,--version-script=${CMAKE_SOURCE_DIR}/facetracknoir/${version-script}-version-script.txt" - COMPILE_FLAGS "${foolib_COMPILE}" + COMPILE_FLAGS "${foolib_COMPILE} -fvisibility=hidden -fvisibility-inlines-hidden" ) else() set_target_properties(${n} PROPERTIES LINK_FLAGS "${foolib_LINK}" COMPILE_FLAGS "${foolib_COMPILE}") @@ -217,8 +162,6 @@ macro(opentrack_library n) install(TARGETS ${n} RUNTIME DESTINATION . LIBRARY DESTINATION .) endmacro() -file(GLOB opentrack-lib-c "opentrack-api/*.cpp" "facetracknoir/global-settings.cpp" "opentrack-api/*.h" "facetracknoir/global-settings.h") - opentrack_module(opentrack-bin facetracknoir) opentrack_module(opentrack-pose-widget ftnoir_posewidget) opentrack_module(opentrack-spline-widget qfunctionconfigurator) @@ -245,11 +188,14 @@ opentrack_module(opentrack-proto-libevdev ftnoir_protocol_libevdev) opentrack_module(opentrack-tracker-ht ftnoir_tracker_ht) opentrack_module(opentrack-tracker-aruco ftnoir_tracker_aruco) -opentrack_module(opentrack-tracker-pt FTNoIR_Tracker_PT) +opentrack_module(opentrack-tracker-pt ftnoir_tracker_pt) opentrack_module(opentrack-tracker-udp ftnoir_tracker_udp) opentrack_module(opentrack-tracker-joystick ftnoir_tracker_joystick) opentrack_module(opentrack-tracker-rift ftnoir_tracker_rift) opentrack_module(opentrack-tracker-hydra ftnoir_tracker_hydra) +opentrack_module(opentrack-tracker-freepie-udp ftnoir_tracker_freepie-udp) + +file(GLOB opentrack-version-c "facetracknoir/version.c") file(GLOB opentrack-csv-c "ftnoir_csv/*.cpp" "ftnoir_csv/*.h") @@ -262,7 +208,7 @@ file(GLOB opentrack-xplane-plugin-c "x-plane-plugin/*.c") # freetrack -file(GLOB opentrack-freetrack-c "freetrackclient/*.cpp") +file(GLOB opentrack-freetrack-c "freetrackclient/*.c") if(SDK_XPLANE) # probably librt already included @@ -312,6 +258,11 @@ target_link_libraries(opentrack-pose-widget ${MY_QT_LIBS}) add_library(opentrack-spline-widget SHARED ${opentrack-spline-widget-c}) target_link_libraries(opentrack-spline-widget ${MY_QT_LIBS}) +add_library(opentrack-version STATIC ${opentrack-version-c}) +set_target_properties(opentrack-version PROPERTIES + COMPILE_DEFINITIONS + "IN_VERSION_UNIT;OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\"") + opentrack_library(opentrack-filter-accela) opentrack_library(opentrack-filter-kalman) opentrack_library(opentrack-filter-ewma) @@ -322,12 +273,12 @@ opentrack_library(opentrack-proto-fgfs) if(SDK_VJOY) include_directories(${SDK_VJOY}) - opentrack_library(opentrack-proto-vjoy) - if(MSVC) - target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.lib") - else() - target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.dll") + set(link-flags) + if(CMAKE_C_COMPILER_IS_GNUCC) + set(link-flags "-Wl,--enable-stdcall-fixup") endif() + opentrack_library(opentrack-proto-vjoy LINK ${link-flags}) + target_link_libraries(opentrack-proto-vjoy ${MY_QT_LIBS} "${SDK_VJOY}/VJoy.dll") endif() if(SDK_ENABLE_LIBEVDEV) @@ -338,10 +289,7 @@ if(SDK_ENABLE_LIBEVDEV) endif() if(SDK_FSUIPC) - if(MSVC) - set(link-flags "/NODEFAULTLIB:libc") - endif() - opentrack_library(opentrack-proto-fsuipc LINK "${link-flags}") + opentrack_library(opentrack-proto-fsuipc) target_link_libraries(opentrack-proto-fsuipc "${SDK_FSUIPC}/FSUIPC_User.lib") endif() @@ -359,9 +307,7 @@ endif() if(WIN32) add_library(freetrackclient SHARED ${opentrack-freetrack-c}) - if(CMAKE_COMPILER_IS_GNUCC) - set_target_properties(freetrackclient PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup -fno-lto -Wl,-kill-at" PREFIX "" COMPILE_FLAGS "-fno-lto") - endif() + set_target_properties(freetrackclient PROPERTIES PREFIX "") endif() opentrack_library(opentrack-proto-udp) @@ -374,23 +320,23 @@ if(SDK_WINE_PREFIX) opentrack_library(opentrack-proto-wine) target_link_libraries(opentrack-proto-wine opentrack-compat opentrack-csv) if(NOT SDK_WINE_NO_WRAPPER) - set(my-rt -lrt) - if(APPLE) - set(my-rt) - endif() + set(my-rt -lrt) + if(APPLE) + set(my-rt) + endif() + file(GLOB wine-deps "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/*.cxx") add_custom_command( OUTPUT opentrack-wrapper-wine.exe.so - DEPENDS "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx" - "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx" - "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx" - COMMAND "${SDK_WINE_PREFIX}/bin/wineg++" -g -O2 -m32 -o + DEPENDS ${wine-deps} + COMMAND "${SDK_WINE_PREFIX}/bin/wineg++" -g -O2 -m32 -std=c++11 -o opentrack-wrapper-wine.exe -I "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx" "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx" "${CMAKE_SOURCE_DIR}/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx" ${my-rt}) add_custom_target(wine-wrapper ALL DEPENDS opentrack-wrapper-wine.exe.so) - add_dependencies(wine-wrapper opentrack-compat opentrack-proto-wine) + add_dependencies(opentrack-proto-wine wine-wrapper) + add_dependencies(wine-wrapper opentrack-compat) endif() endif() @@ -398,15 +344,8 @@ opentrack_library(opentrack-tracker-ht) target_link_libraries(opentrack-tracker-ht opentrack-compat) if(SDK_ARUCO_LIBPATH) - include_directories(${CMAKE_SOURCE_DIR}/ftnoir_tracker_aruco/include) opentrack_library(opentrack-tracker-aruco) target_link_libraries(opentrack-tracker-aruco ${SDK_ARUCO_LIBPATH} ${OpenCV_LIBS}) - if(WIN32 AND MSVC) - target_link_libraries(opentrack-tracker-aruco - "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib" - "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib" - uuid) - endif() endif() link_with_dinput8(opentrack-tracker-ht) @@ -418,6 +357,7 @@ target_link_libraries(opentrack-tracker-pt ${OpenCV_LIBS}) link_with_dinput8(opentrack-tracker-pt) opentrack_library(opentrack-tracker-udp) +opentrack_library(opentrack-tracker-freepie-udp) if(SDK_RIFT) include_directories("${SDK_RIFT}/Include") @@ -428,24 +368,16 @@ if(SDK_RIFT) set(link-flags "-framework CoreFoundation -framework CoreGraphics -framework IOKit -framework Quartz") set(c-flags "-fno-strict-aliasing") else() - if(MSVC) - set(link-flags "/NODEFAULTLIB:LIBCMT") - else() - set(c-flags "-fno-strict-aliasing") - endif() + set(c-flags "-fno-strict-aliasing") endif() opentrack_library(opentrack-tracker-rift LINK "${link-flags}" COMPILE "${c-flags}") - if(MSVC) - target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/Lib/Win32/libovr.lib" winmm.lib setupapi.lib) + if(WIN32) + target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" winmm setupapi ws2_32 imagehlp wbemuuid) else() - if(WIN32) - target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" winmm setupapi) - else() - if(NOT APPLE) + if(NOT APPLE) target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a" udev Xinerama) - else() + else() target_link_libraries(opentrack-tracker-rift "${SDK_RIFT}/libLibOVR.a") - endif() endif() endif() endif() @@ -493,30 +425,16 @@ if(UNIX OR APPLE) SET_TARGET_PROPERTIES(opentrack-qxt-mini PROPERTIES COMPILE_FLAGS "-DBUILD_QXT_CORE=42 -DBUILD_QXT_WIDGETS=42 -DBUILD_QXT_GUI=42") target_link_libraries(opentrack-qxt-mini ${MY_QT_LIBS}) if(NOT APPLE) - target_link_libraries(opentrack-qxt-mini X11) + target_link_libraries(opentrack-qxt-mini X11) endif() endif() + add_executable(opentrack ${opentrack-win32-executable} ${opentrack-bin-c} ${opentrack-bin-uih} ${opentrack-bin-rcc}) -set_target_properties(opentrack PROPERTIES COMPILE_DEFINITIONS OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\") -set(OPENTRACK_COMMIT_VERSION \"${OPENTRACK__COMMIT}\") -configure_file("${CMAKE_SOURCE_DIR}/opentrack-version.h" "${CMAKE_BINARY_DIR}/opentrack-version.h" @ONLY NEWLINE_STYLE UNIX) if(APPLE) SET_TARGET_PROPERTIES(opentrack-qxt-mini PROPERTIES LINK_FLAGS "-framework Carbon -framework CoreFoundation") endif() -add_library(opentrack-api SHARED ${opentrack-lib-c}) -target_link_libraries(opentrack-api ${MY_QT_LIBS}) -if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) - SET_TARGET_PROPERTIES(opentrack-api PROPERTIES - LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/opentrack-api/gnuc-version-script.txt" - COMPILE_FLAGS "-fvisibility=protected -fvisibility-inlines-hidden" - COMPILE_DEFINITIONS IN_OPENTRACK_API - ) -endif() - -set_target_properties(opentrack PROPERTIES COMPILE_DEFINITIONS OPENTRACK_VERSION=\"${OPENTRACK__COMMIT}\") - if(UNIX OR APPLE) target_link_libraries(opentrack opentrack-qxt-mini) endif() @@ -533,23 +451,12 @@ if(CMAKE_SYSTEM STREQUAL LINUX) link_libraries(rt) endif() -if(MSVC) - SET_TARGET_PROPERTIES(opentrack PROPERTIES LINK_FLAGS "/ENTRY:mainCRTStartup") -endif() -target_link_libraries(opentrack opentrack-pose-widget opentrack-spline-widget ${MY_QT_LIBS} ${QXT_QXTCORE_LIB_RELEASE} ${QXT_QXTWIDGETS_LIB_RELEASE}) +target_link_libraries(opentrack opentrack-version opentrack-pose-widget opentrack-spline-widget ${MY_QT_LIBS} ${QXT_QXTCORE_LIB_RELEASE} ${QXT_QXTWIDGETS_LIB_RELEASE}) if(NOT WIN32) target_link_libraries(opentrack dl) - target_link_libraries(opentrack-api dl) -endif() -if(SDK_GOOGLE_BREAKPAD) - if(MSVC) - target_link_libraries(opentrack - "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/crash_generation_client.lib" - "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/exception_handler.lib" - "${SDK_GOOGLE_BREAKPAD}/src/client/windows/Release/lib/common.lib") - endif() +else() + target_link_libraries(opentrack winmm) endif() -set_target_properties(opentrack PROPERTIES COMPILE_FLAGS -DOPENTRACK_MAIN) # make install @@ -569,13 +476,12 @@ install(DIRECTORY "${CMAKE_SOURCE_DIR}/3rdparty-notices" DESTINATION .) install(FILES "${CMAKE_SOURCE_DIR}/bin/NPClient.dll" "${CMAKE_SOURCE_DIR}/bin/NPClient64.dll" "${CMAKE_SOURCE_DIR}/bin/TrackIR.exe" DESTINATION .) install(DIRECTORY "${CMAKE_SOURCE_DIR}/bin/settings" "${CMAKE_SOURCE_DIR}/facetracknoir/clientfiles" DESTINATION .) -if(NOT WIN32 AND SDK_WINE_PREFIX) +if(NOT WIN32 AND SDK_WINE_PREFIX AND NOT SDK_WINE_NO_WRAPPER) install(FILES "${CMAKE_BINARY_DIR}/opentrack-wrapper-wine.exe.so" DESTINATION .) endif() install(TARGETS - opentrack-api opentrack-compat opentrack-csv opentrack-pose-widget @@ -592,8 +498,17 @@ if(WIN32) install(FILES "${CMAKE_SOURCE_DIR}/bin/cleye.config" DESTINATION .) endif() -if(MSVC) - file(GLOB pdbs1 "${CMAKE_BINARY_DIR}/Release/*.pdb") - file(GLOB pdbs2 "${CMAKE_BINARY_DIR}/*.pdb") - install(FILES ${pdbs1} ${pdbs2} DESTINATION .) +string(TIMESTAMP filename-date "%Y%m%d") +set(filename-ostype ${CMAKE_SYSTEM_NAME}) +get_git_head_revision(filename-branch_0 filename-hash_0) +if(filename-hash_0) + string(SUBSTRING "${filename-hash_0}" 0 7 filename-hash) endif() +string(REPLACE "refs/heads/" "" filename-branch_1 "${filename-branch_0}") +string(REPLACE "/" "-" filename-branch "${filename-branch_1}") +set(filename_0 opentrack-${filename-ostype}-${filename-branch}-${filename-date}-${filename-hash}) +string(TOLOWER "${filename_0}" filename_1) +set(filename "${CMAKE_BINARY_DIR}/${filename_1}.tar.xz") + +add_custom_command(OUTPUT ${filename} COMMAND env sh "${CMAKE_SOURCE_DIR}/make-tar.sh" "${CMAKE_INSTALL_PREFIX}" "${filename}") +add_custom_target(tarball DEPENDS ${filename}) diff --git a/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui b/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui deleted file mode 100644 index 0bbec7e1..00000000 --- a/FTNoIR_Tracker_PT/FTNoIR_PT_Controls.ui +++ /dev/null @@ -1,1790 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICPTClientControls</class>
- <widget class="QWidget" name="UICPTClientControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>459</width>
- <height>621</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>PointTracker Settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="ftnoir_tracker_pt.qrc">
- <normaloff>:/Resources/Logo_IR.png</normaloff>:/Resources/Logo_IR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetFixedSize</enum>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>General</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QGroupBox" name="groupBox_6">
- <property name="title">
- <string>Tracker Thread</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_43">
- <property name="text">
- <string>Auto-reset time</string>
- </property>
- <property name="buddy">
- <cstring>reset_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="reset_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Time until automatic reset of tracker's internal state when no valid tracking result is found</string>
- </property>
- <property name="suffix">
- <string>ms</string>
- </property>
- <property name="maximum">
- <number>9999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_17">
- <property name="text">
- <string>Dynamic Pose Resolution</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="dynpose_check">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QPushButton" name="reset_button">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip">
- <string>Reset the tracker's internal state</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
- </property>
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Roll:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableRoll</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Pitch:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnablePitch</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Yaw:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableYaw</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>X:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableX</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QCheckBox" name="chkEnableX">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Y:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableY</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QCheckBox" name="chkEnableY">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Z:</string>
- </property>
- <property name="buddy">
- <cstring>chkEnableZ</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QCheckBox" name="chkEnableZ">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="2">
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="2">
- <spacer name="horizontalSpacer_8">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string>Camera</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="toolTip">
- <string>The camera device used as input</string>
- </property>
- <property name="title">
- <string>Camera Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="label_2">
- <property name="minimumSize">
- <size>
- <width>55</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Device</string>
- </property>
- <property name="buddy">
- <cstring>camdevice_combo</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="camdevice_combo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Camera device used as input</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_8">
- <item>
- <layout class="QGridLayout" name="gridLayout_8">
- <item row="0" column="0">
- <widget class="QLabel" name="label_36">
- <property name="minimumSize">
- <size>
- <width>55</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Resolution</string>
- </property>
- </widget>
- </item>
- <item row="0" column="5">
- <widget class="QLabel" name="label_37">
- <property name="text">
- <string>FPS</string>
- </property>
- <property name="buddy">
- <cstring>fps_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="6">
- <widget class="QSpinBox" name="fps_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Desired capture framerate</string>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_41">
- <property name="text">
- <string>x</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="res_x_spin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Desired capture width</string>
- </property>
- <property name="maximum">
- <number>2000</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QSpinBox" name="res_y_spin">
- <property name="toolTip">
- <string>Desired capture height</string>
- </property>
- <property name="maximum">
- <number>2000</number>
- </property>
- <property name="singleStep">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_34">
- <property name="text">
- <string>F/W</string>
- </property>
- <property name="buddy">
- <cstring>f_dspin</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDoubleSpinBox" name="f_dspin">
- <property name="toolTip">
- <string>The camera's focal length devided by its sensor width</string>
- </property>
- <property name="decimals">
- <number>2</number>
- </property>
- <property name="singleStep">
- <double>0.100000000000000</double>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="7">
- <spacer name="horizontalSpacer_9">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7"/>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string>Camera Orientation</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Pitch</string>
- </property>
- <property name="buddy">
- <cstring>campitch_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="campitch_spin">
- <property name="contextMenuPolicy">
- <enum>Qt::DefaultContextMenu</enum>
- </property>
- <property name="toolTip">
- <string>The angle the camera is facing upwards</string>
- </property>
- <property name="minimum">
- <number>-99</number>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_20">
- <property name="text">
- <string>Yaw</string>
- </property>
- <property name="buddy">
- <cstring>camyaw_spin</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="camyaw_spin">
- <property name="contextMenuPolicy">
- <enum>Qt::DefaultContextMenu</enum>
- </property>
- <property name="toolTip">
- <string>The angle the camera is facing leftwards</string>
- </property>
- <property name="minimum">
- <number>-99</number>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="label_21">
- <property name="text">
- <string>deg (positve = leftwards)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="camroll_combo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Rotation of the camera image</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>deg (positive = upwards)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="label_19">
- <property name="text">
- <string>deg</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_18">
- <property name="text">
- <string>Roll</string>
- </property>
- <property name="buddy">
- <cstring>camroll_combo</cstring>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_10">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>Point Extraction</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Threshold</string>
- </property>
- <property name="buddy">
- <cstring>threshold_slider</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSlider" name="threshold_slider">
- <property name="toolTip">
- <string>Intensity threshold for point extraction</string>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="value">
- <number>127</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_secondary">
- <item>
- <widget class="QLabel" name="label_secondary">
- <property name="text">
- <string>Hysteresis</string>
- </property>
- <property name="buddy">
- <cstring>threshold_secondary_slider</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSlider" name="threshold_secondary_slider">
- <property name="toolTip">
- <string>Per pixel hysteresis width (leave left if there is little difference between dot and non-dot, move right for increased stability against pixel noise)</string>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>100</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Min Diameter</string>
- </property>
- <property name="buddy">
- <cstring>mindiam_spin</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="mindiam_spin">
- <property name="toolTip">
- <string>Minimum point diameter</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_12">
- <property name="text">
- <string>px</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Max Diameter</string>
- </property>
- <property name="buddy">
- <cstring>maxdiam_spin</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="maxdiam_spin">
- <property name="toolTip">
- <string>Maximum point diameter</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>px</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_4">
- <attribute name="title">
- <string>Model</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_16">
- <item>
- <widget class="QTabWidget" name="model_tabs">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>2</number>
- </property>
- <property name="usesScrollButtons">
- <bool>false</bool>
- </property>
- <property name="documentMode">
- <bool>false</bool>
- </property>
- <property name="tabsClosable">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="tab_5">
- <attribute name="title">
- <string>Clip</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_13">
- <item>
- <widget class="QGroupBox" name="groupBox_8">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_16">
- <item>
- <widget class="QWidget" name="widget_4" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>150</width>
- <height>160</height>
- </size>
- </property>
- <widget class="QLabel" name="label_44">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>30</y>
- <width>71</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_side.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_theight_spin">
- <property name="geometry">
- <rect>
- <x>100</x>
- <y>50</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_tlength_spin">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>10</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_bheight_spin">
- <property name="geometry">
- <rect>
- <x>100</x>
- <y>90</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_50">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Side</string>
- </property>
- </widget>
- <widget class="QSpinBox" name="clip_blength_spin">
- <property name="geometry">
- <rect>
- <x>40</x>
- <y>140</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_52">
- <property name="geometry">
- <rect>
- <x>70</x>
- <y>70</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="widget_3" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>140</height>
- </size>
- </property>
- <widget class="QLabel" name="label_51">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Front</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_45">
- <property name="geometry">
- <rect>
- <x>40</x>
- <y>30</y>
- <width>21</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_front.png</pixmap>
- </property>
- </widget>
- <widget class="QLabel" name="label_53">
- <property name="geometry">
- <rect>
- <x>60</x>
- <y>70</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_6">
- <attribute name="title">
- <string>Cap</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_14">
- <item>
- <widget class="QGroupBox" name="groupBox_9">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_15">
- <item>
- <widget class="QWidget" name="widget" native="true">
- <property name="minimumSize">
- <size>
- <width>140</width>
- <height>130</height>
- </size>
- </property>
- <widget class="QLabel" name="label_46">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>50</y>
- <width>111</width>
- <height>81</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_side.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_height_spin">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>80</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- <widget class="QLabel" name="label_54">
- <property name="geometry">
- <rect>
- <x>130</x>
- <y>50</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_48">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Side</string>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_length_spin">
- <property name="geometry">
- <rect>
- <x>50</x>
- <y>40</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="widget_2" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>130</height>
- </size>
- </property>
- <widget class="QLabel" name="label_49">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>10</y>
- <width>46</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>Front</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_55">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>50</y>
- <width>16</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>R</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_47">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>50</y>
- <width>81</width>
- <height>81</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_front.png</pixmap>
- </property>
- </widget>
- <widget class="QSpinBox" name="cap_width_spin">
- <property name="geometry">
- <rect>
- <x>50</x>
- <y>30</y>
- <width>46</width>
- <height>22</height>
- </rect>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_7">
- <attribute name="title">
- <string>Custom</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_15">
- <item>
- <widget class="QGroupBox" name="groupBox_7">
- <property name="title">
- <string>Model Dimensions (mm)</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_12">
- <item>
- <widget class="QLabel" name="label_56">
- <property name="text">
- <string><html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p></body></html></string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_14">
- <item>
- <spacer name="horizontalSpacer_14">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_4">
- <item row="3" column="2">
- <widget class="QSpinBox" name="m1z_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_58">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QSpinBox" name="m1y_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="label_57">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_60">
- <property name="text">
- <string>M1:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QSpinBox" name="m1x_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_63">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_15">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="1" column="2">
- <widget class="QSpinBox" name="m2x_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_67">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="label_69">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QSpinBox" name="m2y_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_70">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_64">
- <property name="text">
- <string>M2:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QSpinBox" name="m2z_spin">
- <property name="suffix">
- <string/>
- </property>
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_16">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_10">
- <property name="title">
- <string>Model Position (mm)</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_11">
- <item>
- <widget class="QLabel" name="label_59">
- <property name="text">
- <string><html><head/><body><p>Translation from head center to model reference point<br/> in default pose</p></body></html></string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_17">
- <item>
- <spacer name="horizontalSpacer_17">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="3" column="1">
- <widget class="QSpinBox" name="tz_spin">
- <property name="suffix">
- <string/>
- </property>
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_61">
- <property name="text">
- <string>x:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_62">
- <property name="text">
- <string>y:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_66">
- <property name="text">
- <string>z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="ty_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="tx_spin">
- <property name="minimum">
- <number>-999</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer_18">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="tcalib_button">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Calibrate</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_19">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_3">
- <attribute name="title">
- <string>About</string>
- </attribute>
- <widget class="QLabel" name="label_10">
- <property name="geometry">
- <rect>
- <x>30</x>
- <y>30</y>
- <width>161</width>
- <height>111</height>
- </rect>
- </property>
- <property name="text">
- <string><html><head/><body><p><span style=" font-weight:600;">FTNoIR PointTracker Plugin<br/>Version 1.1</span></p><p><span style=" font-weight:600;">by Patrick Ruoff</span></p><p><a href="http://ftnoirpt.sourceforge.net/"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">Manual (external)</span></a></p></body></html></string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QLabel" name="label_35">
- <property name="geometry">
- <rect>
- <x>200</x>
- <y>30</y>
- <width>141</width>
- <height>141</height>
- </rect>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/Logo_IR.png</pixmap>
- </property>
- </widget>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_5">
- <property name="title">
- <string>Status</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_38">
- <property name="text">
- <string>Camera Info:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="caminfo_label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>120</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Extracted Points:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="pointinfo_label">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QPushButton" name="btnApply">
- <property name="text">
- <string>Save</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="ok_button">
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="text">
- <string>Ok</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cancel_button">
- <property name="locale">
- <locale language="English" country="UnitedStates"/>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>reset_spin</tabstop>
- <tabstop>chkEnableRoll</tabstop>
- <tabstop>chkEnablePitch</tabstop>
- <tabstop>chkEnableYaw</tabstop>
- <tabstop>chkEnableX</tabstop>
- <tabstop>chkEnableY</tabstop>
- <tabstop>chkEnableZ</tabstop>
- <tabstop>camdevice_combo</tabstop>
- <tabstop>res_x_spin</tabstop>
- <tabstop>res_y_spin</tabstop>
- <tabstop>fps_spin</tabstop>
- <tabstop>f_dspin</tabstop>
- <tabstop>camroll_combo</tabstop>
- <tabstop>campitch_spin</tabstop>
- <tabstop>camyaw_spin</tabstop>
- <tabstop>threshold_slider</tabstop>
- <tabstop>mindiam_spin</tabstop>
- <tabstop>maxdiam_spin</tabstop>
- <tabstop>model_tabs</tabstop>
- <tabstop>clip_tlength_spin</tabstop>
- <tabstop>clip_theight_spin</tabstop>
- <tabstop>clip_bheight_spin</tabstop>
- <tabstop>clip_blength_spin</tabstop>
- <tabstop>cap_length_spin</tabstop>
- <tabstop>cap_height_spin</tabstop>
- <tabstop>cap_width_spin</tabstop>
- <tabstop>m1x_spin</tabstop>
- <tabstop>m1y_spin</tabstop>
- <tabstop>m1z_spin</tabstop>
- <tabstop>m2x_spin</tabstop>
- <tabstop>m2y_spin</tabstop>
- <tabstop>m2z_spin</tabstop>
- <tabstop>tx_spin</tabstop>
- <tabstop>ty_spin</tabstop>
- <tabstop>tz_spin</tabstop>
- <tabstop>tcalib_button</tabstop>
- <tabstop>ok_button</tabstop>
- <tabstop>cancel_button</tabstop>
- </tabstops>
- <resources>
- <include location="ftnoir_tracker_pt.qrc"/>
- </resources>
- <connections>
- <connection>
- <sender>dynpose_check</sender>
- <signal>toggled(bool)</signal>
- <receiver>reset_spin</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>172</x>
- <y>110</y>
- </hint>
- <hint type="destinationlabel">
- <x>351</x>
- <y>112</y>
- </hint>
- </hints>
- </connection>
- </connections>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
diff --git a/FTNoIR_Tracker_PT/boost-compat.h b/FTNoIR_Tracker_PT/boost-compat.h deleted file mode 100644 index 612f2c4d..00000000 --- a/FTNoIR_Tracker_PT/boost-compat.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include <memory> -namespace boost { - using std::shared_ptr; -} diff --git a/FTNoIR_Tracker_PT/frame_observer.cpp b/FTNoIR_Tracker_PT/frame_observer.cpp deleted file mode 100644 index 281f3d57..00000000 --- a/FTNoIR_Tracker_PT/frame_observer.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (c) 2013 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "frame_observer.h"
-
-//-----------------------------------------------------------------------------
-FrameProvider::~FrameProvider()
-{
- QMutexLocker lock(&observer_mutex);
- for (std::set<FrameObserver*>::iterator iter=frame_observers.begin(); iter!=frame_observers.end(); ++iter)
- {
- (*iter)->on_frame_provider_destroy();
- }
-}
diff --git a/FTNoIR_Tracker_PT/frame_observer.h b/FTNoIR_Tracker_PT/frame_observer.h deleted file mode 100644 index 585a6ee7..00000000 --- a/FTNoIR_Tracker_PT/frame_observer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2013 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef FRAME_OBSERVER_H
-#define FRAME_OBSERVER_H
-
-#include <QMutex>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <set>
-
-//-----------------------------------------------------------------------------
-// Forward declarations
-class FrameObserver;
-
-//-----------------------------------------------------------------------------
-// Provides means to copy frame and point information if it has observers
-// Instantiate a FrameObserver to get the information
-class FrameProvider
-{
- friend class FrameObserver;
-public:
- ~FrameProvider();
-
-protected:
- virtual bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points) = 0;
-
- bool has_observers() const { QMutexLocker lock(&observer_mutex); return !frame_observers.empty(); }
-
-private:
- mutable QMutex observer_mutex;
- void add_observer(FrameObserver* obs) { QMutexLocker lock(&observer_mutex); frame_observers.insert(obs); }
- void remove_observer(FrameObserver* obs) { QMutexLocker lock(&observer_mutex); frame_observers.erase(obs); }
- std::set<FrameObserver*> frame_observers;
-};
-
-//-----------------------------------------------------------------------------
-// Used to get frame and point information from MutexedFrameProvider
-// Destroy instance if not interested anymore since a living
-// FrameObserver instance causes MutexedFrameProvider to provide the information,
-// potentially reducing its performance
-class FrameObserver
-{
-public:
- FrameObserver(FrameProvider* provider) : provider(provider) {
- provider->add_observer(this);
- }
-
- ~FrameObserver() {
- if (provider) provider->remove_observer(this);
- }
-
- bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points) {
- return provider ? provider->get_frame_and_points(frame, points) : false;
- }
-
- void on_frame_provider_destroy() {
- provider = NULL;
- }
-
-protected:
- FrameProvider* provider;
-
-private:
- FrameObserver(const FrameObserver&);
-};
-
-#endif //FRAME_OBSERVER_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h b/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h deleted file mode 100644 index 190ed76a..00000000 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef FTNOIR_TRACKER_PT_H
-#define FTNOIR_TRACKER_PT_H
-
-#ifdef OPENTRACK_API
-# include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-# include "facetracknoir/global-settings.h"
-#endif
-#include "ftnoir_tracker_pt_settings.h"
-#include "frame_observer.h"
-#include "camera.h"
-#include "point_extractor.h"
-#include "point_tracker.h"
-#include "pt_video_widget.h"
-#include "facetracknoir/timer.hpp"
-
-#include <QThread>
-#include <QMutex>
-#include <QMutexLocker>
-#include <QTime>
-#include <opencv2/opencv.hpp>
-#include <atomic>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <vector>
-
-//-----------------------------------------------------------------------------
-// Constantly processes the tracking chain in a separate thread
-class Tracker : public ITracker, QThread, public FrameProvider
-{
-public:
- Tracker();
- virtual ~Tracker();
- virtual void StartTracker(QFrame* parent_window);
- virtual void GetHeadPoseData(double* data);
- virtual void refreshVideo();
-
- void apply(settings& s);
- void apply_inner();
- void center();
- void reset(); // reset the trackers internal state variables
- void run();
-
- void get_pose(FrameTrafo* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.get_pose(); }
- int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); }
- void get_cam_info(CamInfo* info) { QMutexLocker lock(&mutex); *info = camera.get_info(); }
-
-protected:
- // --- MutexedFrameProvider interface ---
- virtual bool get_frame_and_points(cv::Mat& frame, boost::shared_ptr< std::vector<cv::Vec2f> >& points);
-
- // --- thread ---
- QMutex mutex;
- // thread commands
- enum Command {
- ABORT = 1<<0,
- PAUSE = 1<<1
- };
- void set_command(Command command);
- void reset_command(Command command);
- volatile int commands;
-
- CVCamera camera;
- FrameRotation frame_rotation;
- PointExtractor point_extractor;
- PointTracker point_tracker;
-
- FrameTrafo X_GH_0; // for centering
- cv::Vec3f t_MH; // translation from model frame to head frame
- cv::Matx33f R_GC; // rotation from opengl reference frame to camera frame
-
- // --- ui ---
- cv::Mat frame; // the output frame for display
-
- PTVideoWidget* video_widget;
- QFrame* video_frame;
- bool tracking_valid;
-
- settings s;
- std::atomic<settings*> new_settings;
- Timer time;
-};
-
-#undef VideoWidget
-
-#endif // FTNOIR_TRACKER_PT_H
diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp b/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp deleted file mode 100644 index c103b78c..00000000 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "ftnoir_tracker_pt_dialog.h"
-
-#include <QMessageBox>
-#include <QDebug>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <vector>
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-TrackerDialog::TrackerDialog()
- : tracker(NULL),
- video_widget_dialog(NULL),
- timer(this),
- trans_calib_running(false)
-{
- qDebug()<<"TrackerDialog::TrackerDialog";
- setAttribute(Qt::WA_DeleteOnClose, false);
-
- ui.setupUi( this );
-
- vector<string> device_names;
- get_camera_device_names(device_names);
- for (vector<string>::iterator iter = device_names.begin(); iter != device_names.end(); ++iter)
- {
- ui.camdevice_combo->addItem(iter->c_str());
- }
-
- ui.camroll_combo->addItem("-90");
- ui.camroll_combo->addItem("0");
- ui.camroll_combo->addItem("90");
-
- tie_setting(s.dyn_pose_res, ui.dynpose_check);
- tie_setting(s.reset_time, ui.reset_spin);
-
- tie_setting(s.cam_index, ui.camdevice_combo);
- tie_setting(s.cam_f, ui.f_dspin);
- tie_setting(s.cam_res_x, ui.res_x_spin);
- tie_setting(s.cam_res_y, ui.res_y_spin);
- tie_setting(s.cam_fps, ui.fps_spin);
- tie_setting(s.cam_roll, ui.camroll_combo);
- tie_setting(s.cam_pitch, ui.campitch_spin);
- tie_setting(s.cam_yaw, ui.camyaw_spin);
-
- tie_setting(s.threshold_secondary, ui.threshold_secondary_slider);
- tie_setting(s.threshold, ui.threshold_slider);
-
- tie_setting(s.bEnableYaw, ui.chkEnableYaw);
- tie_setting(s.bEnablePitch, ui.chkEnablePitch);
- tie_setting(s.bEnableRoll, ui.chkEnableRoll);
- tie_setting(s.bEnableX, ui.chkEnableX);
- tie_setting(s.bEnableY, ui.chkEnableY);
- tie_setting(s.bEnableZ, ui.chkEnableZ);
-
- tie_setting(s.min_point_size, ui.mindiam_spin);
- tie_setting(s.max_point_size, ui.maxdiam_spin);
-
- tie_setting(s.clip_by, ui.clip_bheight_spin);
- tie_setting(s.clip_bz, ui.clip_blength_spin);
- tie_setting(s.clip_ty, ui.clip_theight_spin);
- tie_setting(s.clip_tz, ui.clip_tlength_spin);
-
- tie_setting(s.cap_x, ui.cap_width_spin);
- tie_setting(s.cap_y, ui.cap_height_spin);
- tie_setting(s.cap_z, ui.cap_length_spin);
-
- tie_setting(s.m01_x, ui.m1x_spin);
- tie_setting(s.m01_y, ui.m1y_spin);
- tie_setting(s.m01_z, ui.m1z_spin);
-
- tie_setting(s.m02_x, ui.m2x_spin);
- tie_setting(s.m02_y, ui.m2y_spin);
- tie_setting(s.m02_z, ui.m2z_spin);
-
- tie_setting(s.t_MH_x, ui.tx_spin);
- tie_setting(s.t_MH_y, ui.ty_spin);
- tie_setting(s.t_MH_z, ui.tz_spin);
-
- connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) );
- connect(ui.reset_button, SIGNAL(clicked()), this, SLOT(doReset()));
-
- connect(ui.ok_button, SIGNAL(clicked()), this, SLOT(doOK()));
- connect(ui.cancel_button, SIGNAL(clicked()), this, SLOT(doCancel()));
- connect(ui.btnApply, SIGNAL(clicked()), this, SLOT(doApply()));
-
- ui.model_tabs->setCurrentIndex(s.active_model_panel);
-
- connect(ui.model_tabs, SIGNAL(currentChanged(int)), this, SLOT(set_model(int)));
- connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info()));
- timer.start(100);
-
- connect(s.b.get(), SIGNAL(bundleChanged()), this, SLOT(do_apply_without_saving()));
-}
-
-void TrackerDialog::set_model_clip()
-{
- s.m01_x = 0;
- s.m01_y = static_cast<double>(s.clip_ty);
- s.m01_z = -static_cast<double>(s.clip_tz);
- s.m02_x = 0;
- s.m02_y = -static_cast<double>(s.clip_by);
- s.m02_z = -static_cast<double>(s.clip_bz);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_cap()
-{
- s.m01_x = -static_cast<double>(s.cap_x);
- s.m01_y = -static_cast<double>(s.cap_y);
- s.m01_z = -static_cast<double>(s.cap_z);
- s.m02_x = static_cast<double>(s.cap_x);
- s.m02_y = -static_cast<double>(s.cap_y);
- s.m02_z = -static_cast<double>(s.cap_z);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_custom()
-{
- settings_changed();
-}
-
-void TrackerDialog::set_model(int val)
-{
- s.active_model_panel = val;
-}
-
-void TrackerDialog::startstop_trans_calib(bool start)
-{
- if (start)
- {
- qDebug()<<"TrackerDialog:: Starting translation calibration";
- trans_calib.reset();
- trans_calib_running = true;
- }
- else
- {
- qDebug()<<"TrackerDialog:: Stoppping translation calibration";
- trans_calib_running = false;
- {
- auto tmp = trans_calib.get_estimate();
- s.t_MH_x = tmp[0];
- s.t_MH_y = tmp[1];
- s.t_MH_z = tmp[2];
- }
- settings_changed();
- }
-}
-
-void TrackerDialog::trans_calib_step()
-{
- if (tracker)
- {
- FrameTrafo X_CM;
- tracker->get_pose(&X_CM);
- trans_calib.update(X_CM.R, X_CM.t);
- cv::Vec3f t_MH = trans_calib.get_estimate();
- s.t_MH_x = t_MH[0];
- s.t_MH_y = t_MH[1];
- s.t_MH_z = t_MH[2];
- }
-}
-
-void TrackerDialog::settings_changed()
-{
- if (tracker) tracker->apply(s);
-}
-
-void TrackerDialog::doCenter()
-{
- if (tracker) tracker->center();
-}
-
-void TrackerDialog::doReset()
-{
- if (tracker) tracker->reset();
-}
-
-void TrackerDialog::save()
-{
- do_apply_without_saving();
- s.b->save();
-}
-
-void TrackerDialog::doOK()
-{
- save();
- close();
-}
-
-void TrackerDialog::do_apply_without_saving()
-{
- switch (s.active_model_panel) {
- default:
- case 0:
- set_model_clip();
- break;
- case 1:
- set_model_cap();
- break;
- case 2:
- set_model_custom();
- break;
- }
- if (tracker) tracker->apply(s);
-}
-
-void TrackerDialog::doApply()
-{
- save();
-}
-
-void TrackerDialog::doCancel()
-{
- s.b->revert();
- close();
-}
-
-void TrackerDialog::widget_destroyed(QObject* obj)
-{
- if (obj == video_widget_dialog) {
- // widget was / will be already deleted by Qt
- destroy_video_widget(false);
- }
-}
-
-void TrackerDialog::create_video_widget()
-{
- // this should not happen but better be sure
- if (video_widget_dialog) destroy_video_widget();
- if (!tracker) return;
-
- video_widget_dialog = new VideoWidgetDialog(this, tracker);
- video_widget_dialog->setAttribute( Qt::WA_DeleteOnClose );
- connect( video_widget_dialog, SIGNAL(destroyed(QObject*)), this, SLOT(widget_destroyed(QObject*)) );
- video_widget_dialog->show();
-}
-
-void TrackerDialog::destroy_video_widget(bool do_delete /*= true*/)
-{
- if (video_widget_dialog) {
- if (do_delete) delete video_widget_dialog;
- video_widget_dialog = NULL;
- }
-}
-
-void TrackerDialog::poll_tracker_info()
-{
- if (tracker)
- {
- QString to_print;
-
- // display caminfo
- CamInfo info;
- tracker->get_cam_info(&info);
- to_print = QString::number(info.res_x)+"x"+QString::number(info.res_y)+" @ "+QString::number(info.fps)+" FPS";
- ui.caminfo_label->setText(to_print);
-
- // display pointinfo
- int n_points = tracker->get_n_points();
- to_print = QString::number(n_points);
- if (n_points == 3)
- to_print += " OK!";
- else
- to_print += " BAD!";
- ui.pointinfo_label->setText(to_print);
-
- // update calibration
- if (trans_calib_running) trans_calib_step();
-
- // update videowidget
- if (video_widget_dialog) {
- video_widget_dialog->get_video_widget()->update_frame_and_points();
- }
- }
- else
- {
- QString to_print = "Tracker offline";
- ui.caminfo_label->setText(to_print);
- ui.pointinfo_label->setText(to_print);
- }
-}
-
-void TrackerDialog::registerTracker(ITracker *t)
-{
- qDebug()<<"TrackerDialog:: Tracker registered";
- tracker = static_cast<Tracker*>(t);
- if (isVisible() & s.b->modifiedp())
- tracker->apply(s);
- ui.tcalib_button->setEnabled(true);
- //ui.center_button->setEnabled(true);
- ui.reset_button->setEnabled(true);
-}
-
-void TrackerDialog::unRegisterTracker()
-{
- qDebug()<<"TrackerDialog:: Tracker un-registered";
- tracker = NULL;
- destroy_video_widget();
- ui.tcalib_button->setEnabled(false);
- //ui.center_button->setEnabled(false);
- ui.reset_button->setEnabled(false);
-}
-
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
-{
- return new TrackerDialog;
-}
diff --git a/FTNoIR_Tracker_PT/point_extractor.h b/FTNoIR_Tracker_PT/point_extractor.h deleted file mode 100644 index ff36f3ce..00000000 --- a/FTNoIR_Tracker_PT/point_extractor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef POINTEXTRACTOR_H
-#define POINTEXTRACTOR_H
-
-#include <opencv2/opencv.hpp>
-#include <opencv2/imgproc/imgproc_c.h>
-
-// ----------------------------------------------------------------------------
-// Extracts points from an opencv image
-class PointExtractor
-{
-public:
- // extracts points from frame and draws some processing info into frame, if draw_output is set
- // dt: time since last call in seconds
- // WARNING: returned reference is valid as long as object
- const std::vector<cv::Vec2f>& extract_points(cv::Mat frame, float dt, bool draw_output);
- const std::vector<cv::Vec2f>& get_points() { return points; }
- PointExtractor();
-
- int threshold_val;
- int threshold_secondary_val;
- int min_size, max_size;
-
-protected:
- std::vector<cv::Vec2f> points;
- cv::Mat frame_last;
-};
-
-#endif //POINTEXTRACTOR_H
diff --git a/FTNoIR_Tracker_PT/point_tracker.cpp b/FTNoIR_Tracker_PT/point_tracker.cpp deleted file mode 100644 index dfefdaf8..00000000 --- a/FTNoIR_Tracker_PT/point_tracker.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "point_tracker.h"
-
-#include <vector>
-#include <algorithm>
-#include <cmath>
-
-#include <QDebug>
-
-using namespace cv;
-using namespace boost;
-using namespace std;
-
-const float PI = 3.14159265358979323846f;
-
-// ----------------------------------------------------------------------------
-static void get_row(const Matx33f& m, int i, Vec3f& v)
-{
- v[0] = m(i,0);
- v[1] = m(i,1);
- v[2] = m(i,2);
-}
-
-static void set_row(Matx33f& m, int i, const Vec3f& v)
-{
- m(i,0) = v[0];
- m(i,1) = v[1];
- m(i,2) = v[2];
-}
-
-// ----------------------------------------------------------------------------
-PointModel::PointModel(Vec3f M01, Vec3f M02)
- : M01(M01),
- M02(M02)
-{
- // calculate u
- u = M01.cross(M02);
- u /= norm(u);
-
- // calculate projection matrix on M01,M02 plane
- float s11 = M01.dot(M01);
- float s12 = M01.dot(M02);
- float s22 = M02.dot(M02);
- P = 1.0/(s11*s22-s12*s12) * Matx22f(s22, -s12,
- -s12, s11);
-
- // calculate d and d_order for simple freetrack-like point correspondence
- vector<Vec2f> points;
- points.push_back(Vec2f(0,0));
- points.push_back(Vec2f(M01[0], M01[1]));
- points.push_back(Vec2f(M02[0], M02[1]));
- // fit line to orthographically projected points
- // ERROR: yields wrong results with colinear points?!
- /*
- Vec4f line;
- fitLine(points, line, CV_DIST_L2, 0, 0.01, 0.01);
- d[0] = line[0]; d[1] = line[1];
- */
- // TODO: fix this
- d = Vec2f(M01[0]-M02[0], M01[1]-M02[1]);
-
- // sort model points
- get_d_order(points, d_order);
-}
-
-#ifdef OPENTRACK_API
-static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b)
-{
- return a.first < b.first;
-}
-#endif
-
-void PointModel::get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const
-{
- // get sort indices with respect to d scalar product
- vector< pair<float,int> > d_vals;
- for (int i = 0; i<points.size(); ++i)
- d_vals.push_back(pair<float, int>(d.dot(points[i]), i));
-
- struct
- {
- bool operator()(const pair<float, int>& a, const pair<float, int>& b) { return a.first < b.first; }
- } comp;
- std::sort(d_vals.begin(),
- d_vals.end(),
-#ifdef OPENTRACK_API
- d_vals_sort
-#else
- comp
-#endif
- );
-
- for (int i = 0; i<points.size(); ++i)
- d_order[i] = d_vals[i].second;
-}
-
-
-// ----------------------------------------------------------------------------
-PointTracker::PointTracker()
- : init_phase(true),
- dt_valid(0),
- dt_reset(1),
- v_t(0,0,0),
- v_r(0,0,0),
- dynamic_pose_resolution(true)
-{
- X_CM.t[2] = 1000; // default position: 1 m away from cam;
-}
-
-void PointTracker::reset()
-{
- // enter init phase and reset velocities
- init_phase = true;
- dt_valid = 0;
- reset_velocities();
-}
-
-void PointTracker::reset_velocities()
-{
- v_t = Vec3f(0,0,0);
- v_r = Vec3f(0,0,0);
-}
-
-
-bool PointTracker::track(const vector<Vec2f>& points, float f, float dt)
-{
- if (!dynamic_pose_resolution) init_phase = true;
-
- dt_valid += dt;
- // if there was no valid tracking result for too long, do a reset
- if (dt_valid > dt_reset)
- {
- //qDebug()<<"dt_valid "<<dt_valid<<" > dt_reset "<<dt_reset;
- reset();
- }
-
- bool no_model =
-#ifdef OPENTRACK_API
- point_model.get() == NULL;
-#else
- !point_model;
-#endif
-
- // if there is a pointtracking problem, reset the velocities
- if (no_model || points.size() != PointModel::N_POINTS)
- {
- //qDebug()<<"Wrong number of points!";
- reset_velocities();
- return false;
- }
-
- X_CM_old = X_CM; // backup old transformation for velocity calculation
-
- if (!init_phase)
- predict(dt_valid);
-
- // if there is a point correspondence problem something has gone wrong, do a reset
- if (!find_correspondences(points, f))
- {
- //qDebug()<<"Error in finding point correspondences!";
- X_CM = X_CM_old; // undo prediction
- reset();
- return false;
- }
-
- int n_iter = POSIT(f);
- //qDebug()<<"Number of POSIT iterations: "<<n_iter;
-
- if (!init_phase)
- update_velocities(dt_valid);
-
- // we have a valid tracking result, leave init phase and reset time since valid result
- init_phase = false;
- dt_valid = 0;
- return true;
-}
-
-void PointTracker::predict(float dt)
-{
- // predict with constant velocity
- Matx33f R;
- Rodrigues(dt*v_r, R);
- X_CM.R = R*X_CM.R;
- X_CM.t += dt * v_t;
-}
-
-void PointTracker::update_velocities(float dt)
-{
- // update velocities
- Rodrigues(X_CM.R*X_CM_old.R.t(), v_r);
- v_r /= dt;
- v_t = (X_CM.t - X_CM_old.t)/dt;
-}
-
-bool PointTracker::find_correspondences(const vector<Vec2f>& points, float f)
-{
- if (init_phase) {
- // We do a simple freetrack-like sorting in the init phase...
- // sort points
- int point_d_order[PointModel::N_POINTS];
- point_model->get_d_order(points, point_d_order);
-
- // set correspondences
- for (int i=0; i<PointModel::N_POINTS; ++i)
- {
- p[point_model->d_order[i]] = points[point_d_order[i]];
- }
- }
- else {
- // ... otherwise we look at the distance to the projection of the expected model points
- // project model points under current pose
- p_exp[0] = project(Vec3f(0,0,0), f);
- p_exp[1] = project(point_model->M01, f);
- p_exp[2] = project(point_model->M02, f);
-
- // set correspondences by minimum distance to projected model point
- bool point_taken[PointModel::N_POINTS];
- for (int i=0; i<PointModel::N_POINTS; ++i)
- point_taken[i] = false;
-
- float min_sdist = 0;
- int min_idx = 0;
-
- for (int i=0; i<PointModel::N_POINTS; ++i)
- {
- // find closest point to projected model point i
- for (int j=0; j<PointModel::N_POINTS; ++j)
- {
- Vec2f d = p_exp[i]-points[j];
- float sdist = d.dot(d);
- if (sdist < min_sdist || j==0)
- {
- min_idx = j;
- min_sdist = sdist;
- }
- }
- // if one point is closest to more than one model point, abort
- if (point_taken[min_idx]) return false;
- point_taken[min_idx] = true;
- p[i] = points[min_idx];
- }
- }
- return true;
-}
-
-
-
-int PointTracker::POSIT(float f)
-{
- // POSIT algorithm for coplanar points as presented in
- // [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
- // we use the same notation as in the paper here
-
- // The expected rotation used for resolving the ambiguity in POSIT:
- // In every iteration step the rotation closer to R_expected is taken
- Matx33f R_expected;
- if (init_phase)
- R_expected = Matx33f::eye(); // in the init phase, we want to be close to the default pose = no rotation
- else
- R_expected = X_CM.R; // later we want to be close to the last (predicted) rotation
-
- // initial pose = last (predicted) pose
- Vec3f k;
- get_row(R_expected, 2, k);
- float Z0 = init_phase ? 1000 : X_CM.t[2];
-
- float old_epsilon_1 = 0;
- float old_epsilon_2 = 0;
- float epsilon_1 = 1;
- float epsilon_2 = 1;
-
- Vec3f I0, J0;
- Vec2f I0_coeff, J0_coeff;
-
- Vec3f I_1, J_1, I_2, J_2;
- Matx33f R_1, R_2;
- Matx33f* R_current;
-
- const int MAX_ITER = 100;
- const float EPS_THRESHOLD = 1e-4;
-
- int i=1;
- for (; i<MAX_ITER; ++i)
- {
- epsilon_1 = k.dot(point_model->M01)/Z0;
- epsilon_2 = k.dot(point_model->M02)/Z0;
-
- // vector of scalar products <I0, M0i> and <J0, M0i>
- Vec2f I0_M0i(p[1][0]*(1.0 + epsilon_1) - p[0][0],
- p[2][0]*(1.0 + epsilon_2) - p[0][0]);
- Vec2f J0_M0i(p[1][1]*(1.0 + epsilon_1) - p[0][1],
- p[2][1]*(1.0 + epsilon_2) - p[0][1]);
-
- // construct projection of I, J onto M0i plane: I0 and J0
- I0_coeff = point_model->P * I0_M0i;
- J0_coeff = point_model->P * J0_M0i;
- I0 = I0_coeff[0]*point_model->M01 + I0_coeff[1]*point_model->M02;
- J0 = J0_coeff[0]*point_model->M01 + J0_coeff[1]*point_model->M02;
-
- // calculate u component of I, J
- float II0 = I0.dot(I0);
- float IJ0 = I0.dot(J0);
- float JJ0 = J0.dot(J0);
- float rho, theta;
- if (JJ0 == II0) {
- rho = sqrt(abs(2*IJ0));
- theta = -PI/4;
- if (IJ0<0) theta *= -1;
- }
- else {
- rho = sqrt(sqrt( (JJ0-II0)*(JJ0-II0) + 4*IJ0*IJ0 ));
- theta = atan( -2*IJ0 / (JJ0-II0) );
- if (JJ0 - II0 < 0) theta += PI;
- theta /= 2;
- }
-
- // construct the two solutions
- I_1 = I0 + rho*cos(theta)*point_model->u;
- I_2 = I0 - rho*cos(theta)*point_model->u;
-
- J_1 = J0 + rho*sin(theta)*point_model->u;
- J_2 = J0 - rho*sin(theta)*point_model->u;
-
- float norm_const = 1.0/norm(I_1); // all have the same norm
-
- // create rotation matrices
- I_1 *= norm_const; J_1 *= norm_const;
- I_2 *= norm_const; J_2 *= norm_const;
-
- set_row(R_1, 0, I_1);
- set_row(R_1, 1, J_1);
- set_row(R_1, 2, I_1.cross(J_1));
-
- set_row(R_2, 0, I_2);
- set_row(R_2, 1, J_2);
- set_row(R_2, 2, I_2.cross(J_2));
-
- // the single translation solution
- Z0 = norm_const * f;
-
- // pick the rotation solution closer to the expected one
- // in simple metric d(A,B) = || I - A * B^T ||
- float R_1_deviation = norm(Matx33f::eye() - R_expected * R_1.t());
- float R_2_deviation = norm(Matx33f::eye() - R_expected * R_2.t());
-
- if (R_1_deviation < R_2_deviation)
- R_current = &R_1;
- else
- R_current = &R_2;
-
- get_row(*R_current, 2, k);
-
- // check for convergence condition
- if (abs(epsilon_1 - old_epsilon_1) + abs(epsilon_2 - old_epsilon_2) < EPS_THRESHOLD)
- break;
- old_epsilon_1 = epsilon_1;
- old_epsilon_2 = epsilon_2;
- }
-
- // apply results
- X_CM.R = *R_current;
- X_CM.t[0] = p[0][0] * Z0/f;
- X_CM.t[1] = p[0][1] * Z0/f;
- X_CM.t[2] = Z0;
-
- return i;
-
- //Rodrigues(X_CM.R, r);
- //qDebug()<<"iter: "<<i;
- //qDebug()<<"t: "<<X_CM.t[0]<<' '<<X_CM.t[1]<<' '<<X_CM.t[2];
- //Vec3f r;
- //
- //qDebug()<<"r: "<<r[0]<<' '<<r[1]<<' '<<r[2]<<'\n';
-}
diff --git a/FTNoIR_Tracker_PT/point_tracker.h b/FTNoIR_Tracker_PT/point_tracker.h deleted file mode 100644 index 11034100..00000000 --- a/FTNoIR_Tracker_PT/point_tracker.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef POINTTRACKER_H
-#define POINTTRACKER_H
-
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-#endif
-#include <list>
-
-// ----------------------------------------------------------------------------
-// Affine frame trafo
-class FrameTrafo
-{
-public:
- FrameTrafo() : R(cv::Matx33f::eye()), t(0,0,0) {}
- FrameTrafo(const cv::Matx33f& R, const cv::Vec3f& t) : R(R),t(t) {}
-
- cv::Matx33f R;
- cv::Vec3f t;
-};
-
-inline FrameTrafo operator*(const FrameTrafo& X, const FrameTrafo& Y)
-{
- return FrameTrafo(X.R*Y.R, X.R*Y.t + X.t);
-}
-
-inline FrameTrafo operator*(const cv::Matx33f& X, const FrameTrafo& Y)
-{
- return FrameTrafo(X*Y.R, X*Y.t);
-}
-
-inline FrameTrafo operator*(const FrameTrafo& X, const cv::Matx33f& Y)
-{
- return FrameTrafo(X.R*Y, X.t);
-}
-
-inline cv::Vec3f operator*(const FrameTrafo& X, const cv::Vec3f& v)
-{
- return X.R*v + X.t;
-}
-
-
-// ----------------------------------------------------------------------------
-// Describes a 3-point model
-// nomenclature as in
-// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
-class PointModel
-{
- friend class PointTracker;
-public:
- static const int N_POINTS = 3;
-
- PointModel(cv::Vec3f M01, cv::Vec3f M02);
-
- const cv::Vec3f& get_M01() const { return M01; };
- const cv::Vec3f& get_M02() const { return M02; };
-
-protected:
- cv::Vec3f M01; // M01 in model frame
- cv::Vec3f M02; // M02 in model frame
-
- cv::Vec3f u; // unit vector perpendicular to M01,M02-plane
-
- cv::Matx22f P;
-
- cv::Vec2f d; // discriminant vector for point correspondence
- int d_order[3]; // sorting of projected model points with respect to d scalar product
-
- void get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const;
-};
-
-// ----------------------------------------------------------------------------
-// Tracks a 3-point model
-// implementing the POSIT algorithm for coplanar points as presented in
-// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"]
-class PointTracker
-{
-public:
- PointTracker();
-
- // track the pose using the set of normalized point coordinates (x pos in range -0.5:0.5)
- // f : (focal length)/(sensor width)
- // dt : time since last call
- bool track(const std::vector<cv::Vec2f>& points, float f, float dt);
- boost::shared_ptr<PointModel> point_model;
-
- bool dynamic_pose_resolution;
- float dt_reset;
-
- FrameTrafo get_pose() const { return X_CM; }
- void reset();
-
-protected:
- inline cv::Vec2f project(const cv::Vec3f& v_M, float f)
- {
- cv::Vec3f v_C = X_CM * v_M;
- return cv::Vec2f(f*v_C[0]/v_C[2], f*v_C[1]/v_C[2]);
- }
-
- bool find_correspondences(const std::vector<cv::Vec2f>& points, float f);
-
- cv::Vec2f p[PointModel::N_POINTS]; // the points in model order
- cv::Vec2f p_exp[PointModel::N_POINTS]; // the expected point positions
-
- void predict(float dt);
- void update_velocities(float dt);
- void reset_velocities();
-
-
- int POSIT(float f); // The POSIT algorithm, returns the number of iterations
-
- bool init_phase;
- float dt_valid; // time since last valid tracking result
- cv::Vec3f v_t; // velocities
- cv::Vec3f v_r;
- FrameTrafo X_CM; // trafo from model to camera
- FrameTrafo X_CM_old;
-};
-
-#endif //POINTTRACKER_H
@@ -43,17 +43,14 @@ Don't be afraid to submit an issue/feature request if the need arises. # Credits -- Stanisław Halik +- Stanisław Halik (maintainer) - Chris Thompson (aka mm0zct) -- Donovan Baarda +- Donovan Baarda (filtering/control theory expert) - Ryan Spicer (OSX tester, contributor) - Patrick Ruoff (PT tracker) -- FuraX49 (hatire arduino tracker) - Ulf Schreiber (PT tracker) - uglyDwarf (high CON) -- George Trigonakis (tester) - Wim Vriend (historically) -- Ron Hendriks (historically) # Licensing information diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index e9eb232a..00000000 --- a/TODO.txt +++ /dev/null @@ -1,29 +0,0 @@ -20131023 sh - Low-hanging fruit: Go through all forms and replace ok/cancel with - QButtonBox which works better with layouts. -20131020 sh - Add unit testing by means of batch execution, protocol/filter that does - nothing, add separate executables for readers of specific protocols, - and run continuous integration every time commit happens that day. - - Add statically-typed settings trees, convert result to qsettings-enabled - ini files. Use metadata props in order to get class name for ini section. - Required here are also arrays of settings. Use QList<T> for template - specialization. -20131019 mm0zct - Ship more then one profile for configuring the curves etc. - There are two main user bases, HMD and traditional monitor+webcam users, - each wants a drastically different curve profile (HMD is 1:1 on all axes) - Also re:boost, I'd rather avoid extra library dependences if possible. - - Rift tracker could do with positional estimation using intertial sensors. - Rift could do with a return-yaw-to-centre hotkey that's not the global all-axis option. - Hydra is really just a hack just now, could be improved a lot. - - Add per-tracker hotkey support -20131011 sh - low-hanging fruit: default saving profiles to a directory in user home, - not into global stuffies - - as for build system, low-hanging fruit is writing functions/macrology - for all the repetition out there. diff --git a/bin/settings/facetracknoir supported games.csv b/bin/settings/facetracknoir supported games.csv index 91b9e6e6..4052806b 100644 --- a/bin/settings/facetracknoir supported games.csv +++ b/bin/settings/facetracknoir supported games.csv @@ -1,519 +1,527 @@ No;Game Name;Game protocol;Supported since;Verified;By;INTERNATIONAL_ID;FTN_ID -1;18 Wheels of Steel: Haulin';FreeTrack20;V160;V;doc-uk;13601;000121F172F35116A02100
-2;1944 D-Day;FreeTrack20;V160;;;15701;00022E542A6A0575F05200
-497;2KMarinNEXT;FreeTrack20;V170;;;3425;0D614F6A0820D1EA8EE800
-3;3D Instructor;FreeTrack20;V160;;;20490;00034B0FC367116611B100
-4;3D Interactive;FreeTrack20;V160;;;20425;0004C6371D77135815A600
+1;18 Wheels of Steel: Haulin';FreeTrack20;V160;V;doc-uk;13601;000121F172F35116A02100 +2;1944 D-Day;FreeTrack20;V160;;;15701;00022E542A6A0575F05200 +497;2KMarinNEXT;FreeTrack20;V170;;;3425;0D614F6A0820D1EA8EE800 +3;3D Instructor;FreeTrack20;V160;;;20490;00034B0FC367116611B100 +4;3D Interactive;FreeTrack20;V160;;;20425;0004C6371D77135815A600 505;3D Interieur Visualisation;FreeTrack20;V160;;;20815;01F9EDEE75DAC2968D9A00 -5;3d Nav;FreeTrack20;V160;;;20235;000579EC0E26932651EA00
-6;3D-Fahrschule Driving Simulator;FreeTrack20;V160;;;20020;000601075146E0E9625B00
-7;3ds Max;FreeTrack20;V160;;;8601;00077A32A1A7523A4DE700
-8;Aaaaa!;FreeTrack20;V160;;;1775;00085485D831DA62CA7E00
-9;Accessible Computer Games;FreeTrack20;V160;;;4301;000916BC07A2F9B35B6300
-10;Aces High II;FreeTrack20;V160;V;bash1;2701;000A4B798B7221A72E5800
-11;ADS;FreeTrack20;V160;;;20690;000BB25377780C8A894400
-12;Aerofly FS;FreeTrack20;V160;V;V4Friend;2025;000C3797169752CAB39A00
-13;Affineon;FreeTrack20;V160;;;20405;000D662B0374339635A000
-14;Air Battles: Sky Defender;FreeTrack20;V160;;;7003;000E7C822098630A2ED700
-15;Air Phobia;FreeTrack20;V160;;;20100;000F0108339B3E78525B00
-16;Air Traffic Control Tower;FreeTrack20;V160;;;3601;0010432C28637A8EF97400
-17;AirBook;FreeTrack20;V160;;;15201;0011D615A9C8430A201A00
-18;America's Army;FreeTrack20;V160;;;4101;00120BCF5753D98399E200
-19;America's Army 3;FreeTrack20;V170;;;14203;00133F3206BCEA252BB700
-20;ANAG 3D;FreeTrack20;V160;;;20250;0014E2D1D7780A72166300
-21;Apache: Air Assault;FreeTrack20;V160;V;paleta77;1875;001591D997A2D912AAA200
-22;Aprisoft Gartenplaner;FreeTrack20;V160;;;20014;0016F2F27A5762FA937A00
-23;Aprisoft Traumhaus Designer;FreeTrack20;V160;;;20013;00174655E792BB825B9300
+5;3d Nav;FreeTrack20;V160;;;20235;000579EC0E26932651EA00 +6;3D-Fahrschule Driving Simulator;FreeTrack20;V160;;;20020;000601075146E0E9625B00 +7;3ds Max;FreeTrack20;V160;;;8601;00077A32A1A7523A4DE700 +8;Aaaaa!;FreeTrack20;V160;;;1775;00085485D831DA62CA7E00 +9;Accessible Computer Games;FreeTrack20;V160;;;4301;000916BC07A2F9B35B6300 +10;Aces High II;FreeTrack20;V160;V;bash1;2701;000A4B798B7221A72E5800 +11;ADS;FreeTrack20;V160;;;20690;000BB25377780C8A894400 +12;Aerofly FS;FreeTrack20;V160;V;V4Friend;2025;000C3797169752CAB39A00 +13;Affineon;FreeTrack20;V160;;;20405;000D662B0374339635A000 +14;Air Battles: Sky Defender;FreeTrack20;V160;;;7003;000E7C822098630A2ED700 +15;Air Phobia;FreeTrack20;V160;;;20100;000F0108339B3E78525B00 +16;Air Traffic Control Tower;FreeTrack20;V160;;;3601;0010432C28637A8EF97400 +17;AirBook;FreeTrack20;V160;;;15201;0011D615A9C8430A201A00 +18;America's Army;FreeTrack20;V160;;;4101;00120BCF5753D98399E200 +19;America's Army 3;FreeTrack20;V170;;;14203;00133F3206BCEA252BB700 +20;ANAG 3D;FreeTrack20;V160;;;20250;0014E2D1D7780A72166300 +21;Apache: Air Assault;FreeTrack20;V160;V;paleta77;1875;001591D997A2D912AAA200 +519;Apex Motorsports;FreeTrack20;V160;;;3675;02078F3159271BBE676800 +22;Aprisoft Gartenplaner;FreeTrack20;V160;;;20014;0016F2F27A5762FA937A00 +23;Aprisoft Traumhaus Designer;FreeTrack20;V160;;;20013;00174655E792BB825B9300 498;ARI;FreeTrack20;V160;;;20795;01F23FB9A61044E206E200 -24;ArmA;FreeTrack20;V160;V;EmBeES;10601;0018F2F27A57631A40F200
-25;ArmA 2;FreeTrack20;V170;V;V4Friend, Ronski;7502;0019EB3616B3A44F05B900
-26;ArmA 2 Operation Arrowhead;FreeTrack20;V160;V;vn88holden;0;001ABC224B7783DAF0D500
-27;ArmA 3;FreeTrack20;V170;;;7503;001BB69411ABD4E2B39900
-28;Armored Assault - Gold Edition;FreeTrack20;V170;;;1303;001CA7F7CAA00814ECA700
-29;Arvoch Alliance;FreeTrack20;V160;;;14908;001D318F8773BAE29A9300
-30;Arvoch Conflict;FreeTrack20;V160;;;14901;001E5C1FDE722DAE2BA900
-31;Auditory Displays for the blind;FreeTrack20;V160;;;20035;001F0FC9FF862F9D34BA00
-486;Autodesk;FreeTrack20;V160;;;20755;01E6953FA7F759AF33AC00
-32;AV Core Technology;FreeTrack20;V160;;;20016;00204655E791166FEB5300
-33;AVRS;FreeTrack20;V160;;;20340;0021231517525830F41D00
-482;B.O.M.B.;FreeTrack20;V160;;;3325;01E248ECCB81191AD49F00
-34;BAE Systems HILAS cockpit;FreeTrack20;V160;;;20019;00220D9C887FD88E98B300
-35;Battle of Britain (iENT);FreeTrack20;V170;;;1305;00230BA119195B701AED00
-36;Battle of Britain II - Wings of Victory;FreeTrack20;V160;V;Normalguy;7001;002452135882CA6419E200
-37;Battlecruiser;FreeTrack20;V160;;;6101;00257C822098728A442900
-38;Battlefield 2;FreeTrack20;V170;;;9601;0026B1560A2A7327659200
-39;Battlefield 2 Trauma Studios;FreeTrack20;V160;;;6501;002720C7529B733AE2EA00
-40;Battlefield 2142;FreeTrack20;V170;;;9602;00281C739AD3817FD43300
-41;Battleground Europe : World War II Online;FreeTrack20;V160;;;3301;0029F07957792CAD3DAF00
-42;Battleground Europe : WWII Online;FreeTrack20;V160;;;11201;002A985017330A844A1200
-43;Beckman Institute UIUC;FreeTrack20;V160;;;20012;002BB59DEFA8322A926A00
-44;Beyond The Red Line;FreeTrack20;V160;;;13301;002CE7A7FAA27424BA2A00
-45;BF2 (Unsupported Demo);FreeTrack20;V160;;;9651;002DC6371D86156AEB6000
-46;Big Scale Racing;FreeTrack20;V160;;;8301;002E4655E7A24ADDB99200
-47;Birds of Prey;FreeTrack20;V160;;;1601;002FBF8C4EAA57730B3200
-48;Birds of Steel;FreeTrack20;V160;;;1878;0030D7690F607233A21E00
-49;Boeing;FreeTrack20;V160;;;20351;0031044872BA630A033E00
-50;Boeing Demo;FreeTrack20;V160;;;20350;003228C57B369A37B13600
-51;Bomber Squadron;FreeTrack20;V160;;;1850;00338481733B9E32A83A00
-52;Brain-IT Group;FreeTrack20;V160;;;20050;0034E482F5772C9330B100
-53;Brothers In Arms;FreeTrack20;V160;;;13501;003503FB872CA8439D1F00
-82;C-Spine;FreeTrack20;V160;;;4901;00525FD692C188FB8B2D00
-54;C.A.R.S.;FreeTrack20;V170;;;2825;003698EFE2EB6EE8E11300
-55;C.U.B.;FreeTrack20;V160;;;20505;0037848174F986FD85F500
-56;CameraGripTools;FreeTrack20;V160;;;20150;003870A8B761FA524A4200
-57;Caterpillar Simulators;FreeTrack20;V160;;;23080;0039F52E4221742FA63100
-58;CCG Metamedia;FreeTrack20;V160;;;20009;003A6FA8A8DD86FE8BDB00
-59;CEWIT Immersive Cabin;FreeTrack20;V160;;;20370;003B90B5780C90078DEE00
-60;Chopper;FreeTrack20;V160;;;3150;003CC166C8632A32EA2300
-61;Clearbox;FreeTrack20;V160;;;20565;003D5C1FDE74279D1DB800
-62;CNKFsoft;FreeTrack20;V160;;;20495;003ED7690F6073187B0000
-487;Cognitics;FreeTrack20;V160;;;20760;01E715A96D19515BFC1500
-63;Colin McRae DiRT 2;FreeTrack20;V170;V;V4Friend;8107;003F7815C5379491C73300
-64;Colin McRae Rally 04;FreeTrack20;V160;;;8103;0040D13C2A843DA526A610
-65;Comanche;FreeTrack20;V160;;;2275;00414097C36A12BA32BA00
-66;Combat Flight Simulator 3;FreeTrack20;V160;V;V4Friend;2304;00420EC5F763AB21CA7310
-67;Combat Helo;FreeTrack20;V160;;;2001;004329DFA863FAE1EA7300
+24;ArmA;FreeTrack20;V160;V;EmBeES;10601;0018F2F27A57631A40F200 +25;ArmA 2;FreeTrack20;V170;V;V4Friend Ronski;7502;0019EB3616B3A44F05B900 +26;ArmA 2 Operation Arrowhead;FreeTrack20;V160;V;vn88holden;0;001ABC224B7783DAF0D500 +27;ArmA 3;FreeTrack20;V170;;;7503;001BB69411ABD4E2B39900 +28;Armored Assault - Gold Edition;FreeTrack20;V170;;;1303;001CA7F7CAA00814ECA700 +29;Arvoch Alliance;FreeTrack20;V160;;;14908;001D318F8773BAE29A9300 +30;Arvoch Conflict;FreeTrack20;V160;;;14901;001E5C1FDE722DAE2BA900 +31;Auditory Displays for the blind;FreeTrack20;V160;;;20035;001F0FC9FF862F9D34BA00 +486;Autodesk;FreeTrack20;V160;;;20755;01E6953FA7F759AF33AC00 +32;AV Core Technology;FreeTrack20;V160;;;20016;00204655E791166FEB5300 +33;AVRS;FreeTrack20;V160;;;20340;0021231517525830F41D00 +482;B.O.M.B.;FreeTrack20;V160;;;3325;01E248ECCB81191AD49F00 +34;BAE Systems HILAS cockpit;FreeTrack20;V160;;;20019;00220D9C887FD88E98B300 +35;Battle of Britain (iENT);FreeTrack20;V170;;;1305;00230BA119195B701AED00 +36;Battle of Britain II - Wings of Victory;FreeTrack20;V160;V;Normalguy;7001;002452135882CA6419E200 +37;Battlecruiser;FreeTrack20;V160;;;6101;00257C822098728A442900 +38;Battlefield 2;FreeTrack20;V170;;;9601;0026B1560A2A7327659200 +39;Battlefield 2 Trauma Studios;FreeTrack20;V160;;;6501;002720C7529B733AE2EA00 +40;Battlefield 2142;FreeTrack20;V170;;;9602;00281C739AD3817FD43300 +41;Battleground Europe : World War II Online;FreeTrack20;V160;;;3301;0029F07957792CAD3DAF00 +42;Battleground Europe : WWII Online;FreeTrack20;V160;;;11201;002A985017330A844A1200 +43;Beckman Institute UIUC;FreeTrack20;V160;;;20012;002BB59DEFA8322A926A00 +44;Beyond The Red Line;FreeTrack20;V160;;;13301;002CE7A7FAA27424BA2A00 +45;BF2 (Unsupported Demo);FreeTrack20;V160;;;9651;002DC6371D86156AEB6000 +46;Big Scale Racing;FreeTrack20;V160;;;8301;002E4655E7A24ADDB99200 +47;Birds of Prey;FreeTrack20;V160;;;1601;002FBF8C4EAA57730B3200 +48;Birds of Steel;FreeTrack20;V160;;;1878;0030D7690F607233A21E00 +49;Boeing;FreeTrack20;V160;;;20351;0031044872BA630A033E00 +50;Boeing Demo;FreeTrack20;V160;;;20350;003228C57B369A37B13600 +51;Bomber Squadron;FreeTrack20;V160;;;1850;00338481733B9E32A83A00 +52;Brain-IT Group;FreeTrack20;V160;;;20050;0034E482F5772C9330B100 +53;Brothers In Arms;FreeTrack20;V160;;;13501;003503FB872CA8439D1F00 +82;C-Spine;FreeTrack20;V160;;;4901;00525FD692C188FB8B2D00 +54;C.A.R.S.;FreeTrack20;V170;;;2825;003698EFE2EB6EE8E11300 +55;C.U.B.;FreeTrack20;V160;;;20505;0037848174F986FD85F500 +56;CameraGripTools;FreeTrack20;V160;;;20150;003870A8B761FA524A4200 +57;Caterpillar Simulators;FreeTrack20;V160;;;23080;0039F52E4221742FA63100 +58;CCG Metamedia;FreeTrack20;V160;;;20009;003A6FA8A8DD86FE8BDB00 +59;CEWIT Immersive Cabin;FreeTrack20;V160;;;20370;003B90B5780C90078DEE00 +60;Chopper;FreeTrack20;V160;;;3150;003CC166C8632A32EA2300 +61;Clearbox;FreeTrack20;V160;;;20565;003D5C1FDE74279D1DB800 +62;CNKFsoft;FreeTrack20;V160;;;20495;003ED7690F6073187B0000 +487;Cognitics;FreeTrack20;V160;;;20760;01E715A96D19515BFC1500 +63;Colin McRae DiRT 2;FreeTrack20;V170;V;V4Friend;8107;003F7815C5379491C73300 +64;Colin McRae Rally 04;FreeTrack20;V160;;;8103;0040D13C2A843DA526A610 +65;Comanche;FreeTrack20;V160;;;2275;00414097C36A12BA32BA00 +66;Combat Flight Simulator 3;FreeTrack20;V160;V;V4Friend;2304;00420EC5F763AB21CA7310 +67;Combat Helo;FreeTrack20;V160;;;2001;004329DFA863FAE1EA7300 515;Combined Arms;FreeTrack20;V160;;;1309;0203387EDB1A5AFEADB600 -68;Commandos Strike Force;FreeTrack20;V160;;;8801;0044C1BBF892DB037A7200
-69;Concept RS;FreeTrack20;V160;;;10701;004537971697736A72DA00
-70;Condor: The Competitive Soaring Simulator;FreeTrack20;V160;V;MicheleF;5901;004670A8B762DA623A1300
-71;Conflict Taiwan;FreeTrack20;V160;;;1950;0047D7690F6073399E2000
-72;Corys;FreeTrack20;V160;;;20550;0048157D78738A342A8D00
-73;Counter Strike;FreeTrack20;V160;;;12501;004953FE1E862AB73DA600
-74;Crane Simulator;FreeTrack20;V160;;;20048;004A6B62C6A7931972DA00
-75;Crashday;FreeTrack20;V160;;;5601;004BD6E585F893D933BA00
-76;Creanex Training Simulator;FreeTrack20;V160;;;20205;004CF478D277A40A929A00
-77;Creative Labs headset;FreeTrack20;V160;;;20018;004D348B1743E961FA6300
-78;Cross Racing Championship;FreeTrack20;V160;;;4801;004E20C763AB232B5E8900
-79;Crysis Mod;FreeTrack20;V160;;;1625;004F90B57839B231A24200
-80;Crystal Growth Simulation;FreeTrack20;V160;;;20029;005026F79742FB241A6200
-81;Crytek;FreeTrack20;V170;;;2775;0051D5F1EBBAD81C714600
-83;D2x-XL;FreeTrack20;V160;;;16001;00532E20237BEDABEB8A00
-84;Dark Horizons Lore;FreeTrack20;V160;;;7901;005487801A852AA7385200
-85;Dawn of Aces - Gold Edition;FreeTrack20;V170;;;1304;0055A9ED7700814190DE00
-86;Dawn of Aces II;FreeTrack20;V160;;;1302;00566925967C2BB0285500
+68;Commandos Strike Force;FreeTrack20;V160;;;8801;0044C1BBF892DB037A7200 +69;Concept RS;FreeTrack20;V160;;;10701;004537971697736A72DA00 +70;Condor: The Competitive Soaring Simulator;FreeTrack20;V160;V;MicheleF;5901;004670A8B762DA623A1300 +71;Conflict Taiwan;FreeTrack20;V160;;;1950;0047D7690F6073399E2000 +72;Corys;FreeTrack20;V160;;;20550;0048157D78738A342A8D00 +73;Counter Strike;FreeTrack20;V160;;;12501;004953FE1E862AB73DA600 +74;Crane Simulator;FreeTrack20;V160;;;20048;004A6B62C6A7931972DA00 +75;Crashday;FreeTrack20;V160;;;5601;004BD6E585F893D933BA00 +76;Creanex Training Simulator;FreeTrack20;V160;;;20205;004CF478D277A40A929A00 +77;Creative Labs headset;FreeTrack20;V160;;;20018;004D348B1743E961FA6300 +78;Cross Racing Championship;FreeTrack20;V160;;;4801;004E20C763AB232B5E8900 +79;Crysis Mod;FreeTrack20;V160;;;1625;004F90B57839B231A24200 +80;Crystal Growth Simulation;FreeTrack20;V160;;;20029;005026F79742FB241A6200 +81;Crytek;FreeTrack20;V170;;;2775;0051D5F1EBBAD81C714600 +83;D2x-XL;FreeTrack20;V160;;;16001;00532E20237BEDABEB8A00 +84;Dark Horizons Lore;FreeTrack20;V160;;;7901;005487801A852AA7385200 +85;Dawn of Aces - Gold Edition;FreeTrack20;V170;;;1304;0055A9ED7700814190DE00 +86;Dawn of Aces II;FreeTrack20;V160;;;1302;00566925967C2BB0285500 513;Dawn of Aces/Red Baron;FreeTrack20;V160;;;1307;0201916C14F32918D9B800 -87;DBS WalkAndFollow;FreeTrack20;V160;;;2525;005770A8B77008BDE89200
-88;DCS: Black Shark;FreeTrack20;V170;V;EmBeES;1006;0058F688FC9B0556868F00
-89;DCS: A-10C Warthog (32 and 64 bit);FreeTrack20;V170;V;fabri91, Shadow;1003;0059B6DCD15F5A572F6500
-90;Dead Reckoning;FreeTrack20;V160;;;10401;005A4C2F6752F912D66200
-91;Delivery;FreeTrack20;V160;;;15901;005BF3E85B1A8534AE3400
-471;Demon Core;FreeTrack20;V160;;;3225;01D7D1DC6052A165A7AC00
-92;DiRT;FreeTrack20;V160;;;8104;005C72456F7523881F1800
-93;DiRT 3;FreeTrack20;V170;;;8108;005DABA016ED2DFBDF6F00
-94;Door3;FreeTrack20;V160;;;20665;005ED13C2A853DA82F6B00
-95;Down In Flames;FreeTrack20;V160;;;1025;005F29DFA873FB82A66000
-96;Driver Test;FreeTrack20;V160;;;20265;00609343487C3FAA429D00
-97;Driver's Republic;FreeTrack20;V160;;;14001;0061D24C3F8A3F9C33AB00
-98;DriveSim;FreeTrack20;V160;;;5001;0062DD7CC2B47830A14400
-99;Driving Simulator;FreeTrack20;V160;;;13001;00630AC67539AC3F9F3A00
-100;dSphere TBA;FreeTrack20;V160;;;2425;0064A2AE4981FB5389A300
-101;DTS;FreeTrack20;V160;;;20625;006505B37C12868B3E8500
-102;Dungeons and Dragons Online;FreeTrack20;V170;;;1575;0066BD4D4DDC6BB6818800
-103;DY Demo;FreeTrack20;V160;;;20345;006727D5047A15540F9D00
-104;EADS Testing;FreeTrack20;V160;;;20303;00680288709760D5512900
+87;DBS WalkAndFollow;FreeTrack20;V160;;;2525;005770A8B77008BDE89200 +88;DCS: Black Shark;FreeTrack20;V170;V;EmBeES;1006;0058F688FC9B0556868F00 +89;DCS: A-10C Warthog (32 and 64 bit);FreeTrack20;V170;V;fabri91 Shadow;1003;0059B6DCD15F5A572F6500 +90;Dead Reckoning;FreeTrack20;V160;;;10401;005A4C2F6752F912D66200 +91;Delivery;FreeTrack20;V160;;;15901;005BF3E85B1A8534AE3400 +471;Demon Core;FreeTrack20;V160;;;3225;01D7D1DC6052A165A7AC00 +92;DiRT;FreeTrack20;V160;;;8104;005C72456F7523881F1800 +93;DiRT 3;FreeTrack20;V170;;;8108;005DABA016ED2DFBDF6F00 +94;Door3;FreeTrack20;V160;;;20665;005ED13C2A853DA82F6B00 +95;Down In Flames;FreeTrack20;V160;;;1025;005F29DFA873FB82A66000 +96;Driver Test;FreeTrack20;V160;;;20265;00609343487C3FAA429D00 +97;Driver's Republic;FreeTrack20;V160;;;14001;0061D24C3F8A3F9C33AB00 +98;DriveSim;FreeTrack20;V160;;;5001;0062DD7CC2B47830A14400 +99;Driving Simulator;FreeTrack20;V160;;;13001;00630AC67539AC3F9F3A00 +100;dSphere TBA;FreeTrack20;V160;;;2425;0064A2AE4981FB5389A300 +101;DTS;FreeTrack20;V160;;;20625;006505B37C12868B3E8500 +102;Dungeons and Dragons Online;FreeTrack20;V170;;;1575;0066BD4D4DDC6BB6818800 +103;DY Demo;FreeTrack20;V160;;;20345;006727D5047A15540F9D00 +104;EADS Testing;FreeTrack20;V160;;;20303;00680288709760D5512900 504;EAFIT;FreeTrack20;V160;;;20810;01F8D2675ABC163E99B000 -105;Eagle Lander 3D;FreeTrack20;V160;;;11901;00697686E5A7B209C27900
-106;EasyVR;FreeTrack20;V160;;;20220;006A68292872FAC4588100
-107;ECA-Sindel;FreeTrack20;V160;;;20590;006BC5BEE479FD75FB8500
+105;Eagle Lander 3D;FreeTrack20;V160;;;11901;00697686E5A7B209C27900 +106;EasyVR;FreeTrack20;V160;;;20220;006A68292872FAC4588100 +107;ECA-Sindel;FreeTrack20;V160;;;20590;006BC5BEE479FD75FB8500 508;Elite: Dangerous;FreeTrack20;V170;;;3475;0D93A9485EECA12E18BE00 -481;Embers of Caerus;FreeTrack20;V170;;;3275;0CCB4134258D7E10119E00
-108;EMS Simulations;FreeTrack20;V160;;;20390;006CA59E687D1589DE8500
-109;Enemy Engaged 2;FreeTrack20;V160;;;2102;006D010873EA635AEDC800
-110;Enemy Engaged: Commanche vs Hokum;FreeTrack20;V160;;;2101;006E157D789379636AED00
-111;Envision TE;FreeTrack20;V160;;;20320;006FD13C2A863CAF26AB00
-112;EON Reality;FreeTrack20;V160;;;20410;0070B6C6142771F82EE900
-113;eSigma;FreeTrack20;V160;;;20700;0071950F9AA60DAD2E9F00
-114;Euro Truck Simulator;FreeTrack20;V160;V;mamsa;13602;00721B4BFF8B3EA3296600
-115;EVE Online;FreeTrack20;V160;;;11801;0073F47CC377C2388DC900
-116;Eventology;FreeTrack20;V160;;;12201;0074849F8B469C2BAC3600
-117;EVOC-101 Training;FreeTrack20;V160;;;20038;00756925967D2088FC6200
-118;Evochron Alliance 2.0;FreeTrack20;V160;;;14904;00767A32A1A8735A022900
-119;Evochron Legends;FreeTrack20;V160;;;14906;0077D6E585F8B41A12BA00
-120;Evochron Mercenary;FreeTrack20;V160;V;Scavenger4711 ;14907;00783752FBC7B42B221A00
-121;Evochron Renegades;FreeTrack20;V160;;;14905;0079621E7763FB421A1300
-122;EZCA;FreeTrack20;V160;V;dennison ;2475;007A6DBB52F7B147510601
-125;F-22 Total Air War;FreeTrack20;V160;;;1750;007D20C79F475F0621DB00
-126;F-35 PTA;FreeTrack20;V160;;;20185;007E26F7977E96C0352100
-148;F-Trainer;FreeTrack20;V160;;;20615;0094C6371D8AFB8C3E9900
-123;F1 2011/2012;FreeTrack20;V170;;;8109;007B265ECD74893EA12900
-124;F1 Challenge 99-02;FreeTrack20;V160;;;4401;007CA15F278FB660C9D210
-127;FAAC;FreeTrack20;V160;;;20500;007F0F00F489118300C000
-128;Farmer Simulator 2009;FreeTrack20;V160;;;1725;0080926ED8A1EB628AB300
-129;Faros Driving Simulator;FreeTrack20;V160;;;8001;0081B1C6647A1EA839A800
-130;Faubert Lab Car Simulator;FreeTrack20;V160;;;20480;00822E542A7F2DB61F9700
-131;Ferrari Virtual Academy;FreeTrack20;V160;V;sosna1983 ;0;0083C0AF8C24B62D974000
-132;FIFA 09;FreeTrack20;V170;;;9002;0084288979C65B0DAA0D00
-133;Fighter Ace;FreeTrack20;V160;;;8401;0085E2D1D77D259837B700
-134;Fighter Ops;FreeTrack20;V160;;;9301;00860FC9FF8B23A033BA00
-135;Fighter Squadron: Screamin Demons Over Europe;FreeTrack20;V160;;;1675;00872E20237D259A27A600
-136;First Eagles, Wings Over Europe, Strike Fighters;FreeTrack20;V160;;;1101;0088311857638A73BB7E00
-469;Flight Gear;FreeTrack20;V160;;;12901;01D5D896C66B030606E000
-466;Flight Simulator 2002;FreeTrack20;V160;;;2302;01D21F7650E254B4514B00
-467;Flight Simulator 2004;FreeTrack20;V160;;;2303;01D3E91BAAB385B2362E00
-468;Flight Simulator X;FreeTrack20;V160;;;2305;01D41C31F42FAF32603600
-137;FlightGear;FlightGear;V110;V;V4Friend;0;0089054E8839A02FAB2F00
-138;Flyboys / Warbirds;FreeTrack20;V160;;;1301;008ABB5BF72C8934AB2B00
-139;Flyer;FreeTrack20;V160;;;1650;008BD1C9F27826AE2CA500
-140;Flying Tigers;FreeTrack20;V160;;;7002;008C91D997F29A930B0200
-141;FlyingGuns;FreeTrack20;V160;;;14801;008D7A32A1A882BAA28A00
-142;Ford Racing 3;FreeTrack20;V160;;;6901;008E27D5047C2BA62F5800
-143;Free Falcon 4.0;FreeTrack20;V160;;;1901;008F157D78A3B962E55000
-144;Free Falcon 4.0: Allied Force;FreeTrack20;V160;;;8901;0090656DD6793CA9325900
-145;Free Falcon 5;FreeTrack20;V160;V;V4Friend;1902;00911038C3AAB32590E900
-146;FreeSpace2;FreeTrack20;V160;;;13302;0092C8CDF8C2EA63496300
-147;FTAlpha;FreeTrack20;V160;;;20270;00936C69677F1D772AA900
-149;Full Out;FreeTrack20;V160;;;1701;009527D5047C31A0375800
-150;Future Pinball;FreeTrack20;V160;V;V4Friend;13101;00969343487E42B541AA00
-151;Game VR;FreeTrack20;V160;;;20325;009756BA018030B0355500
-152;GameLab;FreeTrack20;V160;;;20555;00985485D891DB23092200
-472;Games Farm;FreeTrack20;V160;;;3250;01D875C0981E627E5C7600
-153;Gamma;FreeTrack20;V160;;;1050;009921007D1B9D38A76F00
+481;Embers of Caerus;FreeTrack20;V170;;;3275;0CCB4134258D7E10119E00 +108;EMS Simulations;FreeTrack20;V160;;;20390;006CA59E687D1589DE8500 +109;Enemy Engaged 2;FreeTrack20;V160;;;2102;006D010873EA635AEDC800 +110;Enemy Engaged: Commanche vs Hokum;FreeTrack20;V160;;;2101;006E157D789379636AED00 +524;Enemy Starfighter;FreeTrack20;V160;;;3725;020C7EF3AC4F08C8787600 +111;Envision TE;FreeTrack20;V160;;;20320;006FD13C2A863CAF26AB00 +112;EON Reality;FreeTrack20;V160;;;20410;0070B6C6142771F82EE900 +113;eSigma;FreeTrack20;V160;;;20700;0071950F9AA60DAD2E9F00 +114;Euro Truck Simulator;FreeTrack20;V160;V;mamsa;13602;00721B4BFF8B3EA3296600 +115;EVE Online;FreeTrack20;V160;;;11801;0073F47CC377C2388DC900 +116;Eventology;FreeTrack20;V160;;;12201;0074849F8B469C2BAC3600 +117;EVOC-101 Training;FreeTrack20;V160;;;20038;00756925967D2088FC6200 +118;Evochron Alliance 2.0;FreeTrack20;V160;;;14904;00767A32A1A8735A022900 +119;Evochron Legends;FreeTrack20;V160;;;14906;0077D6E585F8B41A12BA00 +120;Evochron Mercenary;FreeTrack20;V160;V;Scavenger4711 ;14907;00783752FBC7B42B221A00 +121;Evochron Renegades;FreeTrack20;V160;;;14905;0079621E7763FB421A1300 +122;EZCA;FreeTrack20;V160;V;dennison ;2475;007A6DBB52F7B147510601 +125;F-22 Total Air War;FreeTrack20;V160;;;1750;007D20C79F475F0621DB00 +126;F-35 PTA;FreeTrack20;V160;;;20185;007E26F7977E96C0352100 +148;F-Trainer;FreeTrack20;V160;;;20615;0094C6371D8AFB8C3E9900 +123;F1 2011/2012;FreeTrack20;V170;;;8109;007B265ECD74893EA12900 +124;F1 Challenge 99-02;FreeTrack20;V160;;;4401;007CA15F278FB660C9D210 +127;FAAC;FreeTrack20;V160;;;20500;007F0F00F489118300C000 +128;Farmer Simulator 2009;FreeTrack20;V160;;;1725;0080926ED8A1EB628AB300 +129;Faros Driving Simulator;FreeTrack20;V160;;;8001;0081B1C6647A1EA839A800 +130;Faubert Lab Car Simulator;FreeTrack20;V160;;;20480;00822E542A7F2DB61F9700 +131;Ferrari Virtual Academy;FreeTrack20;V160;V;sosna1983 ;0;0083C0AF8C24B62D974000 +132;FIFA 09;FreeTrack20;V170;;;9002;0084288979C65B0DAA0D00 +133;Fighter Ace;FreeTrack20;V160;;;8401;0085E2D1D77D259837B700 +134;Fighter Ops;FreeTrack20;V160;;;9301;00860FC9FF8B23A033BA00 +135;Fighter Squadron: Screamin Demons Over Europe;FreeTrack20;V160;;;1675;00872E20237D259A27A600 +136;First Eagles Wings Over Europe Strike Fighters;FreeTrack20;V160;;;1101;0088311857638A73BB7E00 +469;Flight Gear;FreeTrack20;V160;;;12901;01D5D896C66B030606E000 +466;Flight Simulator 2002;FreeTrack20;V160;;;2302;01D21F7650E254B4514B00 +467;Flight Simulator 2004;FreeTrack20;V160;;;2303;01D3E91BAAB385B2362E00 +468;Flight Simulator X;FreeTrack20;V160;;;2305;01D41C31F42FAF32603600 +137;FlightGear;FlightGear;V110;V;V4Friend;0;0089054E8839A02FAB2F00 +138;Flyboys / Warbirds;FreeTrack20;V160;;;1301;008ABB5BF72C8934AB2B00 +139;Flyer;FreeTrack20;V160;;;1650;008BD1C9F27826AE2CA500 +140;Flying Tigers;FreeTrack20;V160;;;7002;008C91D997F29A930B0200 +141;FlyingGuns;FreeTrack20;V160;;;14801;008D7A32A1A882BAA28A00 +142;Ford Racing 3;FreeTrack20;V160;;;6901;008E27D5047C2BA62F5800 +143;Free Falcon 4.0;FreeTrack20;V160;;;1901;008F157D78A3B962E55000 +144;Free Falcon 4.0: Allied Force;FreeTrack20;V160;;;8901;0090656DD6793CA9325900 +145;Free Falcon 5;FreeTrack20;V160;V;V4Friend;1902;00911038C3AAB32590E900 +146;FreeSpace2;FreeTrack20;V160;;;13302;0092C8CDF8C2EA63496300 +147;FTAlpha;FreeTrack20;V160;;;20270;00936C69677F1D772AA900 +149;Full Out;FreeTrack20;V160;;;1701;009527D5047C31A0375800 +150;Future Pinball;FreeTrack20;V160;V;V4Friend;13101;00969343487E42B541AA00 +151;Game VR;FreeTrack20;V160;;;20325;009756BA018030B0355500 +152;GameLab;FreeTrack20;V160;;;20555;00985485D891DB23092200 +472;Games Farm;FreeTrack20;V160;;;3250;01D875C0981E627E5C7600 +153;Gamma;FreeTrack20;V160;;;1050;009921007D1B9D38A76F00 503;Garry's Mod;FreeTrack20;V160;;;12503;01F74EEB71FA7F37856900 -483;Generic Robotics;FreeTrack20;V160;;;20750;01E3FE7B4F05872A415400
-475;Glider Sim;FreeTrack20;V160;;;20720;01DB42130C4B0620871C00
-154;Global Ground Support Deicing Simulation;FreeTrack20;V160;;;20330;009ACFE709237A3AA11F00
-155;GosNIIAS Sim Trainer;FreeTrack20;V160;;;20355;009BB78B06EC8A2DB81800
-156;Gothic 3;FreeTrack20;V160;;;14401;009C37971697B36AD32A00
-157;Grand Prix Legends;FreeTrack20;V160;;;6701;009D521358D3D933B96E01
-158;Grand Theft Auto: San Andreas;FreeTrack20;V160;;;7808;009E5F3D95777D3BA23700
-159;GRID;FreeTrack20;V160;V;LeapoEclipse ;8105;009FD8175F8D1D7C0D3800
-160;GSE Power Plant Simulation;FreeTrack20;V160;;;20044;00A0432C28C217BEF93300
-161;GT Legends;FreeTrack20;V160;V;TrickyDee ;3902;00A116BC08020581CA8200
-162;GTR;FreeTrack20;V160;;;3901;00A2FD6BFE39A881B85B00
-163;GTR2 EVO;FreeTrack20;V160;V;zild1221 ;0;00A34B0FC37B2198F96300
-164;Gun Commander;FreeTrack20;V160;;;2675;00A4E2D1D77E319FEE8600
-165;Half Life 2;FreeTrack20;V160;;;7806;00A556BA018130AF365500
-166;Halo;FreeTrack20;V160;;;3801;00A656BA018130AF3F9C00
+483;Generic Robotics;FreeTrack20;V160;;;20750;01E3FE7B4F05872A415400 +475;Glider Sim;FreeTrack20;V160;;;20720;01DB42130C4B0620871C00 +154;Global Ground Support Deicing Simulation;FreeTrack20;V160;;;20330;009ACFE709237A3AA11F00 +155;GosNIIAS Sim Trainer;FreeTrack20;V160;;;20355;009BB78B06EC8A2DB81800 +156;Gothic 3;FreeTrack20;V160;;;14401;009C37971697B36AD32A00 +157;Grand Prix Legends;FreeTrack20;V160;;;6701;009D521358D3D933B96E01 +158;Grand Theft Auto: San Andreas;FreeTrack20;V160;;;7808;009E5F3D95777D3BA23700 +159;GRID;FreeTrack20;V160;V;LeapoEclipse ;8105;009FD8175F8D1D7C0D3800 +160;GSE Power Plant Simulation;FreeTrack20;V160;;;20044;00A0432C28C217BEF93300 +161;GT Legends;FreeTrack20;V160;V;TrickyDee ;3902;00A116BC08020581CA8200 +162;GTR;FreeTrack20;V160;;;3901;00A2FD6BFE39A881B85B00 +163;GTR2 EVO;FreeTrack20;V160;V;zild1221 ;0;00A34B0FC37B2198F96300 +164;Gun Commander;FreeTrack20;V160;;;2675;00A4E2D1D77E319FEE8600 +520;H1Z1;FreeTrack20;V170;;;6004;1774F090B1BA9E782D0800 +165;Half Life 2;FreeTrack20;V160;;;7806;00A556BA018130AF365500 +166;Halo;FreeTrack20;V160;;;3801;00A656BA018130AF3F9C00 502;hapTEL;FreeTrack20;V160;;;20805;01F63ADE510A20446B6A00 -167;Hardware Control Simulator, Railway Electronics;FreeTrack20;V160;;;20705;00A7F3E85B1A8930B42F00
-168;Harrier Attack II;FreeTrack20;V160;;;1175;00A8F2F27A57D20A940900
+167;Hardware Control Simulator Railway Electronics;FreeTrack20;V160;;;20705;00A7F3E85B1A8930B42F00 +168;Harrier Attack II;FreeTrack20;V160;;;1175;00A8F2F27A57D20A940900 499;Harry's Hard Choices Interactive;FreeTrack20;V160;;;20800;01F33A21BAE3DB6D48A000 -169;HAWX;FreeTrack20;V160;V;EmBeES ;0;00A9D615A9C8B088717000
-170;Herissons (Paris France);FreeTrack20;V160;;;20001;00AAEA1CBED8C20B430B00
-171;HOBI;FreeTrack20;V160;;;20335;00ABB253777F1779168900
-172;HoverAssault;FreeTrack20;V160;;;5303;00AC521358E3AA832A4000
-173;HPC;FreeTrack20;V160;;;20600;00AD0FC9FF8D0A7CEF9500
-174;HPG Tracking;FreeTrack20;V160;;;20255;00AE0288A1879D98930900
-175;HTW;FreeTrack20;V160;;;20630;00AF26F797911901C22C00
-176;Huawei Software;FreeTrack20;V160;;;20660;00B04655E8030A733AB300
-177;HueSpace;FreeTrack20;V160;;;20510;00B1231517C44960FB6300
-178;Hyper Vision;FreeTrack20;V160;;;15101;00B2DB242B657D43B32300
-179;iAmFootball;FreeTrack20;V160;;;1250;00B3B59DEFAAAFDB301A00
-180;id Research;FreeTrack20;V170;;;2950;00B4E723B873D7FC87D700
-181;IESA;FreeTrack20;V160;;;20037;00B5157D78D0E840AD7100
-182;IL-2 Cliffs of Dover;FreeTrack20;V160;V;V4Friend;0;00B6282282095F00521000
-183;IL-2 Forgotten Battles, ACE, Pacific Fighters;FreeTrack20;V160;V;Glenn;1001;00B722FD79137100621100
-484;IL-2 Sturmovik: Battle of Stalingrad;FreeTrack20;V170;;;1008;03F04D5368D1FD2DF2AE00
-184;Illumina;FreeTrack20;V160;;;1350;00B8054E8B39A33DB02400
-185;ILP;FreeTrack20;V160;;;20310;00B9F07957801789C9A600
-186;Imagine 3D ATC Tower Simulation;FreeTrack20;V160;;;20032;00BAEF7A8F4B8812B95300
-187;In Touch Technologies Inc.;FreeTrack20;V160;;;20006;00BB84817A3A5124B23D00
-188;Inglobe;FreeTrack20;V160;;;20360;00BCE7A7FAA27B2DA82700
-189;Innovatec Simulator;FreeTrack20;V160;;;20036;00BD22FD7935B23DB82C00
-190;Insurgency;FreeTrack20;V160;;;9401;00BEB6C61427B3EA744B00
-191;Intific;FreeTrack20;V160;;;20655;00BF2BCA747F2AA8309D00
-192;iRacing;FreeTrack20;V160;V;vn88holden ;14101;00C0103AF1AA730A236900
-193;IREQ Robotic Camera Control;FreeTrack20;V160;;;20027;00C10448E0E8618521EB00
-194;ISIC;FreeTrack20;V160;;;20680;00C2DEE3582F8F217E0B00
+169;HAWX;FreeTrack20;V160;V;EmBeES ;0;00A9D615A9C8B088717000 +170;Herissons (Paris France);FreeTrack20;V160;;;20001;00AAEA1CBED8C20B430B00 +523;hiCRANE2;FreeTrack20;V160;;;20835;020BA8FC8C7DFFA1381A00 +171;HOBI;FreeTrack20;V160;;;20335;00ABB253777F1779168900 +172;HoverAssault;FreeTrack20;V160;;;5303;00AC521358E3AA832A4000 +173;HPC;FreeTrack20;V160;;;20600;00AD0FC9FF8D0A7CEF9500 +174;HPG Tracking;FreeTrack20;V160;;;20255;00AE0288A1879D98930900 +175;HTW;FreeTrack20;V160;;;20630;00AF26F797911901C22C00 +176;Huawei Software;FreeTrack20;V160;;;20660;00B04655E8030A733AB300 +177;HueSpace;FreeTrack20;V160;;;20510;00B1231517C44960FB6300 +178;Hyper Vision;FreeTrack20;V160;;;15101;00B2DB242B657D43B32300 +179;iAmFootball;FreeTrack20;V160;;;1250;00B3B59DEFAAAFDB301A00 +180;id Research;FreeTrack20;V170;;;2950;00B4E723B873D7FC87D700 +181;IESA;FreeTrack20;V160;;;20037;00B5157D78D0E840AD7100 +182;IL-2 Cliffs of Dover;FreeTrack20;V160;V;V4Friend;0;00B6282282095F00521000 +183;IL-2 Forgotten Battles ACE Pacific Fighters;FreeTrack20;V160;V;Glenn;1001;00B722FD79137100621100 +484;IL-2 Sturmovik: Battle of Stalingrad;FreeTrack20;V170;;;1008;03F04D5368D1FD2DF2AE00 +184;Illumina;FreeTrack20;V160;;;1350;00B8054E8B39A33DB02400 +185;ILP;FreeTrack20;V160;;;20310;00B9F07957801789C9A600 +186;Imagine 3D ATC Tower Simulation;FreeTrack20;V160;;;20032;00BAEF7A8F4B8812B95300 +187;In Touch Technologies Inc.;FreeTrack20;V160;;;20006;00BB84817A3A5124B23D00 +188;Inglobe;FreeTrack20;V160;;;20360;00BCE7A7FAA27B2DA82700 +189;Innovatec Simulator;FreeTrack20;V160;;;20036;00BD22FD7935B23DB82C00 +190;Insurgency;FreeTrack20;V160;;;9401;00BEB6C61427B3EA744B00 +191;Intific;FreeTrack20;V160;;;20655;00BF2BCA747F2AA8309D00 +192;iRacing;FreeTrack20;V160;V;vn88holden ;14101;00C0103AF1AA730A236900 +193;IREQ Robotic Camera Control;FreeTrack20;V160;;;20027;00C10448E0E8618521EB00 +194;ISIC;FreeTrack20;V160;;;20680;00C2DEE3582F8F217E0B00 506;ITCL;FreeTrack20;V160;;;20820;01FAD19412681DC9CC6100 -195;IVD Online;FreeTrack20;V160;;;20535;00C390B57E1D7DDD883D00
-196;J.J. Keller and Associates;FreeTrack20;V160;;;20002;00C4E482F57FE77CF46300
-197;Janes F18;FreeTrack20;V160;;;9001;00C55F3D9577802AAF2E00
-198;Javal Ent.;FreeTrack20;V160;;;2650;00C622FD7A28BA2FAEEA00
-199;JC Demo;FreeTrack20;V160;;;20470;00C70AC67B0A630D9B3900
-200;Jet Thunder;FreeTrack20;V160;;;4501;00C82100801FA4EA9A3500
-201;Jetfighter V;FreeTrack20;V160;;;2501;00C9F52E42217B33A63200
-202;JFIST;FreeTrack20;V160;;;20560;00CAC932727C0F8D208600
-203;John Deere Vehicle Simulator;FreeTrack20;V160;;;20175;00CB29DFA8D3FA92A66000
-204;Jump to Lightspeed;FreeTrack20;V160;;;6001;00CCC166C8D3FA12E52400
-205;Jumpgate;FreeTrack20;V160;;;15001;00CD26F797B32A63E99200
-206;Jumpgate Evolution;FreeTrack20;V170;;;15002;00CE5936D4F93DCE0CE700
-207;KAF Keymapper;FreeTrack20;V160;;;3101;00CF934348830E87EB8300
-476;KAI FLight Simulator;FreeTrack20;V160;;;20725;01DCC522132A5C01EDE500
-208;Key Macro View;FreeTrack20;V160;;;12001;00D016BC08431B1EF90100
-209;kiwi.vg;FreeTrack20;V160;;;20395;00D1409A430AB33633E900
-210;L-3;FreeTrack20;V160;;;20465;00D2F885EFA8DE67878B00
-211;L-3 Communications;FreeTrack20;V160;;;20051;00D3D6E585F92F765E7800
-212;Lionhead MGS Game Research;FreeTrack20;V160;;;15301;00D4C1BBF9227B238AE200
-213;Live For Speed;FreeTrack20;V160;V;zild1221 ;7101;00D528228526A833521300
-214;Live for Speed S2;FreeTrack20;V160;;;11601;00D63752FBC8235B923500
-218;Lock-On: Modern Air Combat;FreeTrack20;V160;;;1002;00DAAC156D903C993B6200
-215;Lockheed Martin Littoral Combat Ship simulator;FreeTrack20;V160;;;20025;00D771ED5E802A9827A000
-216;Lockheed Martin Prepar3D;SimConnect;V130;V;elelbe ;0;00D8D615A9C8F36932AA00
-217;LockOn: Flaming Cliffs 2;FreeTrack20;V170;V;EmBeES ;1005;00D9AFB0D279F3A6F72200
-219;London NHS;FreeTrack20;V160;;;20640;00DB2E2023832BA123A100
-220;Lore (Dark Horizons);FreeTrack20;V160;;;5302;00DCF478D27833DB62D500
-221;Love;FreeTrack20;V160;;;3125;00DD71ED5E802AAB214800
-222;Lucid Engine;FreeTrack20;V160;;;10501;00DE71ED5E803098259C00
+195;IVD Online;FreeTrack20;V160;;;20535;00C390B57E1D7DDD883D00 +196;J.J. Keller and Associates;FreeTrack20;V160;;;20002;00C4E482F57FE77CF46300 +197;Janes F18;FreeTrack20;V160;;;9001;00C55F3D9577802AAF2E00 +198;Javal Ent.;FreeTrack20;V160;;;2650;00C622FD7A28BA2FAEEA00 +199;JC Demo;FreeTrack20;V160;;;20470;00C70AC67B0A630D9B3900 +200;Jet Thunder;FreeTrack20;V160;;;4501;00C82100801FA4EA9A3500 +201;Jetfighter V;FreeTrack20;V160;;;2501;00C9F52E42217B33A63200 +202;JFIST;FreeTrack20;V160;;;20560;00CAC932727C0F8D208600 +203;John Deere Vehicle Simulator;FreeTrack20;V160;;;20175;00CB29DFA8D3FA92A66000 +204;Jump to Lightspeed;FreeTrack20;V160;;;6001;00CCC166C8D3FA12E52400 +205;Jumpgate;FreeTrack20;V160;;;15001;00CD26F797B32A63E99200 +206;Jumpgate Evolution;FreeTrack20;V170;;;15002;00CE5936D4F93DCE0CE700 +207;KAF Keymapper;FreeTrack20;V160;;;3101;00CF934348830E87EB8300 +476;KAI FLight Simulator;FreeTrack20;V160;;;20725;01DCC522132A5C01EDE500 +208;Key Macro View;FreeTrack20;V160;;;12001;00D016BC08431B1EF90100 +209;kiwi.vg;FreeTrack20;V160;;;20395;00D1409A430AB33633E900 +521;Kongsberg GlobalSim;FreeTrack20;V160;;;20825;0209B2C573D990BF764700 +210;L-3;FreeTrack20;V160;;;20465;00D2F885EFA8DE67878B00 +211;L-3 Communications;FreeTrack20;V160;;;20051;00D3D6E585F92F765E7800 +522;LG Electronics;FreeTrack20;V160;;;20830;020A3678F5833D513DCA00 +212;Lionhead MGS Game Research;FreeTrack20;V160;;;15301;00D4C1BBF9227B238AE200 +213;Live For Speed;FreeTrack20;V160;V;zild1221 ;7101;00D528228526A833521300 +214;Live for Speed S2;FreeTrack20;V160;;;11601;00D63752FBC8235B923500 +218;Lock-On: Modern Air Combat;FreeTrack20;V160;;;1002;00DAAC156D903C993B6200 +215;Lockheed Martin Littoral Combat Ship simulator;FreeTrack20;V160;;;20025;00D771ED5E802A9827A000 +216;Lockheed Martin Prepar3D;SimConnect;V130;V;elelbe ;0;00D8D615A9C8F36932AA00 +217;LockOn: Flaming Cliffs 2;FreeTrack20;V170;V;EmBeES ;1005;00D9AFB0D279F3A6F72200 +219;London NHS;FreeTrack20;V160;;;20640;00DB2E2023832BA123A100 +220;Lore (Dark Horizons);FreeTrack20;V160;;;5302;00DCF478D27833DB62D500 +221;Love;FreeTrack20;V160;;;3125;00DD71ED5E802AAB214800 +222;Lucid Engine;FreeTrack20;V160;;;10501;00DE71ED5E803098259C00 514;M4 Tank Brigade;FreeTrack20;V160;;;1308;02024ED5A3A26741604300 -223;M4 Tank Platoon;FreeTrack20;V160;;;1306;00DFDCC441A8E036320900
-224;Mach 1;FreeTrack20;V160;;;2575;00E0231518130942466000
-225;ManuVAR;FreeTrack20;V160;;;20455;00E153FE1E901CB0448800
-226;MaqSIM4;FreeTrack20;V160;;;20026;00E28F54A207D29B611700
-227;Mech Tactical Sim;FreeTrack20;V160;;;9501;00E3F3E85B1A8E34A53300
+223;M4 Tank Platoon;FreeTrack20;V160;;;1306;00DFDCC441A8E036320900 +224;Mach 1;FreeTrack20;V160;;;2575;00E0231518130942466000 +225;ManuVAR;FreeTrack20;V160;;;20455;00E153FE1E901CB0448800 +226;MaqSIM4;FreeTrack20;V160;;;20026;00E28F54A207D29B611700 +227;Mech Tactical Sim;FreeTrack20;V160;;;9501;00E3F3E85B1A8E34A53300 +228;Mechwarrior Online;FreeTrack20;V170;;;3025;00E414954226DB5D8CE200 516;MechWarrior Online;FreeTrack20;V170;;;3026;0BD2E0DCBC723836CD2400 -228;Mechwarrior Online;FreeTrack20;V170;;;3025;00E414954226DB5D8CE200
-229;Medical Image Visualization;FreeTrack20;V160;;;20295;00E59343488532A5359B00
-230;Meggitt Defense Systems;FreeTrack20;V160;;;20045;00E6926ED9122AB22AF300
-231;MetaVR;FreeTrack20;V160;;;20545;00E7C5BEE48120A8308800
-232;Meteoroid Maze;FreeTrack20;V160;;;13003;00E8F079578430AD2EB200
-233;MeVEA;FreeTrack20;V160;;;2250;00E9D24C3F933289028700
-234;Micro Flight;FreeTrack20;V160;V;V4Friend;5101;00EABA89D078439932EA00
-235;Microsoft ESP;FreeTrack20;V160;;;2306;00EB0AC67E30A63BA53F00
-236;Microsoft Flight;FreeTrack20;V170;V;V4Friend;2307;00ECAFBC54959539C51500
-237;Microsoft Flight Simulator 3;FreeTrack20;V160;V;V4Friend;0;00ED5909437D36963EA810
-238;Microsoft FS2002/2004;FSUIPC;V130;V;V4Friend;0;00EE44958F34992CB43A00
-239;Microsoft FSX;SimConnect;V130;V;V4Friend;0;00EFF478D278437A73AA00
-240;Microsoft Train Simulator;FreeTrack20;V160;;;7805;00F00449225A439A13FB00
-494;MiddleVR;FreeTrack20;V160;;;20785;01EE1227DF43CA90C26100
-241;Mig Alley;FreeTrack20;V160;;;1501;00F17686E5A83289CDA700
-242;Mimik Vehicle Simulator;FreeTrack20;V160;;;20585;00F2AB1D58A8E35A531A00
-243;Miner Wars;FreeTrack20;V160;;;2550;00F3C5BEE48124A234A400
-244;MKMapper Keymapper;FreeTrack20;V160;;;2201;00F487801A8E14822EA200
-245;ModelSim;FreeTrack20;V160;;;20540;00F544958F3A9A1FB11A00
-246;Morgan State University;FreeTrack20;V160;;;20010;00F65909437D3CA5339A00
-247;Motor Company;FreeTrack20;V160;;;11501;00F70288F37A629A7DD700
-248;Motorsport Simulators;FreeTrack20;V160;;;4201;00F8F52E42217E3DA63B00
-249;Mouse Emulation;FreeTrack20;V160;;;8501;00F9950F9A8E29B93A9700
-250;MS World Tour Kart 2004;FreeTrack20;V160;;;6601;00FA9F819CA27F10591600
-251;MSN Virtual Earth;FreeTrack20;V160;;;2309;00FBF47CC37842091DC900
-252;mTBI Balance;FreeTrack20;V160;;;20420;00FC72456F9E0E78145800
-253;NASA Crew Exploration Vehicle;FreeTrack20;V160;;;20017;00FD028900985FA5501A00
-254;NASCAR Heat;FreeTrack20;V160;;;2602;00FE311857E10880B84100
-255;NASCAR Racing 2003 season;FreeTrack20;V160;;;7804;00FFDE661F6D920B87FC10
-256;NASCAR SimRacing;FreeTrack20;V160;;;6201;01004098708870D761A500
-257;NecroVisioN;FreeTrack20;V160;;;15601;0101621E77F2EA830A8100
-258;NetKar Pro;FreeTrack20;V160;V;sosna1983 ;10901;01028C3958334A5169A300
-259;Nitro Stunt Racing;FreeTrack20;V160;;;13901;0103C0AF9428B82DA5ED00
-260;North Eastern University;FreeTrack20;V160;;;20003;0104A2AE4823BB7449DE00
-261;Novint;FreeTrack20;V160;;;2725;01051C76F8137B823A4300
-262;NVH Sound Simulator;FreeTrack20;V160;;;20695;010655A2AA93158DDE9500
-479;OHJCH;FreeTrack20;V160;;;20740;01DF992E6C0DA43A703600
-263;OMSI Bus Simulator;FreeTrack20;V160;V;Thiago ;2225;0107F47CC37861A9606600
-264;Onadime - Realtime Animation;FreeTrack20;V160;;;20049;010853FE1E9229A3339B00
-265;Open Falcon 4.5;FreeTrack20;V160;V;muplex ;0;0109B1C664832D9B385500
-266;Operation Air Assault 2;FreeTrack20;V160;;;5401;010ABB5BF72C9238973B00
-267;Operation Flashpoint 2 (inactive);FreeTrack20;V160;;;7601;010BD1C9F2812A9A399400
-268;Operation Flashpoint(r): Dragon Rising(tm);FreeTrack20;V170;;;8106;010C3328780E1322676100
-269;OptiMetrics;FreeTrack20;V160;;;20011;010D55A2AA942FB9288F00
-270;OpusFSX;FreeTrack20;V160;;;3175;010E1C76F8238B72D7C100
-271;Orbiter 2005 Plug-In;FreeTrack20;V160;;;10301;010F87801A903B9736A600
-272;Orbiter 2006;FreeTrack20;V160;V;Ripley;10303;0110D24C3F953F9526BA00
-273;Orbiter 2006 Plug-In;FreeTrack20;V160;;;10302;0111054E913F9931B72000
-274;Oryx Vehicle Simulators;FreeTrack20;V160;;;20028;0112C8CDF952EBA4763100
-275;Outer Conflict: Frontiers;FreeTrack20;V160;;;1900;01136C6967883EAA23AB00
-276;Over Flanders Fields;FreeTrack20;V160;V;Summelar ;2325;0114A59E68873E9B315210
-277;PanoPro;FreeTrack20;V160;;;20525;0115B6C61428231A23E900
-278;Paraworld;FreeTrack20;V160;;;14501;0116656DD6832BB62EB000
-279;Phoenix R/C;FreeTrack20;V160;;;3075;0117B6C61428238A334B00
-280;Pivot Maritime;FreeTrack20;V160;;;20365;01187686E5A8628AB2AA00
-281;PlanetSide 2;FreeTrack20;V170;;;6002;0119BB34B53FDC5C5AAF00
-474;PlanetSide 2 M.E.;FreeTrack20;V160;;;6003;01DA321EF31DA48C159A00
-282;Pointman;FreeTrack20;V160;;;7525;011ACFE70923833D9B2B00
-283;Power Driving Simulator;FreeTrack20;V160;;;20675;011BB78B06EC932DBC2F00
-470;Prepar3D;FreeTrack20;V160;;;20440;01D6DA768CE8AA43D8DC00
-284;Priston Tale;FreeTrack20;V160;;;9701;011C849F9642A030AC3600
-285;Project Reality (BF2 Mod);FreeTrack20;V160;;;9201;011D3C2C1C922CB239A800
-286;Project Torque (Invictus);FreeTrack20;V160;;;4802;011E612F28540B52797100
-287;Project X;FreeTrack20;V160;;;20022;011FE9D85E4842DA439900
-288;Quanser;FreeTrack20;V160;;;20435;0120950F9A922FA535A500
-289;QuantaDyn;FreeTrack20;V160;;;20575;012199BB5C9433A739B600
-290;Quest 3D Xframe Plugin;FreeTrack20;V160;;;20043;0122FD6BFE39A923C98200
-291;Quest3D;FreeTrack20;V160;;;1425;01234B0FC38542AB3BB700
-292;Quest3D - CINEACT integration;FreeTrack20;V160;;;20040;0124A15F28340AB3CA9000
-303;R-concept X (AdrenalinStorm);FreeTrack20;V160;;;9101;012F72456F83E6993AA600
-293;R.U.D.O. Tools;FreeTrack20;V160;;;20039;0125612F287FB9BEA76E00
-294;RACE (the WTCC game);FreeTrack20;V160;;;3904;01263C2C1C94FA86146300
-295;RACE 07, RACE, GTR 2;FreeTrack20;V160;V;zild1221, TrickyDee ;3903;0127C0AF9800870056FD00
-296;RaceOn;FreeTrack20;V160;V;zild1221 ;0;0128621E7832AA82388200
-297;Racer;FreeTrack20;V160;;;2401;01296D2D103862E932EA00
-298;Racer S;FreeTrack20;V160;;;20030;012AEA1CBED961CA52CB00
-490;RaceRoom Racing Experience;FreeTrack20;V160;;;3905;01EA9124F663AF03BBC500
-299;Rail Simulator 1;FreeTrack20;V160;;;1550;012BB253778929A0395900
-300;Railway Work Simulator;FreeTrack20;V160;;;20225;012C91D998B1E9933B9100
-301;RailWorks 2;FreeTrack20;V160;;;2750;012D3919C4972D9D299000
+229;Medical Image Visualization;FreeTrack20;V160;;;20295;00E59343488532A5359B00 +230;Meggitt Defense Systems;FreeTrack20;V160;;;20045;00E6926ED9122AB22AF300 +231;MetaVR;FreeTrack20;V160;;;20545;00E7C5BEE48120A8308800 +232;Meteoroid Maze;FreeTrack20;V160;;;13003;00E8F079578430AD2EB200 +233;MeVEA;FreeTrack20;V160;;;2250;00E9D24C3F933289028700 +234;Micro Flight;FreeTrack20;V160;V;V4Friend;5101;00EABA89D078439932EA00 +235;Microsoft ESP;FreeTrack20;V160;;;2306;00EB0AC67E30A63BA53F00 +236;Microsoft Flight;FreeTrack20;V170;V;V4Friend;2307;00ECAFBC54959539C51500 +237;Microsoft Flight Simulator 3;FreeTrack20;V160;V;V4Friend;0;00ED5909437D36963EA810 +238;Microsoft FS2002/2004;FSUIPC;V130;V;V4Friend;0;00EE44958F34992CB43A00 +239;Microsoft FSX;SimConnect;V130;V;V4Friend;0;00EFF478D278437A73AA00 +240;Microsoft Train Simulator;FreeTrack20;V160;;;7805;00F00449225A439A13FB00 +494;MiddleVR;FreeTrack20;V160;;;20785;01EE1227DF43CA90C26100 +241;Mig Alley;FreeTrack20;V160;;;1501;00F17686E5A83289CDA700 +242;Mimik Vehicle Simulator;FreeTrack20;V160;;;20585;00F2AB1D58A8E35A531A00 +243;Miner Wars;FreeTrack20;V160;;;2550;00F3C5BEE48124A234A400 +244;MKMapper Keymapper;FreeTrack20;V160;;;2201;00F487801A8E14822EA200 +245;ModelSim;FreeTrack20;V160;;;20540;00F544958F3A9A1FB11A00 +246;Morgan State University;FreeTrack20;V160;;;20010;00F65909437D3CA5339A00 +247;Motor Company;FreeTrack20;V160;;;11501;00F70288F37A629A7DD700 +248;Motorsport Simulators;FreeTrack20;V160;;;4201;00F8F52E42217E3DA63B00 +249;Mouse Emulation;FreeTrack20;V160;;;8501;00F9950F9A8E29B93A9700 +250;MS World Tour Kart 2004;FreeTrack20;V160;;;6601;00FA9F819CA27F10591600 +251;MSN Virtual Earth;FreeTrack20;V160;;;2309;00FBF47CC37842091DC900 +252;mTBI Balance;FreeTrack20;V160;;;20420;00FC72456F9E0E78145800 +253;NASA Crew Exploration Vehicle;FreeTrack20;V160;;;20017;00FD028900985FA5501A00 +254;NASCAR Heat;FreeTrack20;V160;;;2602;00FE311857E10880B84100 +255;NASCAR Racing 2003 season;FreeTrack20;V160;;;7804;00FFDE661F6D920B87FC10 +256;NASCAR SimRacing;FreeTrack20;V160;;;6201;01004098708870D761A500 +257;NecroVisioN;FreeTrack20;V160;;;15601;0101621E77F2EA830A8100 +258;NetKar Pro;FreeTrack20;V160;V;sosna1983 ;10901;01028C3958334A5169A300 +259;Nitro Stunt Racing;FreeTrack20;V160;;;13901;0103C0AF9428B82DA5ED00 +260;North Eastern University;FreeTrack20;V160;;;20003;0104A2AE4823BB7449DE00 +261;Novint;FreeTrack20;V160;;;2725;01051C76F8137B823A4300 +262;NVH Sound Simulator;FreeTrack20;V160;;;20695;010655A2AA93158DDE9500 +479;OHJCH;FreeTrack20;V160;;;20740;01DF992E6C0DA43A703600 +263;OMSI Bus Simulator;FreeTrack20;V160;V;Thiago ;2225;0107F47CC37861A9606600 +264;Onadime - Realtime Animation;FreeTrack20;V160;;;20049;010853FE1E9229A3339B00 +265;Open Falcon 4.5;FreeTrack20;V160;V;muplex ;0;0109B1C664832D9B385500 +266;Operation Air Assault 2;FreeTrack20;V160;;;5401;010ABB5BF72C9238973B00 +267;Operation Flashpoint 2 (inactive);FreeTrack20;V160;;;7601;010BD1C9F2812A9A399400 +268;Operation Flashpoint(r): Dragon Rising(tm);FreeTrack20;V170;;;8106;010C3328780E1322676100 +269;OptiMetrics;FreeTrack20;V160;;;20011;010D55A2AA942FB9288F00 +270;OpusFSX;FreeTrack20;V160;;;3175;010E1C76F8238B72D7C100 +271;Orbiter 2005 Plug-In;FreeTrack20;V160;;;10301;010F87801A903B9736A600 +272;Orbiter 2006;FreeTrack20;V160;V;Ripley;10303;0110D24C3F953F9526BA00 +273;Orbiter 2006 Plug-In;FreeTrack20;V160;;;10302;0111054E913F9931B72000 +274;Oryx Vehicle Simulators;FreeTrack20;V160;;;20028;0112C8CDF952EBA4763100 +275;Outer Conflict: Frontiers;FreeTrack20;V160;;;1900;01136C6967883EAA23AB00 +276;Over Flanders Fields;FreeTrack20;V160;V;Summelar ;2325;0114A59E68873E9B315210 +277;PanoPro;FreeTrack20;V160;;;20525;0115B6C61428231A23E900 +278;Paraworld;FreeTrack20;V160;;;14501;0116656DD6832BB62EB000 +279;Phoenix R/C;FreeTrack20;V160;;;3075;0117B6C61428238A334B00 +280;Pivot Maritime;FreeTrack20;V160;;;20365;01187686E5A8628AB2AA00 +281;PlanetSide 2;FreeTrack20;V170;;;6002;0119BB34B53FDC5C5AAF00 +474;PlanetSide 2 M.E.;FreeTrack20;V160;;;6003;01DA321EF31DA48C159A00 +282;Pointman;FreeTrack20;V160;;;7525;011ACFE70923833D9B2B00 +283;Power Driving Simulator;FreeTrack20;V160;;;20675;011BB78B06EC932DBC2F00 +470;Prepar3D;FreeTrack20;V160;;;20440;01D6DA768CE8AA43D8DC00 +284;Priston Tale;FreeTrack20;V160;;;9701;011C849F9642A030AC3600 +285;Project Reality (BF2 Mod);FreeTrack20;V160;;;9201;011D3C2C1C922CB239A800 +286;Project Torque (Invictus);FreeTrack20;V160;;;4802;011E612F28540B52797100 +287;Project X;FreeTrack20;V160;;;20022;011FE9D85E4842DA439900 +288;Quanser;FreeTrack20;V160;;;20435;0120950F9A922FA535A500 +289;QuantaDyn;FreeTrack20;V160;;;20575;012199BB5C9433A739B600 +290;Quest 3D Xframe Plugin;FreeTrack20;V160;;;20043;0122FD6BFE39A923C98200 +291;Quest3D;FreeTrack20;V160;;;1425;01234B0FC38542AB3BB700 +292;Quest3D - CINEACT integration;FreeTrack20;V160;;;20040;0124A15F28340AB3CA9000 +303;R-concept X (AdrenalinStorm);FreeTrack20;V160;;;9101;012F72456F83E6993AA600 +293;R.U.D.O. Tools;FreeTrack20;V160;;;20039;0125612F287FB9BEA76E00 +294;RACE (the WTCC game);FreeTrack20;V160;;;3904;01263C2C1C94FA86146300 +295;RACE 07 RACE GTR 2;FreeTrack20;V160;V;zild1221 TrickyDee ;3903;0127C0AF9800870056FD00 +296;RaceOn;FreeTrack20;V160;V;zild1221 ;0;0128621E7832AA82388200 +297;Racer;FreeTrack20;V160;;;2401;01296D2D103862E932EA00 +298;Racer S;FreeTrack20;V160;;;20030;012AEA1CBED961CA52CB00 +490;RaceRoom Racing Experience;FreeTrack20;V160;;;3905;01EA9124F663AF03BBC500 +299;Rail Simulator 1;FreeTrack20;V160;;;1550;012BB253778929A0395900 +300;Railway Work Simulator;FreeTrack20;V160;;;20225;012C91D998B1E9933B9100 +301;RailWorks 2;FreeTrack20;V160;;;2750;012D3919C4972D9D299000 507;RailWorks 5 (TS2014);FreeTrack20;V160;;;1551;01FB8B5232CB1502C95A00 -302;Raydon Driving Simulator;FreeTrack20;V160;;;3701;012E5485D941DBE2FB5300
-304;Real Time Visual;FreeTrack20;V160;;;9901;0130B1C664862297365500
-305;RealFlight;FreeTrack20;V160;;;4001;0131AC6E87892E993A8B00
-306;Reality Manager;FreeTrack20;V160;;;20046;0132DB242B65872FA42A00
-307;RealWorld;FreeTrack20;V160;;;20215;0133B59DEFA9322A727800
-308;Red Baron 3D;FreeTrack20;V160;;;1125;0134C6371D96349CEB7A00
-309;Red Orchestra: Heroes of Stalingrad;FreeTrack20;V170;;;12602;013521F9121056CD997300
-310;Red Orchestra: Ostfront;FreeTrack20;V170;;;12601;01369A9A2BE97252BB9000
-311;Redline Monitor;FreeTrack20;V160;;;20210;01373752FBC8831A72AA00
-312;REFLEX XTR;FreeTrack20;V160;;;2150;0138054E94127D14881300
-313;Remote Presence;FreeTrack20;V160;;;20710;01399BC3BDA93229D2BB00
-314;rFactor;FreeTrack20;V160;V;V4Friend;7401;013AEF7A8F4B8AA0495200
-315;rFactor Pro;FreeTrack20;V170;;;7403;013B175198D74BE8E89600
-316;rFactor2;FreeTrack20;V170;;;7402;013CBFF3A86D34DA24C000
-317;Richard Burns Rally;FreeTrack20;V160;V;zild1221;3401;013D42868B339A31A73C10
-318;RidingStar;FreeTrack20;V160;;;1475;013E3919C497359826A700
-319;Rig N Roll;FreeTrack20;V160;;;9801;013FD1C9F284239CE68100
-320;Rio Tinto Resource Development;FreeTrack20;V160;;;20033;01401039831B5EC8D31900
-321;Rise of Flight;FreeTrack20;V160;V;Seborgarsen ;11401;0141AA71218335A51F5100
-322;Rise: The Vieneo Province;FreeTrack20;V160;;;6301;0142DEE3582F9837A82D00
-323;Rising Conflicts;FreeTrack20;V160;;;12101;014384818335A439B12F00
-492;RITS;FreeTrack20;V160;;;20775;01ECEE745B83DD3A0DBE00
-324;Road Legends;FreeTrack20;V160;;;1876;0144379716986369A2E600
-325;Rogue Space;FreeTrack20;V160;;;3050;014588F5872C9C30ABE900
-326;Rogue Warrior;FreeTrack20;V160;;;14202;0146432C2973D9D45A8E00
-327;ROV Sim;FreeTrack20;V160;;;20530;0147FA04BD27891D9ADD00
-328;Rowan's Battle Of Britain;FreeTrack20;V160;;;1502;014821008829A72CB4F300
-329;RSD Demo;FreeTrack20;V160;;;2050;0149BF8C4EAA5871A85D00
-330;RTMS Crane Sim;FreeTrack20;V160;;;20400;014AC93272841D91205200
-331;RTT DeltaGen Plugin;FreeTrack20;V160;;;20195;014B90B5871B8DDD7D3400
+302;Raydon Driving Simulator;FreeTrack20;V160;;;3701;012E5485D941DBE2FB5300 +304;Real Time Visual;FreeTrack20;V160;;;9901;0130B1C664862297365500 +305;RealFlight;FreeTrack20;V160;;;4001;0131AC6E87892E993A8B00 +306;Reality Manager;FreeTrack20;V160;;;20046;0132DB242B65872FA42A00 +307;RealWorld;FreeTrack20;V160;;;20215;0133B59DEFA9322A727800 +308;Red Baron 3D;FreeTrack20;V160;;;1125;0134C6371D96349CEB7A00 +309;Red Orchestra: Heroes of Stalingrad;FreeTrack20;V170;;;12602;013521F9121056CD997300 +310;Red Orchestra: Ostfront;FreeTrack20;V170;;;12601;01369A9A2BE97252BB9000 +311;Redline Monitor;FreeTrack20;V160;;;20210;01373752FBC8831A72AA00 +312;REFLEX XTR;FreeTrack20;V160;;;2150;0138054E94127D14881300 +313;Remote Presence;FreeTrack20;V160;;;20710;01399BC3BDA93229D2BB00 +314;rFactor;FreeTrack20;V160;V;V4Friend;7401;013AEF7A8F4B8AA0495200 +315;rFactor Pro;FreeTrack20;V170;;;7403;013B175198D74BE8E89600 +316;rFactor2;FreeTrack20;V170;;;7402;013CBFF3A86D34DA24C000 +317;Richard Burns Rally;FreeTrack20;V160;V;zild1221;3401;013D42868B339A31A73C10 +318;RidingStar;FreeTrack20;V160;;;1475;013E3919C497359826A700 +319;Rig N Roll;FreeTrack20;V160;;;9801;013FD1C9F284239CE68100 +320;Rio Tinto Resource Development;FreeTrack20;V160;;;20033;01401039831B5EC8D31900 +321;Rise of Flight;FreeTrack20;V160;V;Seborgarsen ;11401;0141AA71218335A51F5100 +322;Rise: The Vieneo Province;FreeTrack20;V160;;;6301;0142DEE3582F9837A82D00 +323;Rising Conflicts;FreeTrack20;V160;;;12101;014384818335A439B12F00 +492;RITS;FreeTrack20;V160;;;20775;01ECEE745B83DD3A0DBE00 +324;Road Legends;FreeTrack20;V160;;;1876;0144379716986369A2E600 +325;Rogue Space;FreeTrack20;V160;;;3050;014588F5872C9C30ABE900 +326;Rogue Warrior;FreeTrack20;V160;;;14202;0146432C2973D9D45A8E00 +327;ROV Sim;FreeTrack20;V160;;;20530;0147FA04BD27891D9ADD00 +328;Rowan's Battle Of Britain;FreeTrack20;V160;;;1502;014821008829A72CB4F300 +329;RSD Demo;FreeTrack20;V160;;;2050;0149BF8C4EAA5871A85D00 +330;RTMS Crane Sim;FreeTrack20;V160;;;20400;014AC93272841D91205200 +331;RTT DeltaGen Plugin;FreeTrack20;V160;;;20195;014B90B5871B8DDD7D3400 511;Sail;FreeTrack20;V160;;;3575;01FF2916D764159099F800 -332;Sail Simulator 5;FreeTrack20;V160;;;1975;014CE2D1D78A1D9A3B6300
-333;Sailors of the Sky;FreeTrack20;V160;;;10201;014D17BE02961FAF3AB100
-334;Santa Cruz Watermill;FreeTrack20;V160;;;20290;014E88F5881EA32FA7E900
-335;SCANeR Studio Plugin;FreeTrack20;V160;;;20445;014FA2AE4870F861E9A100
-336;SEGA Demo;FreeTrack20;V160;;;2075;015016BC08C117F1163000
-337;Seven-G;FreeTrack20;V160;;;2350;01510F00F49635B822A200
-338;SFSPC;FreeTrack20;V160;;;2801;0152F885EFA9400981B700
-339;Ship Simulator 2006;FreeTrack20;V160;;;5002;015329DFA9638AA2C66100
-340;Ship Simulator 2008;FreeTrack20;V160;V;djj3ff ;5003;01545213599339B3D52100
-341;Shiphandling Simulator;FreeTrack20;V160;;;20570;01553FD0FC9D8B37AD3700
-342;Shooting Simulator;FreeTrack20;V160;;;20047;0156F2F27A58827A63DA00
-343;SIA Games;FreeTrack20;V160;;;20015;0157926ED970685DA8D200
-344;Silent Wings;FreeTrack20;V160;;;8701;0158D615A9C96309C24A00
-345;SilverHat;FreeTrack20;V160;;;12401;0159D8175F99349F3F9600
-346;Simax Simulator;FreeTrack20;V160;;;20021;015AAC156D9736A331AD00
-347;Simball 4D;FreeTrack20;V160;;;20315;015BD6E585F99349F2AA00
-348;Simbionix;FreeTrack20;V160;;;20485;015CE7A7FAA28528AE1D00
+332;Sail Simulator 5;FreeTrack20;V160;;;1975;014CE2D1D78A1D9A3B6300 +333;Sailors of the Sky;FreeTrack20;V160;;;10201;014D17BE02961FAF3AB100 +334;Santa Cruz Watermill;FreeTrack20;V160;;;20290;014E88F5881EA32FA7E900 +335;SCANeR Studio Plugin;FreeTrack20;V160;;;20445;014FA2AE4870F861E9A100 +336;SEGA Demo;FreeTrack20;V160;;;2075;015016BC08C117F1163000 +337;Seven-G;FreeTrack20;V160;;;2350;01510F00F49635B822A200 +338;SFSPC;FreeTrack20;V160;;;2801;0152F885EFA9400981B700 +339;Ship Simulator 2006;FreeTrack20;V160;;;5002;015329DFA9638AA2C66100 +340;Ship Simulator 2008;FreeTrack20;V160;V;djj3ff ;5003;01545213599339B3D52100 +341;Shiphandling Simulator;FreeTrack20;V160;;;20570;01553FD0FC9D8B37AD3700 +342;Shooting Simulator;FreeTrack20;V160;;;20047;0156F2F27A58827A63DA00 +343;SIA Games;FreeTrack20;V160;;;20015;0157926ED970685DA8D200 +344;Silent Wings;FreeTrack20;V160;;;8701;0158D615A9C96309C24A00 +345;SilverHat;FreeTrack20;V160;;;12401;0159D8175F99349F3F9600 +346;Simax Simulator;FreeTrack20;V160;;;20021;015AAC156D9736A331AD00 +347;Simball 4D;FreeTrack20;V160;;;20315;015BD6E585F99349F2AA00 +348;Simbionix;FreeTrack20;V160;;;20485;015CE7A7FAA28528AE1D00 518;SimCraft;FreeTrack20;V160;;;3650;02065BA013963203CB1900 -349;SimCreator;FreeTrack20;V160;;;20520;015D3752FBC8935B001A00
-350;Simlog Personal Simulator;FreeTrack20;V160;;;20635;015E42868C33A435B53100
-351;SimQuest immersion system;FreeTrack20;V160;;;20023;015F6C69678C32A30FAE00
-352;SimSol;FreeTrack20;V160;;;20034;01602315187389E0FB5300
-491;Simumak;FreeTrack20;V160;;;20770;01EB119629980784DCE600
-510;Sir, You Are Being Hunted;FreeTrack20;V160;;;3550;01FEDAB345FA104ED4A100 -353;Sirocco Racing;FreeTrack20;V160;;;5801;01612BCA748925A6369A00
-354;Sky God: Military Freefall;FreeTrack20;V170;;;1526;01622C0104385FD1C44400
-355;Soft fx Demo;FreeTrack20;V160;;;2125;01632E20238A2B99335200
-356;Source Engine (Half-Life 2);FreeTrack20;V160;;;12502;0164E482F58829A739A600
-357;Space Shuttle Mission 2007;FreeTrack20;V160;V;purewhitewings ;1225;0165662B03863D912F9700
+349;SimCreator;FreeTrack20;V160;;;20520;015D3752FBC8935B001A00 +350;Simlog Personal Simulator;FreeTrack20;V160;;;20635;015E42868C33A435B53100 +351;SimQuest immersion system;FreeTrack20;V160;;;20023;015F6C69678C32A30FAE00 +352;SimSol;FreeTrack20;V160;;;20034;01602315187389E0FB5300 +491;Simumak;FreeTrack20;V160;;;20770;01EB119629980784DCE600 +510;Sir You Are Being Hunted;FreeTrack20;V160;;;3550;01FEDAB345FA104ED4A100 +353;Sirocco Racing;FreeTrack20;V160;;;5801;01612BCA748925A6369A00 +354;Sky God: Military Freefall;FreeTrack20;V170;;;1526;01622C0104385FD1C44400 +355;Soft fx Demo;FreeTrack20;V160;;;2125;01632E20238A2B99335200 +356;Source Engine (Half-Life 2);FreeTrack20;V160;;;12502;0164E482F58829A739A600 +357;Space Shuttle Mission 2007;FreeTrack20;V160;V;purewhitewings ;1225;0165662B03863D912F9700 517;Spaze;FreeTrack20;V160;;;3625;020573F9D3ED8C43B8DC00 -358;SRI;FreeTrack20;V160;;;20620;01663FD0FC9D8B218D8100
-359;Stanford University;FreeTrack20;V160;;;20004;0167CE35BAF9933A62AA00
+358;SRI;FreeTrack20;V160;;;20620;01663FD0FC9D8B218D8100 +359;Stanford University;FreeTrack20;V160;;;20004;0167CE35BAF9933A62AA00 500;Star Citizen;FreeTrack20;V170;;;3450;0D7AF4CE4E343EC6B4A200 -360;Starshatter;FreeTrack20;V160;;;6401;0168F079578A3F9A3BB600
-361;Steel Beasts 2;FreeTrack20;V160;;;11703;0169DCC441A9443A831A00
-362;Steel Beasts Pro;FreeTrack20;V160;;;11701;016A8F54A20833CAA23900
-363;Steel Beasts Pro Personal;FreeTrack20;V160;;;11702;016BF3E85B1A9443A73000
-364;Stoked Rider;FreeTrack20;V160;;;14701;016CC166C963EA32997300
-365;Storm of War: the Battle of Britain;FreeTrack20;V170;;;11001;016D8F54A68B71F25D0200
-495;STRAFT;FreeTrack20;V160;;;3375;01EF1329E014ADF98D6B00
-366;Stride;FreeTrack20;V170;;;2310;016EC784B21E4B21984400
-367;STS Driving Simulator;FreeTrack20;V160;;;20300;016FA59E688B1C89DE7600
-368;Sunaerosys;FreeTrack20;V160;;;20475;01700449831AF28973EB00
-369;Superkarting;FreeTrack20;V160;;;14903;0171DE661F6D973FA41F00
-370;SuperX Research;FreeTrack20;V160;;;15401;0172BA89D078A45A021A00
-371;SWRI Demo;FreeTrack20;V160;;;20230;01730AC6841E9512561000
-372;Syncon Robot Control;FreeTrack20;V160;;;20415;0174C1BBF9937B12DB5200
-373;Synergy Simulation;FreeTrack20;V160;;;20595;0175926ED9736B220B8200
-374;T and TS Corp.;FreeTrack20;V160;;;20005;017617BE0297DDA73CA600
-375;Take On Helicopters;FreeTrack20;V170;;;7504;0177513CB40C0623B96A00
-376;Target: Korea;FreeTrack20;V160;;;1201;0178F52E4221852FA43300
-377;Target: Rabaul;FreeTrack20;V160;;;1202;0179E9D85E4881CA736900
-378;Targeting Demo;FreeTrack20;V160;;;13002;017AAB1D58A952DAA2F900
-379;TD Demo;FreeTrack20;V160;;;1925;017BC5BEE488FE54139700
-489;TeachLive;FreeTrack20;V160;;;20765;01E905245B5AC5484FC100
-380;Telepresence;FreeTrack20;V160;;;20450;017CF478D278B33B02DA00
-381;Tenstar Simulator;FreeTrack20;V160;;;20605;017D318F88A2EA62DBA200
-382;Test Drive Unlimited;FreeTrack20;V160;;;13201;017E6F2699559730A84000
+360;Starshatter;FreeTrack20;V160;;;6401;0168F079578A3F9A3BB600 +361;Steel Beasts 2;FreeTrack20;V160;;;11703;0169DCC441A9443A831A00 +362;Steel Beasts Pro;FreeTrack20;V160;;;11701;016A8F54A20833CAA23900 +363;Steel Beasts Pro Personal;FreeTrack20;V160;;;11702;016BF3E85B1A9443A73000 +364;Stoked Rider;FreeTrack20;V160;;;14701;016CC166C963EA32997300 +365;Storm of War: the Battle of Britain;FreeTrack20;V170;;;11001;016D8F54A68B71F25D0200 +495;STRAFT;FreeTrack20;V160;;;3375;01EF1329E014ADF98D6B00 +366;Stride;FreeTrack20;V170;;;2310;016EC784B21E4B21984400 +367;STS Driving Simulator;FreeTrack20;V160;;;20300;016FA59E688B1C89DE7600 +368;Sunaerosys;FreeTrack20;V160;;;20475;01700449831AF28973EB00 +369;Superkarting;FreeTrack20;V160;;;14903;0171DE661F6D973FA41F00 +370;SuperX Research;FreeTrack20;V160;;;15401;0172BA89D078A45A021A00 +371;SWRI Demo;FreeTrack20;V160;;;20230;01730AC6841E9512561000 +372;Syncon Robot Control;FreeTrack20;V160;;;20415;0174C1BBF9937B12DB5200 +373;Synergy Simulation;FreeTrack20;V160;;;20595;0175926ED9736B220B8200 +374;T and TS Corp.;FreeTrack20;V160;;;20005;017617BE0297DDA73CA600 +375;Take On Helicopters;FreeTrack20;V170;;;7504;0177513CB40C0623B96A00 +376;Target: Korea;FreeTrack20;V160;;;1201;0178F52E4221852FA43300 +377;Target: Rabaul;FreeTrack20;V160;;;1202;0179E9D85E4881CA736900 +378;Targeting Demo;FreeTrack20;V160;;;13002;017AAB1D58A952DAA2F900 +379;TD Demo;FreeTrack20;V160;;;1925;017BC5BEE488FE54139700 +489;TeachLive;FreeTrack20;V160;;;20765;01E905245B5AC5484FC100 +380;Telepresence;FreeTrack20;V160;;;20450;017CF478D278B33B02DA00 +381;Tenstar Simulator;FreeTrack20;V160;;;20605;017D318F88A2EA62DBA200 +382;Test Drive Unlimited;FreeTrack20;V160;;;13201;017E6F2699559730A84000 509;Tetrahedral;FreeTrack20;V160;;;3525;01FDCFF1C56D6F757E8200 501;The Crew;FreeTrack20;V170;;;1009;03F1F534E94F4834D9B100 -488;The Gallery;FreeTrack20;V160;;;3350;01E8CE152EDE5FFD267700
-383;The Sky Gods;FreeTrack20;V170;;;1525;017FDFF782DCCEEA27C200
-384;theHunter;FreeTrack20;V170;;;2375;0180BFF3A86D34DA24C000
-385;thriXXX HII 3D;FreeTrack20;V160;;;13403;0181FA04BD27AB36B62700
-386;thriXXX Jenna;FreeTrack20;V160;;;13401;01829F819CA2A625AB2800
-387;ThriXXX Technology;FreeTrack20;V160;;;13402;0183F47CC378B35B526900
-388;tir2joy;FreeTrack20;V160;;;2202;018487801AB532A7FE9C00
-389;TIRF4;FreeTrack20;V160;;;2203;0185311858418870E77000
-390;TNO;FreeTrack20;V160;;;20285;01861AAF6870A853D64900
-391;ToCA Race Driver 2;FreeTrack20;V160;;;8102;0187FFE9E886F286297910
-392;Toca Race Driver 3;FreeTrack20;V160;;;8101;01884098D36972B551A900
-393;Tom Clancy's H.A.W.X.;FreeTrack20;V170;V;EmBeES ;1004;0189AA4D48E85966FBAA00
-394;Tom Clancy's H.A.W.X. 2;FreeTrack20;V170;;;1007;018A1B7583521C12406F00
-395;Torque Game Engine;FreeTrack20;V160;;;5301;018BC0AF9A2EB62CAB3300
-396;Total War;FreeTrack20;V160;;;1375;018C72456F8529AA2CA400
-397;Tower Crane Simulator;FreeTrack20;V160;;;20670;018D03FB9929B034A7D900
-398;Tower I;FreeTrack20;V160;;;1325;018E662B03873CA731A400
-399;TPL Testing;FreeTrack20;V160;;;20260;018F849F9A2083DC8C2C00
-400;trackd;FreeTrack20;V160;;;20580;019053FE1EB72DA3329D00
-401;TrackMapper2;FreeTrack20;V160;;;2175;0191CE35BAF9A31A61FA00
-402;TrainMaster;FreeTrack20;V160;;;20042;01925C1FDE852D9925B400
-403;Trainz;FreeTrack20;V160;;;4701;0193D1C9F2862C9630A100
-404;TraumTek;FreeTrack20;V160;;;20650;0194A2AE4883EA645A2100
-405;Turismo Carretera;FreeTrack20;V160;;;15801;01956F2699559740A73500
-406;UK Rally Champion;FreeTrack20;V160;;;5701;019679EC0E28B196522A00
-407;ULAN;FreeTrack20;V160;;;20645;01974ADE68E16780D97A00
-473;Underwater Navigation;FreeTrack20;V160;;;20715;01D9FE2B94FB03772DE200
-408;Unity 3D Plugin;FreeTrack20;V160;;;20430;0198D24C3F9B3B9C31BF00
-409;Untitled 10tacle;FreeTrack20;V160;;;13701;0199FFE9E886F28728AA00
-410;Untitled 3D People;FreeTrack20;V160;;;15501;019A6925968D38AD23A900
-411;Untitled Apportmedia;FreeTrack20;V160;;;6801;019B3C2C1C9728B738B700
-412;Untitled Combat Flight Sim;FreeTrack20;V160;;;13801;019CA59E688D36AA28A600
-413;Untitled Deep Silver;FreeTrack20;V160;;;14601;019D656DD68838B836AD00
-414;Untitled G5 Software;FreeTrack20;V160;;;7301;019E318F88B37AC23BA300
-415;Untitled Microsoft;FreeTrack20;V160;;;2308;019FA15F28739BA32A9300
-416;Untitled Research;FreeTrack20;V160;;;1075;01A07686E5A8B2DA924A00
-417;Untitled Ron E;FreeTrack20;V160;;;14902;01A14ADE68E38AB28B9300
-418;Untitled Sega of America;FreeTrack20;V160;;;12801;01A27A32A1A972DA528A00
-419;Untitled Simbin;FreeTrack20;V160;;;3902;01A36C69678E37AA27AD00
-420;Untitled WorkShield;FreeTrack20;V160;;;4601;01A442868E38AB32BA3600
-421;Untitled ZootFly;FreeTrack20;V160;;;12701;01A5348B1863AA527A6300
-422;UQO;FreeTrack20;V160;;;23085;01A67C822099A187FE3600
-423;UVEG Machinery Simulator;FreeTrack20;V160;;;20024;01A73118585257A0F63100
-424;VAR;FreeTrack20;V160;;;20460;01A8950F9A97FA96FD2E00
-425;VBS2;FreeTrack20;V160;;;7501;01A999BB5C990099FCBF00
-485;VBS2 2.0;FreeTrack20;V170;;;7505;1D51EB3616B3A44F05B900
-426;Vehicle Simulator (Quality Simulations);FreeTrack20;V160;;;5102;01AA0FC9FF9B1FA134A900
-478;Vehicle Simulator Direction;FreeTrack20;V160;;;20735;01DEB88CF58E570F1CEF00
-427;Vestibular Ocular Reflex;FreeTrack20;V160;;;20008;01AB3919C49B31A731A200
-428;Viper Arena;FreeTrack20;V160;;;3501;01AC6F2699559934A53100
-429;VIRTools Engine;FreeTrack20;V160;;;10801;01AD1AAF68905881EB5300
-430;Virtools Plugin;FreeTrack20;V160;;;20200;01AE03FB9B23AB43A42900
-431;Virtual Driving;FreeTrack20;V160;;;20245;01AF99BB5C9927B83FB700
-432;Virtual Heroes;FreeTrack20;V160;;;20375;01B0621E78732B732AE200
-433;Virtual RC Racing;FreeTrack20;V160;;;8201;01B16D2D1038A36A23DA00
-434;Virtual Sailor;FreeTrack20;V160;;;5201;01B25F3D95778C32B33D00
-435;Virtual Shopper;FreeTrack20;V160;;;20610;01B3B78B06EC9927B73E00
-436;Virtual Supermarket;FreeTrack20;V160;;;20280;01B4849F9C39A931AD2800
-496;VirtualiTeach;FreeTrack20;V160;;;20790;01F062AE1CAB33B52D0700
-480;Vizard;FreeTrack20;V160;;;20745;01E0C1F20A79D7C0561300
-437;VizRD;FreeTrack20;V160;;;20031;01B55485D9825BF1D8AB00
-438;Void War;FreeTrack20;V160;;;10001;01B65C1FDE872AA1206600
-477;VRPlayer;FreeTrack20;V160;;;20730;01DD6787E57245201D5000
-439;VT08;FreeTrack20;V160;;;1275;01B7B78B06EC9912750200
-440;VVVV Plugin;FreeTrack20;V160;;;20075;01B8B1C6648A138C205500
-441;VW Testing;FreeTrack20;V160;;;20275;01B9AC6E878D205822AA00
-442;Walkabout3d;FreeTrack20;V160;;;20125;01BA2822901E9E39932F00
-443;Wallbusters;FreeTrack20;V160;;;1450;01BB88F58C1EA127A83F00
-444;War Thunder;FreeTrack20;V160;;;0;01BC17BE029A1FB8ED9600
-445;WAVES;FreeTrack20;V160;;;20515;01BD05B38FFE89008B8B00
-446;Welding Simulator;FreeTrack20;V160;;;2625;01BE348B188319D229B300
-447;West Racing;FreeTrack20;V160;;;1801;01BF91D999022A33B62000
-448;Whirlwind of Vietnam;FreeTrack20;V160;;;11101;01C0054E9935A03AAF3200
-449;Wikid FJ;FreeTrack20;V160;;;20685;01C19BC3BDA98269B25A00
-450;Wings of Prey;FreeTrack20;V160;V;V4Friend;1877;01C25909438736A133AC00
-451;Wings of War;FreeTrack20;V160;;;7807;01C34B0FC38B36B42FB610
+488;The Gallery;FreeTrack20;V160;;;3350;01E8CE152EDE5FFD267700 +383;The Sky Gods;FreeTrack20;V170;;;1525;017FDFF782DCCEEA27C200 +384;theHunter;FreeTrack20;V170;;;2375;0180BFF3A86D34DA24C000 +385;thriXXX HII 3D;FreeTrack20;V160;;;13403;0181FA04BD27AB36B62700 +386;thriXXX Jenna;FreeTrack20;V160;;;13401;01829F819CA2A625AB2800 +387;ThriXXX Technology;FreeTrack20;V160;;;13402;0183F47CC378B35B526900 +388;tir2joy;FreeTrack20;V160;;;2202;018487801AB532A7FE9C00 +389;TIRF4;FreeTrack20;V160;;;2203;0185311858418870E77000 +390;TNO;FreeTrack20;V160;;;20285;01861AAF6870A853D64900 +391;ToCA Race Driver 2;FreeTrack20;V160;;;8102;0187FFE9E886F286297910 +392;Toca Race Driver 3;FreeTrack20;V160;;;8101;01884098D36972B551A900 +393;Tom Clancy's H.A.W.X.;FreeTrack20;V170;V;EmBeES ;1004;0189AA4D48E85966FBAA00 +394;Tom Clancy's H.A.W.X. 2;FreeTrack20;V170;;;1007;018A1B7583521C12406F00 +395;Torque Game Engine;FreeTrack20;V160;;;5301;018BC0AF9A2EB62CAB3300 +396;Total War;FreeTrack20;V160;;;1375;018C72456F8529AA2CA400 +397;Tower Crane Simulator;FreeTrack20;V160;;;20670;018D03FB9929B034A7D900 +398;Tower I;FreeTrack20;V160;;;1325;018E662B03873CA731A400 +399;TPL Testing;FreeTrack20;V160;;;20260;018F849F9A2083DC8C2C00 +400;trackd;FreeTrack20;V160;;;20580;019053FE1EB72DA3329D00 +401;TrackMapper2;FreeTrack20;V160;;;2175;0191CE35BAF9A31A61FA00 +402;TrainMaster;FreeTrack20;V160;;;20042;01925C1FDE852D9925B400 +403;Trainz;FreeTrack20;V160;;;4701;0193D1C9F2862C9630A100 +404;TraumTek;FreeTrack20;V160;;;20650;0194A2AE4883EA645A2100 +405;Turismo Carretera;FreeTrack20;V160;;;15801;01956F2699559740A73500 +406;UK Rally Champion;FreeTrack20;V160;;;5701;019679EC0E28B196522A00 +407;ULAN;FreeTrack20;V160;;;20645;01974ADE68E16780D97A00 +473;Underwater Navigation;FreeTrack20;V160;;;20715;01D9FE2B94FB03772DE200 +408;Unity 3D Plugin;FreeTrack20;V160;;;20430;0198D24C3F9B3B9C31BF00 +525;Unity 64-bit;FreeTrack20;V160;;;3750;020DC8AB18AF3539FA5200 +409;Untitled 10tacle;FreeTrack20;V160;;;13701;0199FFE9E886F28728AA00 +410;Untitled 3D People;FreeTrack20;V160;;;15501;019A6925968D38AD23A900 +411;Untitled Apportmedia;FreeTrack20;V160;;;6801;019B3C2C1C9728B738B700 +412;Untitled Combat Flight Sim;FreeTrack20;V160;;;13801;019CA59E688D36AA28A600 +413;Untitled Deep Silver;FreeTrack20;V160;;;14601;019D656DD68838B836AD00 +414;Untitled G5 Software;FreeTrack20;V160;;;7301;019E318F88B37AC23BA300 +415;Untitled Microsoft;FreeTrack20;V160;;;2308;019FA15F28739BA32A9300 +416;Untitled Research;FreeTrack20;V160;;;1075;01A07686E5A8B2DA924A00 +417;Untitled Ron E;FreeTrack20;V160;;;14902;01A14ADE68E38AB28B9300 +418;Untitled Sega of America;FreeTrack20;V160;;;12801;01A27A32A1A972DA528A00 +419;Untitled Simbin;FreeTrack20;V160;;;3902;01A36C69678E37AA27AD00 +420;Untitled WorkShield;FreeTrack20;V160;;;4601;01A442868E38AB32BA3600 +421;Untitled ZootFly;FreeTrack20;V160;;;12701;01A5348B1863AA527A6300 +422;UQO;FreeTrack20;V160;;;23085;01A67C822099A187FE3600 +423;UVEG Machinery Simulator;FreeTrack20;V160;;;20024;01A73118585257A0F63100 +424;VAR;FreeTrack20;V160;;;20460;01A8950F9A97FA96FD2E00 +425;VBS2;FreeTrack20;V160;;;7501;01A999BB5C990099FCBF00 +485;VBS2 2.0;FreeTrack20;V170;;;7505;1D51EB3616B3A44F05B900 +426;Vehicle Simulator (Quality Simulations);FreeTrack20;V160;;;5102;01AA0FC9FF9B1FA134A900 +478;Vehicle Simulator Direction;FreeTrack20;V160;;;20735;01DEB88CF58E570F1CEF00 +427;Vestibular Ocular Reflex;FreeTrack20;V160;;;20008;01AB3919C49B31A731A200 +428;Viper Arena;FreeTrack20;V160;;;3501;01AC6F2699559934A53100 +429;VIRTools Engine;FreeTrack20;V160;;;10801;01AD1AAF68905881EB5300 +430;Virtools Plugin;FreeTrack20;V160;;;20200;01AE03FB9B23AB43A42900 +431;Virtual Driving;FreeTrack20;V160;;;20245;01AF99BB5C9927B83FB700 +432;Virtual Heroes;FreeTrack20;V160;;;20375;01B0621E78732B732AE200 +433;Virtual RC Racing;FreeTrack20;V160;;;8201;01B16D2D1038A36A23DA00 +434;Virtual Sailor;FreeTrack20;V160;;;5201;01B25F3D95778C32B33D00 +435;Virtual Shopper;FreeTrack20;V160;;;20610;01B3B78B06EC9927B73E00 +436;Virtual Supermarket;FreeTrack20;V160;;;20280;01B4849F9C39A931AD2800 +496;VirtualiTeach;FreeTrack20;V160;;;20790;01F062AE1CAB33B52D0700 +480;Vizard;FreeTrack20;V160;;;20745;01E0C1F20A79D7C0561300 +437;VizRD;FreeTrack20;V160;;;20031;01B55485D9825BF1D8AB00 +438;Void War;FreeTrack20;V160;;;10001;01B65C1FDE872AA1206600 +477;VRPlayer;FreeTrack20;V160;;;20730;01DD6787E57245201D5000 +439;VT08;FreeTrack20;V160;;;1275;01B7B78B06EC9912750200 +440;VVVV Plugin;FreeTrack20;V160;;;20075;01B8B1C6648A138C205500 +441;VW Testing;FreeTrack20;V160;;;20275;01B9AC6E878D205822AA00 +442;Walkabout3d;FreeTrack20;V160;;;20125;01BA2822901E9E39932F00 +443;Wallbusters;FreeTrack20;V160;;;1450;01BB88F58C1EA127A83F00 +444;War Thunder;FreeTrack20;V160;;;0;01BC17BE029A1FB8ED9600 +445;WAVES;FreeTrack20;V160;;;20515;01BD05B38FFE89008B8B00 +446;Welding Simulator;FreeTrack20;V160;;;2625;01BE348B188319D229B300 +447;West Racing;FreeTrack20;V160;;;1801;01BF91D999022A33B62000 +448;Whirlwind of Vietnam;FreeTrack20;V160;;;11101;01C0054E9935A03AAF3200 +449;Wikid FJ;FreeTrack20;V160;;;20685;01C19BC3BDA98269B25A00 +450;Wings of Prey;FreeTrack20;V160;V;V4Friend;1877;01C25909438736A133AC00 +451;Wings of War;FreeTrack20;V160;;;7807;01C34B0FC38B36B42FB610 512;Wings: Over Flanders Fields;FreeTrack20;V160;;;2326;02008AE39AAA4624B33C00 -452;World Racing 2;FreeTrack20;V160;;;7201;01C41AAF68A2BA836AAE00
-453;WWII Battle Tanks: T-34 vs. Tiger;FreeTrack20;V160;;;11102;01C5432C29C257F1963100
-454;X Motor Racing;FreeTrack20;V160;;;1150;01C669259690E98629A900
-458;X-Cockpit for X-Plane;FreeTrack20;V160;;;2901;01CA1C76F8BF4852999300
-459;X-Plane (32 and 64 bit);FreeTrack20;V160;V;EmBeES ;7701;01CB3FD0FC9D90FB943300
-460;X-Plane 6DOF Plugin;FreeTrack20;V160;;;10101;01CCA15F28AF7963596300
-461;X-Plane Pilot View (32 and 64 bit);FreeTrack20;V160;V;V4Friend;11301;01CD79EC0E28EFA953CA00
-462;X-Tower for X-Plane;FreeTrack20;V160;;;3001;01CE05B390EA872AAF3200
-455;X1Alpha;FreeTrack20;V160;;;1825;01C76D2D1038CFD7135A00
-456;X2: The Threat;FreeTrack20;V160;;;5501;01C81039EF980EC8D30900
-457;X3: Albion Prelude and Reunion;FreeTrack20;V170;V;V4Friend;5502;01C97E101A708F8524E300
-463;Xyphoid;FreeTrack20;V160;;;14301;01CF656DD68B43B435A800
-464;zedasoft F-35 Demo;FreeTrack20;V160;;;20041;01D02100B01F942CB93C00
-493;ZKT;FreeTrack20;V160;;;20780;01ED2BAA723F3C097EE800
-465;Zombie AA Research;FreeTrack20;V160;;;14201;01D1AA71218B3B9F1C9A00
+452;World Racing 2;FreeTrack20;V160;;;7201;01C41AAF68A2BA836AAE00 +453;WWII Battle Tanks: T-34 vs. Tiger;FreeTrack20;V160;;;11102;01C5432C29C257F1963100 +454;X Motor Racing;FreeTrack20;V160;;;1150;01C669259690E98629A900 +526;X-Camera;FreeTrack20;V160;;;3775;020E1C4055DE39CBC03D00 +458;X-Cockpit for X-Plane;FreeTrack20;V160;;;2901;01CA1C76F8BF4852999300 +459;X-Plane (32 and 64 bit);FreeTrack20;V160;V;EmBeES ;7701;01CB3FD0FC9D90FB943300 +460;X-Plane 6DOF Plugin;FreeTrack20;V160;;;10101;01CCA15F28AF7963596300 +461;X-Plane Pilot View (32 and 64 bit);FreeTrack20;V160;V;V4Friend;11301;01CD79EC0E28EFA953CA00 +462;X-Tower for X-Plane;FreeTrack20;V160;;;3001;01CE05B390EA872AAF3200 +455;X1Alpha;FreeTrack20;V160;;;1825;01C76D2D1038CFD7135A00 +456;X2: The Threat;FreeTrack20;V160;;;5501;01C81039EF980EC8D30900 +457;X3: Albion Prelude and Reunion;FreeTrack20;V170;V;V4Friend;5502;01C97E101A708F8524E300 +463;Xyphoid;FreeTrack20;V160;;;14301;01CF656DD68B43B435A800 +464;zedasoft F-35 Demo;FreeTrack20;V160;;;20041;01D02100B01F942CB93C00 +493;ZKT;FreeTrack20;V160;;;20780;01ED2BAA723F3C097EE800 +465;Zombie AA Research;FreeTrack20;V160;;;14201;01D1AA71218B3B9F1C9A00 diff --git a/cmake/mingw-w64.cmake b/cmake/mingw-w64.cmake new file mode 100644 index 00000000..b5c06549 --- /dev/null +++ b/cmake/mingw-w64.cmake @@ -0,0 +1,28 @@ +# this file only serves as toolchain file when specified so explicitly +# when building the software. from repository's root directory: +# mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$(pwd)/../cmake/mingw-w64.cmake +# -sh 20140922 + +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_VERSION 1) + +# specify the cross compiler +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) +set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) + +SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) + +# search for programs in the host directories +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# don't poison with system compile-time data +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -flto -march=i686 -mtune=prescott -mno-sse3 -mno-avx -frename-registers" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} CACHE STRING "" FORCE) +set(CMAKE_BUILD_TYPE "RELEASE" CACHE STRING "" FORCE) + +# these are merely for my own convenience +set(OpenCV_DIR /home/sthalik/opentrack-win32-sdk/opencv/build) +set(Qt5_DIR /home/sthalik/opentrack-win32-sdk/qt-install-5.3.1/lib/cmake/Qt5) diff --git a/compat/compat.cpp b/compat/compat.cpp index 7b695617..b5d63f2b 100644 --- a/compat/compat.cpp +++ b/compat/compat.cpp @@ -4,12 +4,12 @@ * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ + +#include <cstring> #define IN_FTNOIR_COMPAT #include "compat.h" -#include <string.h> #if defined(_WIN32) - PortableLockedShm::PortableLockedShm(const char* shmName, const char* mutexName, int mapSize) { hMutex = CreateMutexA(NULL, false, mutexName); @@ -43,8 +43,8 @@ void PortableLockedShm::unlock() { (void) ReleaseMutex(hMutex); } - #else +#pragma GCC diagnostic ignored "-Wunused-result" PortableLockedShm::PortableLockedShm(const char *shmName, const char* /*mutexName*/, int mapSize) : size(mapSize) { char filename[512] = {0}; @@ -57,8 +57,6 @@ PortableLockedShm::PortableLockedShm(const char *shmName, const char* /*mutexNam PortableLockedShm::~PortableLockedShm() { - //(void) shm_unlink(shm_filename); - (void) munmap(mem, size); (void) close(fd); } @@ -72,7 +70,6 @@ void PortableLockedShm::unlock() { flock(fd, LOCK_UN); } - #endif bool PortableLockedShm::success() diff --git a/compat/compat.h b/compat/compat.h index 0e488752..490d8913 100644 --- a/compat/compat.h +++ b/compat/compat.h @@ -38,12 +38,12 @@ public: void lock(); void unlock(); bool success(); - void* mem; + inline void* ptr() { return mem; } private: + void* mem; #if defined(_WIN32) HANDLE hMutex, hMapFile; #else int fd, size; - //char shm_filename[NAME_MAX]; #endif }; diff --git a/compat/qt-bug-appeasement.cpp b/compat/qt-bug-appeasement.cpp deleted file mode 100644 index 9a86ac0a..00000000 --- a/compat/qt-bug-appeasement.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "facetracknoir/qt-moc.h" diff --git a/dinput/dinput8.lib b/dinput/dinput8.lib Binary files differdeleted file mode 100644 index 3fad62fb..00000000 --- a/dinput/dinput8.lib +++ /dev/null diff --git a/dinput/dxguid.lib b/dinput/dxguid.lib Binary files differdeleted file mode 100644 index 8397d134..00000000 --- a/dinput/dxguid.lib +++ /dev/null diff --git a/dinput/strmiids.lib b/dinput/strmiids.lib Binary files differdeleted file mode 100644 index 8d921239..00000000 --- a/dinput/strmiids.lib +++ /dev/null diff --git a/documentation/filemapping example.doc b/documentation/filemapping example.doc Binary files differdeleted file mode 100644 index 0940508c..00000000 --- a/documentation/filemapping example.doc +++ /dev/null diff --git a/documentation/qt 4.5 with visual studio 2.pdf b/documentation/qt 4.5 with visual studio 2.pdf Binary files differdeleted file mode 100644 index c23e3ac9..00000000 --- a/documentation/qt 4.5 with visual studio 2.pdf +++ /dev/null diff --git a/documentation/setting up qt.pdf b/documentation/setting up qt.pdf Binary files differdeleted file mode 100644 index addaee9a..00000000 --- a/documentation/setting up qt.pdf +++ /dev/null diff --git a/documentation/using shared memory for freetrack server.pdf b/documentation/using shared memory for freetrack server.pdf Binary files differdeleted file mode 100644 index 980a0e55..00000000 --- a/documentation/using shared memory for freetrack server.pdf +++ /dev/null diff --git a/documentation/working with qt visual studio plugin.pdf b/documentation/working with qt visual studio plugin.pdf Binary files differdeleted file mode 100644 index 5d70447e..00000000 --- a/documentation/working with qt visual studio plugin.pdf +++ /dev/null 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 Binary files differnew file mode 100644 index 00000000..c4e5318f --- /dev/null +++ b/facetracknoir/clientfiles/cute-octopus-vector-material_15-1831.jpg 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 Binary files differindex fe21fa15..3f953a0a 100644 --- a/facetracknoir/uielements/curves.png +++ b/facetracknoir/uielements/curves.png diff --git a/facetracknoir/uielements/no-feed.png b/facetracknoir/uielements/no-feed.png Binary files differnew file mode 100644 index 00000000..6494e9c6 --- /dev/null +++ b/facetracknoir/uielements/no-feed.png diff --git a/facetracknoir/version.c b/facetracknoir/version.c new file mode 100644 index 00000000..0ef4ec14 --- /dev/null +++ b/facetracknoir/version.c @@ -0,0 +1,5 @@ +#ifdef IN_VERSION_UNIT +# define IN_CRAPOLA_COMPILE_UNIT +volatile const char* opentrack_version = OPENTRACK_VERSION; +#else +#endif diff --git a/freetrackclient/build-msvc.sh b/freetrackclient/build-msvc.sh new file mode 100644 index 00000000..4fd303a0 --- /dev/null +++ b/freetrackclient/build-msvc.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +export PATH="/bin:/usr/bin:$PATH" + +case "$(uname -s 2>/dev/null)" in +*CYG*|*MING*|'') wrap= ;; +*) wrap=wine ;; +esac + +c_src=".\\freetrackclient.c" +c_bin="..\\facetracknoir\\clientfiles\\freetrackclient.dll" +opt_link="-nologo -LTCG -SAFESEH:NO -OPT:REF,ICF" +opt_cl=" +-nologo -arch:SSE2 -fp:fast -EHc -EH- -GL -GR- -GS- -Gw -LD -MT -O1 +-Ob2 -Og -Oi -Ot -Oy -QIfist -volatile:iso -Ze -Fe\"${c_bin}\" +" + +MSVC="VS140COMNTOOLS" + +test -z "$MSVC" && { + echo "uh-oh, no MSVC" >&2 + exit 1 +} + +sep="\&" + +cd "$(dirname "$0")" + +$wrap cmd.exe /C $(echo " + del /F /Q $c_bin $sep + call %${MSVC}%/vsvars32.bat 2>nul >nul $sep + cl $opt_cl $c_src -link $opt_link + " | tr '\n' ' ') diff --git a/freetrackclient/freetrackclient.c b/freetrackclient/freetrackclient.c new file mode 100644 index 00000000..4bc39d67 --- /dev/null +++ b/freetrackclient/freetrackclient.c @@ -0,0 +1,114 @@ +/*********************************************************************************** + * * FTTypes FTTypes contains the specific type definitions for the * + * * FreeTrack protocol. * + * * It was loosely translated from FTTypes.pas * + * * which was created by the FreeTrack-team. * + * * * + * * Wim Vriend (Developing) * + * * Ron Hendriks (Testing and Research) * + * * * + * * Homepage <http://facetracknoir.sourceforge.net/home/default.htm> * + * * * + * * This program is distributed in the hope that it will be useful, but * + * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * * or FITNESS FOR A PARTICULAR PURPOSE. * + * * * + * * * + * * The FreeTrackClient sources were translated from the original Delphi sources * + * * created by the FreeTrack developers. * + */ + +#ifndef _MSC_VER +# warning "expect misnamed symbols" +#endif + +#pragma GCC diagnostic ignored "-Wvariadic-macros" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#define NP_AXIS_MAX 16383 + +#include <stdbool.h> +#include <string.h> +#include <windows.h> + +#include "../ftnoir_protocol_ft/fttypes.h" + +#define FT_EXPORT(t) __declspec(dllexport) t __stdcall + +#if 0 +# include <stdio.h> +static FILE *debug_stream = fopen("c:\\FreeTrackClient.log", "a"); +# define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); } +#else +#define dbg_report(...) ((void)0) +#endif + +static HANDLE hFTMemMap = 0; +static FTHeap* ipc_heap = 0; +static HANDLE ipc_mutex = 0; +static const char* dllVersion = "1.0.0.0"; +static const char* dllProvider = "FreeTrack"; + +static bool impl_create_mapping(void) +{ + if (ipc_heap != NULL) + return true; + + hFTMemMap = CreateFileMappingA(INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + sizeof(FTHeap), + (LPCSTR) FREETRACK_HEAP); + + if (hFTMemMap == NULL) + return (ipc_heap = NULL), false; + + ipc_heap = (FTHeap*) MapViewOfFile(hFTMemMap, FILE_MAP_WRITE, 0, 0, sizeof(FTHeap)); + ipc_mutex = CreateMutexA(NULL, false, FREETRACK_MUTEX); + + return true; +} + +#pragma comment (linker, "/export:FTGetData") +FT_EXPORT(bool) FTGetData(FTData* data) +{ + if (impl_create_mapping() == false) + return false; + + if (ipc_mutex && WaitForSingleObject(ipc_mutex, 16) == WAIT_OBJECT_0) { + if (ipc_heap) { + if (ipc_heap->data.DataID > (1 << 29)) + ipc_heap->data.DataID = 0; + data->DataID = ipc_heap->data.DataID; + } + ReleaseMutex(ipc_mutex); + } + return true; +} + +/* +// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument. +// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing). +// Thanks guys! +*/ +#pragma comment (linker, "/export:FTReportName") +FT_EXPORT(void) FTReportName( int name ) +{ + dbg_report("FTReportName request (ID = %d).\n", name); +} + +#pragma comment (linker, "/export:FTGetDllVersion") +FT_EXPORT(const char*) FTGetDllVersion(void) +{ + dbg_report("FTGetDllVersion request.\n"); + return dllVersion; +} + +#pragma comment (linker, "/export:FTProvider") +FT_EXPORT(const char*) FTProvider(void) +{ + dbg_report("FTProvider request.\n"); + return dllProvider; +} + diff --git a/freetrackclient/freetrackclient.cpp b/freetrackclient/freetrackclient.cpp deleted file mode 100644 index 395f017d..00000000 --- a/freetrackclient/freetrackclient.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/*********************************************************************************** - * * FTTypes FTTypes contains the specific type definitions for the * - * * FreeTrack protocol. * - * * It was loosely translated from FTTypes.pas * - * * which was created by the FreeTrack-team. * - * * * - * * Wim Vriend (Developing) * - * * Ron Hendriks (Testing and Research) * - * * * - * * Homepage <http://facetracknoir.sourceforge.net/home/default.htm> * - * * * - * * This program is distributed in the hope that it will be useful, but * - * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * - * * or FITNESS FOR A PARTICULAR PURPOSE. * - * * * - * * * - * * The FreeTrackClient sources were translated from the original Delphi sources * - * * created by the FreeTrack developers. * - */ -#define NP_AXIS_MAX 16383 - -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <windows.h> -//#include <tchar.h> - -#include "ftnoir_protocol_ft/fttypes.h" - -#define FT_EXPORT(t) extern "C" __declspec(dllexport) t __stdcall - -// -// Functions to create/open the file-mapping -// and to destroy it again. -// -static float scale2AnalogLimits( float x, float min_x, float max_x ); -static float getDegreesFromRads ( float rads ); -FT_EXPORT(bool) FTCreateMapping(void); - -#if 0 -static FILE *debug_stream = fopen("c:\\FreeTrackClient.log", "a"); -#define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); } -#else -#define dbg_report(...) -#endif - -// -// Handles to 'handle' the memory mapping -// -static HANDLE hFTMemMap = 0; -static FTMemMap *pMemData = 0; -static HANDLE hFTMutex = 0; -static const char* dllVersion = "1.0.0.0"; -static const char* dllProvider = "FreeTrack"; - -static unsigned short gameid = 0; - -// -// DllMain gets called, when the DLL is (un)loaded or a process attaches. -// -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) { - case DLL_PROCESS_ATTACH: -#ifdef WIN64 - dbg_report("\n= WIN64 =========================================================================================\n"); -#else - dbg_report("\n= WIN32 =========================================================================================\n"); -#endif - dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - dbg_report("DllMain: Attach request\n"); - DisableThreadLibraryCalls(hinstDLL); - break; - - case DLL_PROCESS_DETACH: - dbg_report("DllMain: Detach\n"); - dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - dbg_report("==========================================================================================\n"); - break; - } - return TRUE; -} - -/****************************************************************** - * FTGetData (FreeTrackClient.1) - */ - -#pragma comment(linker, "/export:FTGetData@4=FTGetData") -FT_EXPORT(bool) FTGetData(PFreetrackData data) -{ - static int prevDataID = 0; - static int dlyTrackingOff = 0; - - -// dbg_report("NP_GetData called."); - if (FTCreateMapping() == false) return false; - - if (hFTMutex && WaitForSingleObject(hFTMutex, 5) == WAIT_OBJECT_0) { - if (pMemData) { - - // - // When FaceTrackNoIR does not update frames (any more), don't update the data. - // - if (prevDataID != pMemData->data.DataID) { - memcpy(data, &pMemData->data, sizeof(TFreeTrackData)); - dlyTrackingOff = 0; - } - else { - dlyTrackingOff++; - if (dlyTrackingOff > 20) { - dlyTrackingOff = 100; - } - } - prevDataID = pMemData->data.DataID; - - // - // Limit the range of DataID - // - if (pMemData->data.DataID > 1000) { - pMemData->data.DataID = 0; - } - data->DataID = pMemData->data.DataID; - - // - // Send the ID to FaceTrackNoIR, so it can display the game-name. - // This could be a FreeTrack-specific ID - // - pMemData->GameID = gameid; - } - ReleaseMutex(hFTMutex); - } - return true; -} - -/****************************************************************** - * FTReportName (FreeTrackClient.2) - */ -#pragma comment(linker, "/export:FTReportName@4=FTReportName") -// -// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument. -// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing). -// Thanks guys! -// -FT_EXPORT(void) FTReportName( int name ) -{ - dbg_report("FTReportName request (ID = %d).\n", name); - gameid = name; // They might have really passed the name here... but they didn't! - return; -} - -/****************************************************************** - * FTGetDllVersion (FreeTrackClient.3) - */ -#pragma comment(linker, "/export:FTGetDllVersion@0=FTGetDllVersion") -FT_EXPORT(const char*) FTGetDllVersion(void) -{ - dbg_report("FTGetDllVersion request.\n"); - - return dllVersion; -} - -/****************************************************************** - * FTProvider (FreeTrackClient.4) - */ -#pragma comment(linker, "/export:FTProvider@0=FTProvider") -FT_EXPORT(const char*) FTProvider(void) -{ - dbg_report("FTProvider request.\n"); - - return dllProvider; -} - -// -// Create a memory-mapping to the Freetrack data. -// It contains the tracking data, a handle to the main-window and the program-name of the Game! -// -// -FT_EXPORT(bool) FTCreateMapping(void) -{ - // - // Memory-mapping already exists! - // - if ( pMemData != NULL ) { - return true; - } - - dbg_report("FTCreateMapping request (pMemData == NULL).\n"); - - // - // A FileMapping is used to create 'shared memory' between the FTClient and the FTServer. - // - // Try to create a FileMapping to the Shared Memory. This is done to check if it's already there (what - // may mean the face-tracker program is already running). - // - // If one already exists: close it and open the file-mapping to the existing one. - // - hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , - sizeof( FTMemMap ), - (LPCSTR) FT_MM_DATA ); - - if ( ( hFTMemMap != 0 ) && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) { - dbg_report("FTCreateMapping: Mapping already exists.\n"); - CloseHandle( hFTMemMap ); - hFTMemMap = 0; - } - - // - // Create a new FileMapping, Read/Write access - // - hFTMemMap = OpenFileMappingA( FILE_MAP_WRITE , false , (LPCSTR) FT_MM_DATA ); - if ( ( hFTMemMap != 0 ) ) { - dbg_report("FTCreateMapping: Mapping opened.\n"); - pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_WRITE, 0, 0, sizeof( FTMemMap ) ); - hFTMutex = CreateMutexA(NULL, false, FREETRACK_MUTEX); - } - else { - return false; - } - return true; -} - -// -// Destory the FileMapping to the shared memory -// -FT_EXPORT(void) FTDestroyMapping(void) -{ - if ( pMemData != NULL ) { - UnmapViewOfFile ( pMemData ); - } - - CloseHandle( hFTMutex ); - CloseHandle( hFTMemMap ); - pMemData = 0; - hFTMemMap = 0; -} - -// -// 4 convenience -// -static float getDegreesFromRads ( float rads ) { - return (rads * 57.295781f); -} - -// -// Scale the measured value to the TIR values -// -static float scale2AnalogLimits( float x, float min_x, float max_x ) { -double y; -double local_x; - - local_x = x; - if (local_x > max_x) { - local_x = max_x; - } - if (local_x < min_x) { - local_x = min_x; - } - y = ( NP_AXIS_MAX * local_x ) / max_x; - - return (float) y; -} diff --git a/freetrackclient/freetrackclient.def b/freetrackclient/freetrackclient.def deleted file mode 100644 index 155648dd..00000000 --- a/freetrackclient/freetrackclient.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY freetrackclient.dll -EXPORTS -FTGetData@4 = FTGetData -FTReportName@4 = FTReportName -FTGetDllVersion@0 = FTGetDllVersion -FTProvider@0 = FTProvider diff --git a/ftnoir_csv/csv.cpp b/ftnoir_csv/csv.cpp index 66823d24..b59b5083 100644 --- a/ftnoir_csv/csv.cpp +++ b/ftnoir_csv/csv.cpp @@ -25,9 +25,9 @@ #define INSIDE_CSV #include "csv.h" #include <QTextDecoder> -#include <QDebug> #include <QFile> #include <QCoreApplication> +#include <QDebug> CSV::CSV(QIODevice * device) { @@ -46,12 +46,10 @@ CSV::CSV(QString &string){ CSV::~CSV() { - //delete m_codec; } void CSV::setCodec(const char* codecName){ - //delete m_codec; m_codec = QTextCodec::codecForName(codecName); } @@ -59,7 +57,6 @@ QString CSV::readLine(){ QString line; if(m_string.isNull()){ - //READ DATA FROM DEVICE if(m_device && m_device->isReadable()){ QTextDecoder dec(m_codec); m_string = dec.toUnicode(m_device->readAll()); @@ -67,8 +64,6 @@ QString CSV::readLine(){ return QString(); } } - - //PARSE if((m_pos = m_rx.indexIn(m_string,m_pos)) != -1) { line = m_rx.cap(1); m_pos += m_rx.matchedLength(); @@ -111,12 +106,9 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename) QStringList gameLine; qDebug() << "getGameData, ID = " << gameID; - // - // Open the supported games list, to get the Name. - // QFile file(QCoreApplication::applicationDirPath() + "/settings/facetracknoir supported games.csv"); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ - return; + return; } CSV csv(&file); gameLine = csv.parseLine(); @@ -131,9 +123,6 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename) //qDebug() << "Column 6: " << gameLine.at(6); // International ID //qDebug() << "Column 7: " << gameLine.at(7); // FaceTrackNoIR ID - // - // If the gameID was found, fill the shared memory - // if (gameLine.count() > 6) { if (gameLine.at(6).compare( gameID, Qt::CaseInsensitive ) == 0) { QByteArray id = gameLine.at(7).toLatin1(); @@ -172,9 +161,6 @@ void CSV::getGameData( const int id, unsigned char* table, QString& gamename) gameLine = csv.parseLine(); } - // - // If the gameID was NOT found, fill only the name "Unknown game connected" - // qDebug() << "Unknown game connected" << gameID; file.close(); } diff --git a/ftnoir_csv/csv.h b/ftnoir_csv/csv.h index bfbece58..79e1351e 100644 --- a/ftnoir_csv/csv.h +++ b/ftnoir_csv/csv.h @@ -1,11 +1,4 @@ -/*dummy CSV reader for QT4*/ -/*version 0.1*/ -/*11.1.2009*/ -#ifndef CSV_H -#define CSV_H - -//#include "myclass_api.h" - +#pragma once #include <QObject> #include <QStringList> #include <QIODevice> @@ -41,5 +34,3 @@ private: CSV(QIODevice * device); CSV(QString &string); }; - -#endif // CSV_H diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index b07290e2..9b7b2cb2 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -1,72 +1,67 @@ -/* Copyright (c) 2012-2013 Stanislaw Halik
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-#include "ftnoir_filter_accela/ftnoir_filter_accela.h"
-#include <algorithm>
-#include <cmath>
-#include <QDebug>
-#include <QMutexLocker>
-#include "facetracknoir/global-settings.h"
-using namespace std;
-
-FTNoIR_Filter::FTNoIR_Filter() : first_run(true)
-{
-}
-
-static inline double parabola(const double a, const double x, const double dz, const double expt)
-{
- const double sign = x > 0 ? 1 : -1;
- const double a1 = 1./a;
- return a1 * pow(std::max<double>(fabs(x) - dz, 0), expt) * sign;
-}
-
-void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position,
- double *new_camera_position)
-{
- if (first_run)
- {
- for (int i = 0; i < 6; i++)
- {
- for (int j = 0; j < 3; j++)
- last_output[j][i] = target_camera_position[i];
- l.write(target_camera_position, target_camera_position, new_camera_position);
- }
-
- first_run = false;
- return;
- }
-
- if (!l.idempotentp(target_camera_position))
- {
- for (int i=0;i<6;i++)
- {
- const double vec = target_camera_position[i] - last_output[0][i];
- const double vec2 = target_camera_position[i] - last_output[1][i];
- const double vec3 = target_camera_position[i] - last_output[2][i];
- const int sign = vec < 0 ? -1 : 1;
- const double a = i >= 3 ? s.rotation_alpha : s.translation_alpha;
- const double a2 = a * s.second_order_alpha;
- const double a3 = a * s.third_order_alpha;
- const double deadzone = i >= 3 ? s.rot_deadzone : s.trans_deadzone;
- const double velocity =
- parabola(a, vec, deadzone, s.expt) +
- parabola(a2, vec2, deadzone, s.expt) +
- parabola(a3, vec3, deadzone, s.expt);
- const double result = last_output[0][i] + velocity;
- const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i];
- last_output[2][i] = last_output[1][i];
- last_output[1][i] = last_output[0][i];
- last_output[0][i] = done ? target_camera_position[i] : result;
- }
- }
-
- l.write(target_camera_position, last_output[0], new_camera_position);
-}
-
-extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor()
-{
- return new FTNoIR_Filter;
-}
+/* Copyright (c) 2012-2013 Stanislaw Halik + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ +#include "ftnoir_filter_accela/ftnoir_filter_accela.h" +#include <algorithm> +#include <cmath> +#include <QDebug> +#include <QMutexLocker> +#include "facetracknoir/plugin-support.h" +using namespace std; + +FTNoIR_Filter::FTNoIR_Filter() : first_run(true) +{ +} + +static inline double parabola(const double a, const double x, const double dz, const double expt) +{ + const double sign = x > 0 ? 1 : -1; + const double a1 = 1./a; + return a1 * pow(std::max<double>(fabs(x) - dz, 0), expt) * sign; +} + +void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position, + double *new_camera_position) +{ + if (first_run) + { + for (int i = 0; i < 6; i++) + { + new_camera_position[i] = target_camera_position[i]; + for (int j = 0; j < 3; j++) + last_output[j][i] = target_camera_position[i]; + } + + first_run = false; + return; + } + + for (int i=0;i<6;i++) + { + const double vec = target_camera_position[i] - last_output[0][i]; + const double vec2 = target_camera_position[i] - last_output[1][i]; + const double vec3 = target_camera_position[i] - last_output[2][i]; + const int sign = vec < 0 ? -1 : 1; + const double a = i >= 3 ? s.rotation_alpha : s.translation_alpha; + const double a2 = a * s.second_order_alpha; + const double a3 = a * s.third_order_alpha; + const double deadzone = i >= 3 ? s.rot_deadzone : s.trans_deadzone; + const double velocity = + parabola(a, vec, deadzone, s.expt) + + parabola(a2, vec2, deadzone, s.expt) + + parabola(a3, vec3, deadzone, s.expt); + const double result = last_output[0][i] + velocity; + const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i]; + last_output[2][i] = last_output[1][i]; + last_output[1][i] = last_output[0][i]; + last_output[0][i] = new_camera_position[i] = done ? target_camera_position[i] : result; + } +} + +extern "C" OPENTRACK_EXPORT IFilter* GetConstructor() +{ + return new FTNoIR_Filter; +} diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h index 2187fd01..0a736042 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -1,81 +1,79 @@ -#pragma once
-#include "ftnoir_filter_base/ftnoir_filter_base.h"
-#include "ui_ftnoir_accela_filtercontrols.h"
-#include "facetracknoir/global-settings.h"
-#include "facetracknoir/lerp.hpp"
-#include <QMutex>
-
-#define ACCELA_SMOOTHING_ROTATION 60.0
-#define ACCELA_SMOOTHING_TRANSLATION 40.0
-#define ACCELA_SECOND_ORDER_ALPHA 100.0
-#define ACCELA_THIRD_ORDER_ALPHA 180.0
-
-#include <facetracknoir/options.h>
-using namespace options;
-
-struct settings {
- pbundle b;
- value<double> rotation_alpha,
- translation_alpha,
- second_order_alpha,
- third_order_alpha,
- rot_deadzone,
- trans_deadzone,
- expt;
- settings() :
- b(bundle("Accela")),
- rotation_alpha(b, "rotation-alpha", ACCELA_SMOOTHING_ROTATION),
- translation_alpha(b, "translation-alpha", ACCELA_SMOOTHING_TRANSLATION),
- second_order_alpha(b, "second-order-alpha", ACCELA_SECOND_ORDER_ALPHA),
- third_order_alpha(b, "third-order-alpha", ACCELA_THIRD_ORDER_ALPHA),
- rot_deadzone(b, "rotation-deadband", 0),
- trans_deadzone(b, "translation-deadband", 0),
- expt(b, "exponent", 2)
- {}
-};
-
-class FTNoIR_Filter : public IFilter
-{
-public:
- FTNoIR_Filter();
- void FilterHeadPoseData(const double* target_camera_position, double *new_camera_position);
- void reset() {
- first_run = true;
- }
- void receiveSettings() {
- s.b->reload();
- }
-private:
- lerp l;
- settings s;
- bool first_run;
- double last_output[3][6];
-};
-
-class FilterControls: public QWidget, public IFilterDialog
-{
- Q_OBJECT
-public:
- FilterControls();
- void registerFilter(IFilter* filter);
- void unregisterFilter();
-private:
- Ui::AccelaUICFilterControls ui;
- void discard();
- void save();
- FTNoIR_Filter* accela_filter;
- settings s;
-private slots:
- void doOK();
- void doCancel();
-};
-
-class FTNoIR_FilterDll : public Metadata
-{
-public:
- void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk4"); }
- void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk4"); }
- void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk4"); }
-
- void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); }
-};
+#pragma once +#include "ui_ftnoir_accela_filtercontrols.h" +#include "facetracknoir/plugin-api.hpp" +#include <QMutex> + +#define ACCELA_SMOOTHING_ROTATION 60.0 +#define ACCELA_SMOOTHING_TRANSLATION 40.0 +#define ACCELA_SECOND_ORDER_ALPHA 100.0 +#define ACCELA_THIRD_ORDER_ALPHA 180.0 + +#include <facetracknoir/options.h> +using namespace options; + +struct settings { + pbundle b; + value<double> rotation_alpha, + translation_alpha, + second_order_alpha, + third_order_alpha, + rot_deadzone, + trans_deadzone, + expt; + settings() : + b(bundle("Accela")), + rotation_alpha(b, "rotation-alpha", ACCELA_SMOOTHING_ROTATION), + translation_alpha(b, "translation-alpha", ACCELA_SMOOTHING_TRANSLATION), + second_order_alpha(b, "second-order-alpha", ACCELA_SECOND_ORDER_ALPHA), + third_order_alpha(b, "third-order-alpha", ACCELA_THIRD_ORDER_ALPHA), + rot_deadzone(b, "rotation-deadband", 0), + trans_deadzone(b, "translation-deadband", 0), + expt(b, "exponent", 2) + {} +}; + +class FTNoIR_Filter : public IFilter +{ +public: + FTNoIR_Filter(); + void FilterHeadPoseData(const double* target_camera_position, double *new_camera_position); + void reset() { + first_run = true; + } + void receiveSettings() { + s.b->reload(); + } + +private: + settings s; + bool first_run; + double last_output[3][6]; +}; + +class FilterControls: public QWidget, public IFilterDialog +{ + Q_OBJECT +public: + FilterControls(); + void registerFilter(IFilter* filter); + void unregisterFilter(); +private: + Ui::AccelaUICFilterControls ui; + void discard(); + void save(); + FTNoIR_Filter* accela_filter; + settings s; +private slots: + void doOK(); + void doCancel(); +}; + +class FTNoIR_FilterDll : public Metadata +{ +public: + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk4"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk4"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk4"); } + + void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } +}; diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp index ca321891..1520ad6e 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp @@ -3,7 +3,7 @@ #include <QDebug> #include <algorithm> #include <QDoubleSpinBox> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FilterControls::FilterControls() : accela_filter(nullptr) @@ -43,7 +43,7 @@ void FilterControls::doCancel() { void FilterControls::discard() { - s.b->revert(); + s.b->reload(); } void FilterControls::save() { @@ -52,7 +52,7 @@ void FilterControls::save() { accela_filter->receiveSettings(); } -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog() +extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog() { return new FilterControls; } diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp index a024e789..65bee314 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp @@ -1,7 +1,7 @@ #include "ftnoir_filter_accela.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_FilterDll; } diff --git a/ftnoir_filter_base/ftnoir_filter_base.h b/ftnoir_filter_base/ftnoir_filter_base.h deleted file mode 100644 index fbb0441d..00000000 --- a/ftnoir_filter_base/ftnoir_filter_base.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef FTNOIR_FILTER_BASE_H
-#define FTNOIR_FILTER_BASE_H
-
-#include "ftnoir_filter_base_global.h"
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#include <QString>
-#include <QList>
-#include <QFile>
-#include <QCoreApplication>
-#include <QMessageBox>
-#include <QSettings>
-
-struct IFilter
-{
- virtual ~IFilter() = 0;
- virtual void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position) = 0;
- virtual void reset() = 0;
-};
-
-inline IFilter::~IFilter() { }
-
-struct IFilterDialog
-{
- virtual ~IFilterDialog() {}
- virtual void registerFilter(IFilter* tracker) = 0;
- virtual void unregisterFilter() = 0;
-};
-
-#endif // FTNOIR_FILTER_BASE_H
diff --git a/ftnoir_filter_base/ftnoir_filter_base_global.h b/ftnoir_filter_base/ftnoir_filter_base_global.h deleted file mode 100644 index a1a13315..00000000 --- a/ftnoir_filter_base/ftnoir_filter_base_global.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FTNOIR_FILTER_BASE_GLOBAL_H -#define FTNOIR_FILTER_BASE_GLOBAL_H - -#include <QtGlobal> - -#ifndef OPENTRACK_MAIN -# if !defined(_MSC_VER) -# define FTNOIR_FILTER_BASE_EXPORT __attribute__ ((visibility ("default"))) -# else -# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT -#endif -#else -# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT -#endif - -#endif // FTNOIR_FILTER_BASE_GLOBAL_H diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp index d3cb2c32..c7169faa 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp @@ -1,13 +1,5 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * +/*** Written by Donovan Baarda +* * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation; either version 3 of the License, or (at your * @@ -23,28 +15,13 @@ * * ********************************************************************************/ #include "ftnoir_filter_ewma2.h" -#include "math.h" +#include <cmath> #include <QDebug> #include <QWidget> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" #include <algorithm> #include <QMutexLocker> -/////////////////////////////////////////////////////////////////////////////// -// -// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter -// -// This filter tries to adjust the amount of filtering to minimize lag when -// moving, and minimize noise when still. It uses the delta filtered over the -// last 3 frames (0.1secs) compared to the delta's average noise variance over -// the last 3600 frames (~2mins) to try and detect movement vs noise. As the -// delta increases from 0->3 stdevs of the noise, the filtering scales down -// from maxSmooth->minSmooth at a rate controlled by the powCurve setting. -// -// Written by Donovan Baarda -// -/////////////////////////////////////////////////////////////////////////////// - FTNoIR_Filter::FTNoIR_Filter() : first_run(true), // Deltas are smoothed over the last 3 frames (0.1sec at 30fps). @@ -64,46 +41,57 @@ void FTNoIR_Filter::FilterHeadPoseData(const double *target_camera_position, { double new_delta, new_noise, norm_noise; double alpha; - double pos[6]; //On the first run, initialize to output=target and return. if (first_run==true) { for (int i=0;i<6;i++) { + new_camera_position[i] = target_camera_position[i]; + current_camera_position[i] = target_camera_position[i]; delta[i] = 0.0; noise[i] = 0.0; - l.write(target_camera_position, target_camera_position, new_camera_position); } first_run=false; return; } - if (!l.idempotentp(target_camera_position)) + bool new_frame = false; + + for (int i = 0; i < 6; i++) { - double cur[6]; - l.get_state(cur); - // Calculate the new camera position. - for (int i=0;i<6;i++) { - // Calculate the current and smoothed delta. - new_delta = target_camera_position[i]-cur[i]; - delta[i] = delta_smoothing*new_delta + (1.0-delta_smoothing)*delta[i]; - // Calculate the current and smoothed noise variance. - new_noise = delta[i]*delta[i]; - noise[i] = noise_smoothing*new_noise + (1.0-noise_smoothing)*noise[i]; - // Normalise the noise between 0->1 for 0->9 variances (0->3 stddevs). - norm_noise = std::min<double>(new_noise/(9.0*noise[i]), 1.0); - // Calculate the alpha from the normalized noise. - // TODO(abo): change kSmoothingScaleCurve to a float where 1.0 is sqrt(norm_noise). - alpha = 1.0/(s.kMinSmoothing+(1.0-pow(norm_noise,s.kSmoothingScaleCurve/20.0))*(s.kMaxSmoothing-s.kMinSmoothing)); - // Update the current camera position to the new position. - double value = alpha*target_camera_position[i] + (1.0-alpha)*cur[i]; - pos[i] = value; + if (target_camera_position[i] != current_camera_position[i]) + { + new_frame = true; + break; } } - l.write(target_camera_position, pos, new_camera_position); + if (!new_frame) + { + for (int i = 0; i < 6; i++) + new_camera_position[i] = current_camera_position[i]; + return; + } + + // Calculate the new camera position. + for (int i=0;i<6;i++) { + // Calculate the current and smoothed delta. + new_delta = target_camera_position[i]-current_camera_position[i]; + delta[i] = delta_smoothing*new_delta + (1.0-delta_smoothing)*delta[i]; + // Calculate the current and smoothed noise variance. + new_noise = delta[i]*delta[i]; + noise[i] = noise_smoothing*new_noise + (1.0-noise_smoothing)*noise[i]; + // Normalise the noise between 0->1 for 0->9 variances (0->3 stddevs). + norm_noise = std::min<double>(new_noise/(9.0*noise[i]), 1.0); + // Calculate the alpha from the normalized noise. + // TODO(abo): change kSmoothingScaleCurve to a float where 1.0 is sqrt(norm_noise). + alpha = 1.0/(s.kMinSmoothing+(1.0-pow(norm_noise,s.kSmoothingScaleCurve/20.0))*(s.kMaxSmoothing-s.kMinSmoothing)); + // Update the current camera position to the new position. + double pos = alpha*target_camera_position[i] + (1.0-alpha)*current_camera_position[i]; + new_camera_position[i] = current_camera_position[i] = pos; + } } -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IFilter* GetConstructor() { return new FTNoIR_Filter; } diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h index ea25a135..8863348c 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h @@ -1,38 +1,10 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #pragma once -#ifndef INCLUDED_FTN_FILTER_H -#define INCLUDED_FTN_FILTER_H -#include "ftnoir_filter_base/ftnoir_filter_base.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "ui_ftnoir_ewma_filtercontrols.h" #include <QWidget> #include <QMutex> #include "facetracknoir/options.h" -#include "facetracknoir/lerp.hpp" using namespace options; struct settings { @@ -62,8 +34,8 @@ private: double noise_smoothing; double delta[6]; double noise[6]; + double current_camera_position[6]; settings s; - lerp l; }; class FilterControls: public QWidget, public IFilterDialog @@ -93,6 +65,3 @@ public: void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Exponentially Weighted Moving Average filter with dynamic smoothing parameter"); } void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } }; - -#endif //INCLUDED_FTN_FILTER_H -//END diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp index fb02354e..b6bde553 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp @@ -1,31 +1,7 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #include "ftnoir_filter_ewma2.h" #include <cmath> #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" #include "ui_ftnoir_ewma_filtercontrols.h" FilterControls::FilterControls() : @@ -57,7 +33,7 @@ void FilterControls::doOK() { } void FilterControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } @@ -67,7 +43,7 @@ void FilterControls::save() { pFilter->receiveSettings(); } -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog( ) { return new FilterControls; } diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp index 6ef7768e..5ec6138a 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp @@ -1,31 +1,7 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #include "ftnoir_filter_ewma2.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_FilterDll; } diff --git a/ftnoir_filter_kalman/ftnoir_filter_kalman.h b/ftnoir_filter_kalman/ftnoir_filter_kalman.h index 363b8cd4..558aebd6 100644..100755 --- a/ftnoir_filter_kalman/ftnoir_filter_kalman.h +++ b/ftnoir_filter_kalman/ftnoir_filter_kalman.h @@ -8,29 +8,24 @@ #ifndef INCLUDED_FTN_FILTER_H #define INCLUDED_FTN_FILTER_H -#undef FTNOIR_TRACKER_BASE_LIB -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT - -#include "ftnoir_filter_base/ftnoir_filter_base.h" #include "ui_ftnoir_kalman_filtercontrols.h" -#include "facetracknoir/global-settings.h" -#include <opencv2/opencv.hpp> +#include "facetracknoir/plugin-api.hpp" +#include <opencv2/core/core.hpp> +#include <opencv2/video/video.hpp> #include <vector> #include <QString> -#include <QIcon> -#include <QWidget> #include <QElapsedTimer> -#include <QObject> +#include <QWidget> #include "facetracknoir/options.h" using namespace options; -class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter +class OPENTRACK_EXPORT FTNoIR_Filter : public IFilter { public: FTNoIR_Filter(); - void reset() virt_override; + void reset(); void FilterHeadPoseData(const double *target_camera_position, - double *new_camera_position) virt_override; + double *new_camera_position); double accel_variance; double noise_variance; cv::KalmanFilter kalman; @@ -38,7 +33,7 @@ public: QElapsedTimer timer; }; -class FTNOIR_FILTER_BASE_EXPORT FTNoIR_FilterDll : public Metadata +class OPENTRACK_EXPORT FTNoIR_FilterDll : public Metadata { public: void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Kalman filter"); } @@ -47,7 +42,7 @@ public: void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } }; -class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog +class OPENTRACK_EXPORT FilterControls: public QWidget, public IFilterDialog { Q_OBJECT public: @@ -58,8 +53,8 @@ public: show(); } Ui::KalmanUICFilterControls ui; - virtual void registerFilter(IFilter*) virt_override {} - virtual void unregisterFilter() virt_override {} + void registerFilter(IFilter*) override {} + void unregisterFilter() override {} public slots: void doOK(); void doCancel(); diff --git a/ftnoir_filter_kalman/kalman.cpp b/ftnoir_filter_kalman/kalman.cpp index 388390f3..62d5ff98 100644 --- a/ftnoir_filter_kalman/kalman.cpp +++ b/ftnoir_filter_kalman/kalman.cpp @@ -5,9 +5,9 @@ * copyright notice and this permission notice appear in all copies. */ #include "ftnoir_filter_kalman.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" #include <QDebug> -#include <math.h> +#include <cmath> FTNoIR_Filter::FTNoIR_Filter() { reset(); @@ -118,16 +118,16 @@ void FilterControls::doCancel() { close(); } -extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_FilterDll; } -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IFilter* GetConstructor() { return new FTNoIR_Filter; } -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog() { +extern "C" OPENTRACK_EXPORT IFilterDialog* GetDialog() { return new FilterControls; } diff --git a/ftnoir_posewidget/glwidget.h b/ftnoir_posewidget/glwidget.h index c4b2e09d..91536336 100644 --- a/ftnoir_posewidget/glwidget.h +++ b/ftnoir_posewidget/glwidget.h @@ -5,12 +5,11 @@ * copyright notice and this permission notice appear in all copies. */ -#ifndef GLWIDGET_H -#define GLWIDGET_H +#pragma once #include <QtGui> #include <QPixmap> -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "facetracknoir/plugin-api.hpp" struct Point { Point(int x, int y) : @@ -48,7 +47,7 @@ struct Vec2f { } }; -class FTNOIR_TRACKER_BASE_EXPORT GLWidget : public QWidget +class OPENTRACK_EXPORT GLWidget : public QWidget { Q_OBJECT @@ -56,10 +55,8 @@ public: GLWidget(QWidget *parent); ~GLWidget(); void rotateBy(double xAngle, double yAngle, double zAngle); - protected: - void paintEvent ( QPaintEvent * event ); - + void paintEvent ( QPaintEvent * event ) override; private: Point project(const Vec3f& point) { Point rect; @@ -93,5 +90,3 @@ private: QImage back; QImage texture; }; - -#endif diff --git a/ftnoir_protocol_base/ftnoir_protocol_base.h b/ftnoir_protocol_base/ftnoir_protocol_base.h deleted file mode 100644 index d2f85ec0..00000000 --- a/ftnoir_protocol_base/ftnoir_protocol_base.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of the some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2010 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* This class implements a tracker-base * -*********************************************************************************/ -/* - Modifications (last one on top): - - 20121115 - WVR: Added RegisterProtocol() and unRegisterProtocol() to Dialog Class - 20110415 - WVR: Added overloaded operator - and -= -*/ - -#ifndef FTNOIR_PROTOCOL_BASE_H -#define FTNOIR_PROTOCOL_BASE_H - -#include "ftnoir_protocol_base_global.h" -#include "ftnoir_tracker_base/ftnoir_tracker_types.h" -#include <QWidget> -#include <QFrame> - -struct IProtocol -{ - virtual ~IProtocol() = 0; - virtual bool checkServerInstallationOK() = 0; - virtual void sendHeadposeToGame( const double* headpose ) = 0; - virtual QString getGameName() = 0; -}; - -inline IProtocol::~IProtocol() { } - -struct IProtocolDialog -{ - virtual ~IProtocolDialog() {} - virtual void registerProtocol(IProtocol *protocol) = 0; - virtual void unRegisterProtocol() = 0; -}; - -#endif // FTNOIR_PROTOCOL_BASE_H diff --git a/ftnoir_protocol_base/ftnoir_protocol_base_global.h b/ftnoir_protocol_base/ftnoir_protocol_base_global.h deleted file mode 100644 index 06386c7f..00000000 --- a/ftnoir_protocol_base/ftnoir_protocol_base_global.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H -#define FTNOIR_PROTOCOL_BASE_GLOBAL_H - -#include <QtGlobal> - -#ifndef OPENTRACK_MAIN -# if !defined(_MSC_VER) -# define FTNOIR_PROTOCOL_BASE_EXPORT __attribute__ ((visibility ("default"))) -# else -# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT -#endif -#else -# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#endif - -#endif // FTNOIR_PROTOCOL_BASE_GLOBAL_H diff --git a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui index a4092c05..575549d6 100644 --- a/ftnoir_protocol_fg/ftnoir_fgcontrols.ui +++ b/ftnoir_protocol_fg/ftnoir_fgcontrols.ui @@ -1,143 +1,143 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFGControls</class>
- <widget class="QWidget" name="UICFGControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>415</width>
- <height>112</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>FlightGear protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="../ftnoir_filter_ewma2/ewma-filter.qrc">
- <normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>IP-address remote PC</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="spinIPFirstNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QSpinBox" name="spinIPSecondNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QSpinBox" name="spinIPThirdNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QSpinBox" name="spinIPFourthNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>1000</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- <item row="2" column="2" colspan="3">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinIPFirstNibble</tabstop>
- <tabstop>spinIPSecondNibble</tabstop>
- <tabstop>spinIPThirdNibble</tabstop>
- <tabstop>spinIPFourthNibble</tabstop>
- <tabstop>spinPortNumber</tabstop>
- </tabstops>
- <resources>
- <include location="../ftnoir_filter_ewma2/ewma-filter.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFGControls</class> + <widget class="QWidget" name="UICFGControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>415</width> + <height>112</height> + </rect> + </property> + <property name="windowTitle"> + <string>FlightGear protocol settings</string> + </property> + <property name="windowIcon"> + <iconset resource="../ftnoir_filter_ewma2/ewma-filter.qrc"> + <normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>IP-address remote PC</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinIPFirstNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QSpinBox" name="spinIPSecondNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QSpinBox" name="spinIPThirdNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QSpinBox" name="spinIPFourthNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Port-number</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="spinPortNumber"> + <property name="minimum"> + <number>1000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + </widget> + </item> + <item row="2" column="2" colspan="3"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>spinIPFirstNibble</tabstop> + <tabstop>spinIPSecondNibble</tabstop> + <tabstop>spinIPThirdNibble</tabstop> + <tabstop>spinIPFourthNibble</tabstop> + <tabstop>spinPortNumber</tabstop> + </tabstops> + <resources> + <include location="../ftnoir_filter_ewma2/ewma-filter.qrc"/> + </resources> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp index 0ef6b50f..b2d29118 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp @@ -26,8 +26,7 @@ * It is based on the (Linux) example made by Melchior FRANZ. * ********************************************************************************/ #include "ftnoir_protocol_fg.h" -#include "facetracknoir/global-settings.h" -#include <ftnoir_tracker_base/ftnoir_tracker_types.h> +#include "facetracknoir/plugin-api.hpp" // For Todd and Arda Kutlu @@ -58,7 +57,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return outSocket.bind(QHostAddress::Any, 0, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.h b/ftnoir_protocol_fg/ftnoir_protocol_fg.h index dca1f245..4b25a3e1 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.h +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.h @@ -26,13 +26,12 @@ * It is based on the (Linux) example made by Melchior FRANZ. * ********************************************************************************/ #pragma once -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" #include "ui_ftnoir_fgcontrols.h" #include "fgtypes.h" #include <QThread> #include <QUdpSocket> #include <QMessageBox> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "facetracknoir/options.h" using namespace options; diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp index 1c3e5ef8..0074a64a 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp @@ -28,7 +28,7 @@ #include "ftnoir_protocol_fg.h" #include <QObject> #include <QFile> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" //******************************************************************************************************* // FaceTrackNoIR Client Settings-dialog. @@ -59,11 +59,11 @@ void FGControls::doOK() { } void FGControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new FGControls; } diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp index 3125f136..f830f8f7 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp @@ -24,9 +24,9 @@ ********************************************************************************/ #include "ftnoir_protocol_fg.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui index 6cb066bd..637e4dba 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui +++ b/ftnoir_protocol_fsuipc/ftnoir_fsuipccontrols.ui @@ -1,134 +1,134 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFSUIPCControls</class>
- <widget class="QWidget" name="UICFSUIPCControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>512</width>
- <height>100</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>FSUIPC settings FaceTrackNoIR</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="1">
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="txtLocationOfDLL">
- <property name="minimumSize">
- <size>
- <width>230</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Location of FSUIPC.dll</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="lineWidth">
- <number>1</number>
- </property>
- <property name="text">
- <string>Location of FSUIPC.dll</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>The DLL should be located in the Modules/ directory of MS FS 2004</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="btnFindDLL">
- <property name="maximumSize">
- <size>
- <width>35</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFSUIPCControls</class> + <widget class="QWidget" name="UICFSUIPCControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>512</width> + <height>100</height> + </rect> + </property> + <property name="windowTitle"> + <string>FSUIPC settings FaceTrackNoIR</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="1"> + <widget class="QPushButton" name="btnCancel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="txtLocationOfDLL"> + <property name="minimumSize"> + <size> + <width>230</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Location of FSUIPC.dll</string> + </property> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="lineWidth"> + <number>1</number> + </property> + <property name="text"> + <string>Location of FSUIPC.dll</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>The DLL should be located in the Modules/ directory of MS FS 2004</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QPushButton" name="btnOK"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="btnFindDLL"> + <property name="maximumSize"> + <size> + <width>35</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp index 632d502a..822cdb4d 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp @@ -25,9 +25,8 @@ * to games, using the FSUIPC.dll. * ********************************************************************************/ #include "ftnoir_protocol_fsuipc.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -/** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() { prevPosX = 0.0f; @@ -43,9 +42,6 @@ FTNoIR_Protocol::~FTNoIR_Protocol() FSUIPCLib.unload(); } -// -// Scale the measured value to the Joystick values -// int FTNoIR_Protocol::scale2AnalogLimits( float x, float min_x, float max_x ) { double y; double local_x; @@ -162,7 +158,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return true; } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT FTNoIR_Protocol* CALLING_CONVENTION GetConstructor(void) +extern "C" OPENTRACK_EXPORT FTNoIR_Protocol* GetConstructor(void) { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h index ff8d3b7f..bde16d8f 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h @@ -31,8 +31,7 @@ #include <windows.h> #include <stdlib.h> #include "FSUIPC_User.h" -#include "facetracknoir/global-settings.h" -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "facetracknoir/plugin-api.hpp" #include "ui_ftnoir_fsuipccontrols.h" #include <QMessageBox> #include <QSettings> @@ -67,7 +66,7 @@ class FTNoIR_Protocol : public IProtocol { public: FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol() virt_override; + ~FTNoIR_Protocol() override; bool checkServerInstallationOK(); void sendHeadposeToGame(const double* headpose); QString getGameName() { diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp index d97cff99..ceabeabf 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp @@ -23,7 +23,7 @@ * * ********************************************************************************/ #include "ftnoir_protocol_fsuipc.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FSUIPCControls::FSUIPCControls() : QWidget() @@ -42,7 +42,7 @@ void FSUIPCControls::doOK() { } void FSUIPCControls::doCancel() { - s.b->revert(); + s.b->reload(); close(); } @@ -56,7 +56,7 @@ void FSUIPCControls::getLocationOfDLL() } } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog(void) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog(void) { return new FSUIPCControls; } diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp index 57b174c5..dbea2c46 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp @@ -23,9 +23,9 @@ * * ********************************************************************************/ #include "ftnoir_protocol_fsuipc.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata(void) +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata(void) { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui index 941aaff0..5356d2e5 100644 --- a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui +++ b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui @@ -1,223 +1,182 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTControls</class>
- <widget class="QWidget" name="UICFTControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>489</width>
- <height>402</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="windowTitle">
- <string>freetrack protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="ft-protocol.qrc">
- <normaloff>:/images/freetrack.png</normaloff>:/images/freetrack.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>TIRViews</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <item row="0" column="0">
- <widget class="QCheckBox" name="chkTIRViews">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Memory hacks</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Only for very old and buggy old games such as CFS3.</string>
- </property>
- <property name="scaledContents">
- <bool>false</bool>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>TrackIR.exe</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QFormLayout" name="formLayout_3">
- <item row="0" column="0">
- <widget class="QCheckBox" name="chkStartDummy">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Using EZCA</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>FSX-specific EZCA protocol hacks</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Select interface</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QComboBox" name="cbxSelectInterface"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>Disable one of the protocols if game is confused by presence of both at the same time.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QGroupBox" name="groupBox_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Repair NPClient location</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignJustify|Qt::AlignTop</set>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QPushButton" name="bntLocateNPClient">
- <property name="text">
- <string>Locate DLL</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources>
- <include location="ft-protocol.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFTControls</class> + <widget class="QWidget" name="UICFTControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>422</width> + <height>305</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>freetrack protocol settings</string> + </property> + <property name="windowIcon"> + <iconset resource="ft-protocol.qrc"> + <normaloff>:/images/freetrack.png</normaloff>:/images/freetrack.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>TIRViews</string> + </property> + <property name="alignment"> + <set>Qt::AlignJustify|Qt::AlignTop</set> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QCheckBox" name="chkTIRViews"> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string>Memory hacks</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Only for very old and buggy old games such as CFS3.</string> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="groupBox_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Repair NPClient location</string> + </property> + <property name="alignment"> + <set>Qt::AlignJustify|Qt::AlignTop</set> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QPushButton" name="bntLocateNPClient"> + <property name="text"> + <string>Locate DLL</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Replace the registry entry if you want to use other software with the NPClient protocol and it doesn't work automatically.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Select interface</string> + </property> + <property name="alignment"> + <set>Qt::AlignJustify|Qt::AlignTop</set> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QComboBox" name="cbxSelectInterface"/> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Disable one of the protocols if game is confused by presence of both at the same time.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="ft-protocol.qrc"/> + </resources> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp index 281af6a0..ae23be3c 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp @@ -28,9 +28,9 @@ #include "ftnoir_csv/csv.h" FTNoIR_Protocol::FTNoIR_Protocol() : - shm(FT_MM_DATA, FREETRACK_MUTEX, sizeof(FTMemMap)) + shm(FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap)) { - pMemData = (FTMemMap*) shm.mem; + pMemData = (FTHeap*) shm.ptr(); ProgramName = ""; intGameID = 0; viewsStart = 0; @@ -49,50 +49,30 @@ FTNoIR_Protocol::~FTNoIR_Protocol() } void FTNoIR_Protocol::sendHeadposeToGame(const double* headpose) { - float virtPosX; - float virtPosY; - float virtPosZ; - - float virtRotX; - float virtRotY; - float virtRotZ; - - float headPosX; - float headPosY; - float headPosZ; - - float headRotX; - float headRotY; - float headRotZ; - headRotX = virtRotX = getRadsFromDegrees(headpose[Pitch]) * (s.useDummyExe ? 2.0 : 1.0); - headRotY = virtRotY = getRadsFromDegrees(headpose[Yaw]); - headRotZ = virtRotZ = getRadsFromDegrees(headpose[Roll]); - headPosX = virtPosX = headpose[TX] * 10; - headPosY = virtPosY = headpose[TY] * 10; - headPosZ = virtPosZ = headpose[TZ] * 10; + float yaw = getRadsFromDegrees(headpose[Yaw]); + float pitch = getRadsFromDegrees(headpose[Pitch]); + float roll = getRadsFromDegrees(headpose[Roll]); + float tx = headpose[TX] * 10.f; + float ty = headpose[TY] * 10.f; + float tz = headpose[TZ] * 10.f; shm.lock(); - pMemData->data.RawX = headPosX; - pMemData->data.RawY = headPosY; - pMemData->data.RawZ = headPosZ; - pMemData->data.RawPitch = headRotX; - pMemData->data.RawYaw = headRotY; - pMemData->data.RawRoll = headRotZ; - - // - // - pMemData->data.X = virtPosX; - pMemData->data.Y = virtPosY; - pMemData->data.Z = virtPosZ; - pMemData->data.Pitch = virtRotX; - pMemData->data.Yaw = virtRotY; - pMemData->data.Roll = virtRotZ; - - // - // Leave some values 0 yet... - // - pMemData->data.X1 = pMemData->data.DataID + 10; + pMemData->data.RawX = 0; + pMemData->data.RawY = 0; + pMemData->data.RawZ = 0; + pMemData->data.RawPitch = 0; + pMemData->data.RawYaw = 0; + pMemData->data.RawRoll = 0; + + pMemData->data.X = tx; + pMemData->data.Y = ty; + pMemData->data.Z = tz; + pMemData->data.Yaw = yaw; + pMemData->data.Pitch = pitch; + pMemData->data.Roll = roll; + + pMemData->data.X1 = ++pMemData->data.DataID; pMemData->data.X2 = 0; pMemData->data.X3 = 0; pMemData->data.X4 = 0; @@ -146,28 +126,18 @@ void FTNoIR_Protocol::start_dummy() { QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe"; dummyTrackIR.setProgram("\"" + program + "\""); dummyTrackIR.start(); - - qDebug() << "FTServer::run() says: TrackIR.exe executed!" << program; } bool FTNoIR_Protocol::checkServerInstallationOK() { QSettings settings("Freetrack", "FreetrackClient"); // Registry settings (in HK_USER) QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER) - QString aLocation; // Location of Client DLL - if (!shm.success()) return false; - qDebug() << "checkServerInstallationOK says: Starting Function"; + QString aLocation = QCoreApplication::applicationDirPath() + "/"; - // - // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s). - // - aLocation = QCoreApplication::applicationDirPath() + "/"; - - qDebug() << "checkServerInstallationOK says: used interface = " << s.intUsedInterface; switch (s.intUsedInterface) { case 0: // Use both interfaces settings.setValue( "Path" , aLocation ); @@ -182,13 +152,9 @@ bool FTNoIR_Protocol::checkServerInstallationOK() settingsTIR.setValue( "Path" , aLocation ); break; default: - // should never be reached - break; + break; } - // - // TIRViews must be started first, or the NPClient DLL will never be loaded. - // if (s.useTIRViews) { start_tirviews(); } @@ -205,7 +171,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return true; } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.h b/ftnoir_protocol_ft/ftnoir_protocol_ft.h index 0af9ff07..5a9e5cdd 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.h +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.h @@ -25,10 +25,8 @@ * to games, using the FreeTrackClient.dll. * ********************************************************************************/ #pragma once -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" #include "ui_ftnoir_ftcontrols.h" -#include "facetracknoir/global-settings.h" -#include "fttypes.h" +#include "facetracknoir/plugin-api.hpp" #include <QMessageBox> #include <QSettings> #include <QLibrary> @@ -36,34 +34,32 @@ #include <QDebug> #include <QFile> #include <QString> -#include <windows.h> #include <QMutex> #include <QMutexLocker> #include "compat/compat.h" #include "facetracknoir/options.h" +#include "fttypes.h" using namespace options; struct settings { pbundle b; value<int> intUsedInterface; - value<bool> useTIRViews, useDummyExe; + value<bool> useTIRViews; settings() : b(bundle("proto-freetrack")), intUsedInterface(b, "used-interfaces", 0), - useTIRViews(b, "use-memory-hacks", false), - useDummyExe(b, "ezca-mode", false) + useTIRViews(b, "use-memory-hacks", false) {} }; -//typedef char *(WINAPI *importProvider)(void); -typedef void (WINAPI *importTIRViewsStart)(void); -typedef void (WINAPI *importTIRViewsStop)(void); +typedef void (__stdcall *importTIRViewsStart)(void); +typedef void (__stdcall *importTIRViewsStop)(void); class FTNoIR_Protocol : public IProtocol { public: FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol(); + ~FTNoIR_Protocol() override; bool checkServerInstallationOK( ); void sendHeadposeToGame( const double *headpose ); QString getGameName() { @@ -71,14 +67,13 @@ public: return connected_game; } private: - importTIRViewsStart viewsStart; // Functions inside TIRViews.dll + importTIRViewsStart viewsStart; importTIRViewsStop viewsStop; - - FTMemMap *pMemData; + + FTHeap *pMemData; QString game_name; PortableLockedShm shm; - // Private properties QString ProgramName; QLibrary FTIRViewsLib; QProcess dummyTrackIR; diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp index 5ce903b7..3e440607 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp @@ -26,26 +26,14 @@ #include <QDebug> #include <QFileDialog> -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -FTControls::FTControls() : - QWidget() +FTControls::FTControls() { - QString aFileName; // File Path and Name - ui.setupUi( this ); - // Connect Qt signals to member-functions connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL())); - tie_setting(s.useDummyExe, ui.chkStartDummy); tie_setting(s.useTIRViews, ui.chkTIRViews); ui.cbxSelectInterface->addItem("Enable both"); @@ -54,8 +42,8 @@ FTControls::FTControls() : tie_setting(s.intUsedInterface, ui.cbxSelectInterface); - aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; - if ( !QFile::exists( aFileName ) ) { + QFile memhacks_pathname(QCoreApplication::applicationDirPath() + "/TIRViews.dll"); + if (!memhacks_pathname.exists()) { ui.chkTIRViews->setChecked( false ); ui.chkTIRViews->setEnabled ( false ); } @@ -70,27 +58,21 @@ void FTControls::doOK() { } void FTControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } void FTControls::selectDLL() { - QString fileName = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)")); - - // - // Write the location of the file in the required Registry-key. - // - if (! fileName.isEmpty() ) { - if (fileName.endsWith("NPClient.dll", Qt::CaseInsensitive) ) { - QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER) - QString aLocation = fileName.left(fileName.length() - 12); // Location of Client DLL + QString filename = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)")); - settingsTIR.setValue( "Path" , aLocation ); - } + if (! filename.isEmpty() ) { + QSettings node("NaturalPoint", "NATURALPOINT\\NPClient Location"); + QFileInfo dllname(filename); + node.setValue( "Path" , dllname.dir().path() ); } } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog() { return new FTControls; } diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp index 38f11211..d7a13fa5 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp @@ -1,30 +1,7 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ -#include "ftnoir_protocol_ft.h" +#include "facetracknoir/plugin-support.h" +#include "ftnoir_protocol_ft/ftnoir_protocol_ft.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_ft/fttypes.h b/ftnoir_protocol_ft/fttypes.h index ced844dc..f41350c8 100644 --- a/ftnoir_protocol_ft/fttypes.h +++ b/ftnoir_protocol_ft/fttypes.h @@ -16,45 +16,38 @@ * * The FTTypes sources were translated from the original Delphi sources * * * created by the FreeTrack developers. * */ -#ifndef INCLUDED_FTTYPES_H -#define INCLUDED_FTTYPES_H -#if !defined(_WIN32) +#pragma once + +#ifndef _MSC_VER # include <inttypes.h> -typedef int32_t my_32bit_int; -# define WINAPI #else -# include <windows.h> -typedef __int32 my_32bit_int; +typedef unsigned __int32 uint32_t; #endif -//#include "Registry.h" - -// static const char* FT_CLIENT_LOCATION = "Software\\Freetrack\\FreetrackClient"; -//#define FT_CLIENT_FILENAME "FreeTrackClient.Dll" -#define FT_MM_DATA "FT_SharedMem" -//#define FREETRACK "Freetrack" +#define FREETRACK_HEAP "FT_SharedMem" #define FREETRACK_MUTEX "FT_Mutext" -struct TFreeTrackData { +/* only 6 headpose floats and the data id are filled -sh */ +typedef struct __FTData { int DataID; int CamWidth; int CamHeight; - // virtual pose - float Yaw; // positive yaw to the left - float Pitch; // positive pitch up - float Roll; // positive roll to the left + /* virtual pose */ + float Yaw; /* positive yaw to the left */ + float Pitch; /* positive pitch up */ + float Roll; /* positive roll to the left */ float X; float Y; float Z; - // raw pose with no smoothing, sensitivity, response curve etc. + /* raw pose with no smoothing, sensitivity, response curve etc. */ float RawYaw; float RawPitch; float RawRoll; float RawX; float RawY; float RawZ; - // raw points, sorted by Y, origin top left corner + /* raw points, sorted by Y, origin top left corner */ float X1; float Y1; float X2; @@ -63,24 +56,13 @@ struct TFreeTrackData { float Y3; float X4; float Y4; -}; -typedef TFreeTrackData * PFreetrackData; +} FTData; -struct FTMemMap { - TFreeTrackData data; - my_32bit_int GameID; - unsigned char table[8]; - my_32bit_int GameID2; -}; -typedef FTMemMap * PFTMemMap; +/* we add some shit at the end for other legacy proto, sadly */ -//extern bool (*FTGetData) (PFreetrackData data); -// DLL function signatures -// These match those given in FTTypes.pas -// WINAPI is macro for __stdcall defined somewhere in the depths of windows.h -typedef bool (WINAPI *importGetData)(TFreeTrackData * data); -typedef char *(WINAPI *importGetDllVersion)(void); -typedef void (WINAPI *importReportID)(int name); -typedef char *(WINAPI *importProvider)(void); - -#endif//INCLUDED_FTTYPES_H +typedef struct __FTHeap { + FTData data; + int32_t GameID; + unsigned char table[8]; + int32_t GameID2; +} FTHeap; diff --git a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui index 48679f3c..ca811e99 100644 --- a/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui +++ b/ftnoir_protocol_ftn/ftnoir_ftncontrols.ui @@ -1,266 +1,266 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTNControls</class>
- <widget class="QWidget" name="UICFTNControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>411</width>
- <height>169</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>UDP protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="../facetracknoir/main-facetracknoir.qrc">
- <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="4">
- <widget class="QSpinBox" name="spinIPFourthNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinIPFirstNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QSpinBox" name="spinIPSecondNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QSpinBox" name="spinIPThirdNibble">
- <property name="maximumSize">
- <size>
- <width>60</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="maximum">
- <number>255</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>IP-address remote PC</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>1000</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Enter IP-address and port-number for the remote PC.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Remember: you may have to change firewall-settings too!</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinIPFirstNibble</tabstop>
- <tabstop>spinIPSecondNibble</tabstop>
- <tabstop>spinIPThirdNibble</tabstop>
- <tabstop>spinIPFourthNibble</tabstop>
- <tabstop>spinPortNumber</tabstop>
- <tabstop>btnOK</tabstop>
- <tabstop>btnCancel</tabstop>
- </tabstops>
- <resources>
- <include location="../facetracknoir/main-facetracknoir.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFTNControls</class> + <widget class="QWidget" name="UICFTNControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>411</width> + <height>169</height> + </rect> + </property> + <property name="windowTitle"> + <string>UDP protocol settings</string> + </property> + <property name="windowIcon"> + <iconset resource="../facetracknoir/main-facetracknoir.qrc"> + <normaloff>:/images/facetracknoir.png</normaloff>:/images/facetracknoir.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="_vertical_layout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="4"> + <widget class="QSpinBox" name="spinIPFourthNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="spinIPFirstNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="spinIPSecondNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QSpinBox" name="spinIPThirdNibble"> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>IP-address remote PC</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Port-number</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="spinPortNumber"> + <property name="minimum"> + <number>1000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Enter IP-address and port-number for the remote PC.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Remember: you may have to change firewall-settings too!</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QPushButton" name="btnOK"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnCancel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <tabstops> + <tabstop>spinIPFirstNibble</tabstop> + <tabstop>spinIPSecondNibble</tabstop> + <tabstop>spinIPThirdNibble</tabstop> + <tabstop>spinIPFourthNibble</tabstop> + <tabstop>spinPortNumber</tabstop> + <tabstop>btnOK</tabstop> + <tabstop>btnCancel</tabstop> + </tabstops> + <resources> + <include location="../facetracknoir/main-facetracknoir.qrc"/> + </resources> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp index e93a751e..ccff1ba5 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp @@ -27,9 +27,8 @@ ********************************************************************************/ #include "ftnoir_protocol_ftn.h" #include <QFile> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -/** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() { } @@ -49,7 +48,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return outSocket.bind(QHostAddress::Any, 0, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h index 99e6c6a1..c14a7dba 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h @@ -27,14 +27,12 @@ ********************************************************************************/ #pragma once -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_ftnoir_ftncontrols.h" #include <QThread> #include <QUdpSocket> #include <QMessageBox> -#include <math.h> -#include "facetracknoir/global-settings.h" +#include <cmath> +#include "facetracknoir/plugin-api.hpp" #include "facetracknoir/options.h" using namespace options; diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp index 37db314f..8af12ad7 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp @@ -23,7 +23,7 @@ * * ********************************************************************************/ #include "ftnoir_protocol_ftn.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FTNControls::FTNControls() : QWidget() @@ -52,11 +52,11 @@ void FTNControls::doOK() { // Cancel clicked on server-dialog // void FTNControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new FTNControls; } diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp index 99689432..0d24ccf8 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp @@ -23,9 +23,9 @@ * * ********************************************************************************/ #include "ftnoir_protocol_ftn.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp index 70fde395..1840fa03 100644 --- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp +++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp @@ -1,6 +1,5 @@ #include "ftnoir_protocol_libevdev.h" -#include "facetracknoir/global-settings.h" -//#include "ftnoir_tracker_base/ftnoir_tracker_types.h" +#include "facetracknoir/plugin-api.hpp" #include <cstdio> #include <algorithm> @@ -95,7 +94,7 @@ void FTNoIR_Protocol::sendHeadposeToGame(const double* headpose) { (void) libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h index 66f53547..e613885a 100644 --- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h +++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.h @@ -5,11 +5,10 @@ * copyright notice and this permission notice appear in all copies. */ #pragma once -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" #include "ui_ftnoir_libevdev_controls.h" #include <QMessageBox> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" extern "C" { # include <libevdev/libevdev.h> @@ -20,7 +19,7 @@ class FTNoIR_Protocol : public IProtocol { public: FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol(); + ~FTNoIR_Protocol() override; bool checkServerInstallationOK() { return dev != NULL; } @@ -33,7 +32,6 @@ private: struct libevdev_uinput* uidev; }; -// Widget that has controls for FTNoIR protocol client-settings. class LibevdevControls: public QWidget, public IProtocolDialog { Q_OBJECT diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp index bb54c354..d522610b 100644 --- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp +++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dialog.cpp @@ -1,5 +1,5 @@ #include "ftnoir_protocol_libevdev.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" LibevdevControls::LibevdevControls() : QWidget() { @@ -20,7 +20,7 @@ void LibevdevControls::doCancel() { void LibevdevControls::save() { } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new LibevdevControls; } diff --git a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp index 79a22d5e..e258b077 100644 --- a/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp +++ b/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev_dll.cpp @@ -1,6 +1,6 @@ #include "ftnoir_protocol_libevdev.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() { } @@ -10,7 +10,7 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll() } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui index 2705fff7..258ed06a 100644 --- a/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui +++ b/ftnoir_protocol_mouse/ftnoir_mousecontrols.ui @@ -1,205 +1,205 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICMOUSEControls</class>
- <widget class="QWidget" name="UICMOUSEControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>257</width>
- <height>114</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Mouse protocol settings</string>
- </property>
- <property name="windowIcon">
- <iconset resource="win32-mouse-protocol.qrc">
- <normaloff>:/images/mouse.png</normaloff>:/images/mouse.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="1">
- <widget class="QComboBox" name="cbxSelectMouse_Y">
- <property name="maximumSize">
- <size>
- <width>80</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="textLabel2_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Map mouse Y to:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel2_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Map mouse X to:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="cbxSelectMouse_X">
- <property name="maximumSize">
- <size>
- <width>80</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Select Number</string>
- </property>
- <property name="insertPolicy">
- <enum>QComboBox::InsertAlphabetically</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources>
- <include location="win32-mouse-protocol.qrc"/>
- </resources>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICMOUSEControls</class> + <widget class="QWidget" name="UICMOUSEControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>257</width> + <height>114</height> + </rect> + </property> + <property name="windowTitle"> + <string>Mouse protocol settings</string> + </property> + <property name="windowIcon"> + <iconset resource="win32-mouse-protocol.qrc"> + <normaloff>:/images/mouse.png</normaloff>:/images/mouse.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="_vertical_layout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="1"> + <widget class="QComboBox" name="cbxSelectMouse_Y"> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>Select Number</string> + </property> + <property name="insertPolicy"> + <enum>QComboBox::InsertAlphabetically</enum> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="textLabel2_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Map mouse Y to:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="textLabel2_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Map mouse X to:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="cbxSelectMouse_X"> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>Select Number</string> + </property> + <property name="insertPolicy"> + <enum>QComboBox::InsertAlphabetically</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QPushButton" name="btnOK"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnCancel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="win32-mouse-protocol.qrc"/> + </resources> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp index cc8aa11e..47f7a67e 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp @@ -27,12 +27,14 @@ * but no face-tracking. * ********************************************************************************/ #include "ftnoir_protocol_mouse.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" void FTNoIR_Protocol::sendHeadposeToGame(const double *headpose ) { double fMouse_X = 0; double fMouse_Y = 0; + // XXX TODO remove axis selector, use mapping window's + // axis selection. Mention in UI axis used. -sh 20140920 int Mouse_X = s.Mouse_X; int Mouse_Y = s.Mouse_Y; @@ -61,7 +63,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return true; } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h index 01f283d3..8f1f3ff1 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h @@ -30,7 +30,6 @@ #ifndef INCLUDED_MOUSESERVER_H #define INCLUDED_MOUSESERVER_H -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" #include "ui_ftnoir_mousecontrols.h" #include <QMessageBox> #include <QSettings> @@ -40,7 +39,7 @@ #include <QFile> #include <windows.h> #include <winuser.h> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "facetracknoir/options.h" using namespace options; @@ -71,7 +70,6 @@ private: struct settings s; }; -// Widget that has controls for FTNoIR protocol client-settings. class MOUSEControls: public QWidget, public IProtocolDialog { Q_OBJECT @@ -92,9 +90,6 @@ private slots: void doCancel(); }; -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* class FTNoIR_ProtocolDll : public Metadata { public: diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp index 22b7024c..efac958c 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp @@ -23,7 +23,7 @@ * * ********************************************************************************/ #include "ftnoir_protocol_mouse.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" MOUSEControls::MOUSEControls() : _proto(nullptr) { @@ -59,11 +59,11 @@ void MOUSEControls::doOK() { } void MOUSEControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new MOUSEControls; } diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp index 54f6b307..39bdf6e5 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp @@ -23,9 +23,9 @@ * * ********************************************************************************/ #include "ftnoir_protocol_mouse.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp index 2714e980..72b800d2 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp @@ -27,7 +27,7 @@ * must be treated as such... * ********************************************************************************/ #include "ftnoir_protocol_sc.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" importSimConnect_CameraSetRelative6DOF FTNoIR_Protocol::simconnect_set6DOF; HANDLE FTNoIR_Protocol::hSimConnect = 0; // Handle to SimConnect @@ -79,13 +79,11 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) { if (!blnSimConnectActive) { if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) { - HRESULT hr; - simconnect_subscribetosystemevent(hSimConnect, EVENT_PING, "Frame"); - hr = simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, ""); - hr = simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false); - hr = simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST); + simconnect_mapclienteventtosimevent(hSimConnect, EVENT_INIT, ""); + simconnect_addclienteventtonotificationgroup(hSimConnect, GROUP0, EVENT_INIT, false); + simconnect_setnotificationgrouppriority(hSimConnect, GROUP0, SIMCONNECT_GROUP_PRIORITY_HIGHEST); blnSimConnectActive = true; } } @@ -93,6 +91,8 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) { (void) (simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, NULL)); } +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + class ActivationContext { public: ActivationContext(const int resid) { @@ -103,7 +103,7 @@ public: actx.lpResourceName = MAKEINTRESOURCEA(resid); actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; #ifdef _MSC_VER -# define PREFIX "" +# error "MSVC support removed" #else # define PREFIX "lib" #endif @@ -203,7 +203,7 @@ bool FTNoIR_Protocol::checkServerInstallationOK() return true; } -void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) +void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD, void *) { switch(pData->dwID) { @@ -246,7 +246,7 @@ void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData } } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.h b/ftnoir_protocol_sc/ftnoir_protocol_sc.h index a13c0097..02cb7b0e 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.h +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.h @@ -29,7 +29,7 @@ #pragma once #undef _WIN32_WINNT #define _WIN32_WINNT 0x0502 -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" // // Prevent the SimConnect manifest from being merged in the application-manifest // This is necessary to run FaceTrackNoIR on a PC without FSX @@ -38,8 +38,7 @@ #include <windows.h> #include <SimConnect.h> -#include <ftnoir_protocol_base/ftnoir_protocol_base.h> -#include <ui_ftnoir_sccontrols.h> +#include "ui_ftnoir_sccontrols.h" #include <QMessageBox> #include <QSettings> #include <QLibrary> @@ -89,7 +88,7 @@ class FTNoIR_Protocol : public IProtocol { public: FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol(); + ~FTNoIR_Protocol() override; bool checkServerInstallationOK(); void sendHeadposeToGame(const double* headpose); QString getGameName() { @@ -128,13 +127,12 @@ private: settings s; }; -// Widget that has controls for FTNoIR protocol client-settings. class SCControls: public QWidget, public IProtocolDialog { Q_OBJECT public: SCControls(); - void registerProtocol(IProtocol *protocol) {} + void registerProtocol(IProtocol *) {} void unRegisterProtocol() {} private: Ui::UICSCControls ui; @@ -144,9 +142,6 @@ private slots: void doCancel(); }; -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* class FTNoIR_ProtocolDll : public Metadata { public: diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp index c7428d77..c3d64e9d 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp @@ -24,7 +24,7 @@ ********************************************************************************/ #include "ftnoir_protocol_sc.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" SCControls::SCControls() : QWidget() @@ -44,11 +44,11 @@ void SCControls::doOK() { } void SCControls::doCancel() { - s.b->revert(); + s.b->reload(); close(); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new SCControls; } diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp index 0a52fa96..9bdbef09 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp @@ -24,9 +24,9 @@ ********************************************************************************/ #include "ftnoir_protocol_sc.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_sc/ftnoir_sccontrols.ui b/ftnoir_protocol_sc/ftnoir_sccontrols.ui index 87dc8d86..5b2fd291 100644 --- a/ftnoir_protocol_sc/ftnoir_sccontrols.ui +++ b/ftnoir_protocol_sc/ftnoir_sccontrols.ui @@ -1,72 +1,72 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICSCControls</class>
- <widget class="QWidget" name="UICSCControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>290</width>
- <height>79</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>SimConnect settings FaceTrackNoIR</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>FSX version</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboBox">
- <item>
- <property name="text">
- <string>SP1</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>SP2</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Acceleration</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICSCControls</class> + <widget class="QWidget" name="UICSCControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>290</width> + <height>79</height> + </rect> + </property> + <property name="windowTitle"> + <string>SimConnect settings FaceTrackNoIR</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>images/FaceTrackNoIR.png</normaloff>images/FaceTrackNoIR.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>FSX version</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBox"> + <item> + <property name="text"> + <string>SP1</string> + </property> + </item> + <item> + <property name="text"> + <string>SP2</string> + </property> + </item> + <item> + <property name="text"> + <string>Acceleration</string> + </property> + </item> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp index a3a5cb5f..58fa2ab1 100644 --- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp +++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.cpp @@ -1,22 +1,21 @@ #include "ftnoir_protocol_vjoy.h" -#include "facetracknoir/global-settings.h" -#include <ftnoir_tracker_base/ftnoir_tracker_types.h> +#include "facetracknoir/plugin-api.hpp" -/** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() { - VJoy_Initialize("", ""); + static char meh[1] = {0}; + VJoy_Initialize(meh, meh); } -/** destructor **/ FTNoIR_Protocol::~FTNoIR_Protocol() { VJoy_Shutdown(); } void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) { +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" JOYSTICK_STATE state[2] = { 0 }; - + state[0].POV = (4 << 12) | (4 << 8) | (4 << 4) | 4; state[0].XAxis = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[Yaw] * VJOY_AXIS_MAX / 180.0)); @@ -25,11 +24,11 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) { state[0].XRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TX] * VJOY_AXIS_MAX / 100.0)); state[0].YRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TY] * VJOY_AXIS_MAX / 100.0)); state[0].ZRotation = std::min<int>(VJOY_AXIS_MAX, std::max<int>(VJOY_AXIS_MIN, headpose[TZ] * VJOY_AXIS_MAX / 100.0)); - + VJoy_UpdateJoyState(0, state); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT IProtocol* GetConstructor() { return new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h index 873b4e3c..eac3c610 100644 --- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h +++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy.h @@ -26,15 +26,9 @@ * It is based on the (Linux) example made by Melchior FRANZ. * ********************************************************************************/ #pragma once -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" #include "ui_ftnoir_vjoy_controls.h" -#include <QThread> -#include <QUdpSocket> -#include <QMessageBox> -#include <QSettings> -#include <math.h> -#include "facetracknoir/global-settings.h" -#include <windows.h> +#include <cmath> +#include "facetracknoir/plugin-api.hpp" #define FT_PROGRAMID "FT_ProgramID" @@ -42,7 +36,7 @@ class FTNoIR_Protocol : public IProtocol { public: FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol(); + ~FTNoIR_Protocol() override; bool checkServerInstallationOK() { return true; } @@ -60,7 +54,7 @@ class VJoyControls: public QWidget, public IProtocolDialog public: explicit VJoyControls(); - void registerProtocol(IProtocol *l) {} + void registerProtocol(IProtocol *) {} void unRegisterProtocol() {} private: @@ -72,9 +66,6 @@ private slots: void doCancel(); }; -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* class FTNoIR_ProtocolDll : public Metadata { public: @@ -92,6 +83,8 @@ public: #define VJOY_AXIS_NIL 0 #define VJOY_AXIS_MAX 32767 +#include <windows.h> + #include <pshpack1.h> typedef struct _JOYSTICK_STATE @@ -109,17 +102,6 @@ typedef struct _JOYSTICK_STATE UINT32 Buttons; // 32 Buttons } JOYSTICK_STATE, * PJOYSTICK_STATE; -#include <poppack.h> - -#undef EXTERN_C -#if _MSC_VER -# define EXTERN_C -#else -# define EXTERN_C extern "C" -#endif -#if _MSC_VER -# pragma comment(linker, "/implib:vjoy.def") -#endif EXTERN_C BOOL __stdcall VJoy_Initialize(PCHAR name, PCHAR serial); EXTERN_C VOID __stdcall VJoy_Shutdown(); EXTERN_C BOOL __stdcall VJoy_UpdateJoyState(int id, PJOYSTICK_STATE pJoyState); diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp index febb7b18..6bd82d9a 100644 --- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp +++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dialog.cpp @@ -1,5 +1,5 @@ #include "ftnoir_protocol_vjoy.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" VJoyControls::VJoyControls() : QWidget() { @@ -20,7 +20,7 @@ void VJoyControls::doCancel() { void VJoyControls::save() { } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT IProtocolDialog* GetDialog( ) { return new VJoyControls; } diff --git a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp index 5cb5ef05..367a0df6 100644 --- a/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp +++ b/ftnoir_protocol_vjoy/ftnoir_protocol_vjoy_dll.cpp @@ -1,6 +1,6 @@ #include "ftnoir_protocol_vjoy.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() { } @@ -10,7 +10,7 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll() } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp index 58ffe974..29a2a70c 100644 --- a/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp +++ b/ftnoir_protocol_wine/ftnoir_protocol_wine.cpp @@ -3,18 +3,17 @@ #include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ +#include "ftnoir_csv/csv.h" -/** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() : lck_shm(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)), shm(NULL), gameid(0) { if (lck_shm.success()) { - shm = (WineSHM*) lck_shm.mem; + shm = (WineSHM*) lck_shm.ptr(); memset(shm, 0, sizeof(*shm)); } wrapper.start("wine", QStringList() << (QCoreApplication::applicationDirPath() + "/opentrack-wrapper-wine.exe.so")); } -/** destructor **/ FTNoIR_Protocol::~FTNoIR_Protocol() { if (shm) { @@ -52,25 +51,12 @@ void FTNoIR_Protocol::sendHeadposeToGame( const double *headpose ) { } } -// -// Check if the Client DLL exists and load it (to test it), if so. -// Returns 'true' if all seems OK. -// bool FTNoIR_Protocol::checkServerInstallationOK() { return lck_shm.success(); } -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol object. - -// Export both decorated and undecorated names. -// GetProtocol - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocol@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT void* GetConstructor() { return (IProtocol*) new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine.h b/ftnoir_protocol_wine/ftnoir_protocol_wine.h index 50d2bc0c..9a7fb7d5 100644 --- a/ftnoir_protocol_wine/ftnoir_protocol_wine.h +++ b/ftnoir_protocol_wine/ftnoir_protocol_wine.h @@ -1,36 +1,5 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2010 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -* FTServer FTServer is the Class, that communicates headpose-data * -* to games, using the FreeTrackClient.dll. * -********************************************************************************/ #pragma once -#ifndef INCLUDED_FTSERVER_H -#define INCLUDED_FTSERVER_H -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ftnoir_protocol_ft/fttypes.h" -#include "ftnoir_csv/csv.h" #include "ui_ftnoir_winecontrols.h" #include <QMessageBox> #include <QLibrary> @@ -39,15 +8,15 @@ #include <QMutex> #include <QMutexLocker> #include <QFile> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "compat/compat.h" #include "ftnoir_protocol_wine/wine-shm.h" class FTNoIR_Protocol : public IProtocol { public: - FTNoIR_Protocol(); - virtual ~FTNoIR_Protocol(); + FTNoIR_Protocol(); + ~FTNoIR_Protocol() override; bool checkServerInstallationOK(); void sendHeadposeToGame(const double* headpose); @@ -64,7 +33,6 @@ private: QMutex game_name_mutex; }; -// Widget that has controls for FTNoIR protocol client-settings. class FTControls: public QWidget, public IProtocolDialog { Q_OBJECT @@ -77,18 +45,15 @@ private: Ui::UICFTControls ui; private slots: - void doOK(); - void doCancel(); + void doOK(); + void doCancel(); }; -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* class FTNoIR_ProtocolDll : public Metadata { public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Wine"); } void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Wine"); } @@ -96,7 +61,3 @@ public: void getIcon(QIcon *icon) { *icon = QIcon(":/images/wine.png"); } }; - - -#endif//INCLUDED_FTSERVER_H -//END diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp index ecbc2137..c092de42 100644 --- a/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp +++ b/ftnoir_protocol_wine/ftnoir_protocol_wine_dialog.cpp @@ -1,39 +1,23 @@ #include "ftnoir_protocol_wine.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// FTControls::FTControls() : QWidget() { - ui.setupUi( this ); - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + ui.setupUi( this ); + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); } -// -// Destructor for server-dialog - -// -// OK clicked on server-dialog -// void FTControls::doOK() { - this->close(); + this->close(); } -// -// Cancel clicked on server-dialog -// void FTControls::doCancel() { this->close(); } -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT void* GetDialog( ) { return (IProtocolDialog*) new FTControls; } diff --git a/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp b/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp index dd7f17a6..c6e3d433 100644 --- a/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp +++ b/ftnoir_protocol_wine/ftnoir_protocol_wine_dll.cpp @@ -1,25 +1,15 @@ #include "ftnoir_protocol_wine.h" -#include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() { +FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() +{ } FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll() { - } -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol object. - -// Export both decorated and undecorated names. -// GetProtocolDll - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDll@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx index 6e512b6e..40f36f8d 100644 --- a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx +++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx @@ -1,8 +1,13 @@ -#include <errno.h> -#include <stdio.h> +#include <cerrno> +#include <cstdio> #include "ftnoir_protocol_ft/fttypes.h" #include "ftnoir_protocol_wine/wine-shm.h" -#include "ftnoir_tracker_base/ftnoir_tracker_types.h" + +#define OPENTRACK_CROSS_ONLY +#include "facetracknoir/plugin-api.hpp" + +#define OPENTRACK_COMPAT_BUNDLED +#include "compat/compat.h" void create_registry_key(void); @@ -13,8 +18,9 @@ public: void lock(); void unlock(); bool success(); - void* mem; + inline void* ptr() { return mem; } private: + void* mem; int fd, size; }; @@ -25,8 +31,9 @@ public: void lock(); void unlock(); bool success(); - void* mem; + inline void* ptr() { return mem; } private: + void* mem; void *hMutex, *hMapFile; }; #include <windows.h> @@ -34,8 +41,8 @@ private: int main(void) { ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); - ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTMemMap)); - if(!lck_posix.success()) { + ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap)); + if(!lck_posix.success()) { printf("Can't open posix map: %d\n", errno); return 1; } @@ -43,12 +50,11 @@ int main(void) printf("Can't open Wine map\n"); return 1; } - WineSHM* shm_posix = (WineSHM*) lck_posix.mem; - FTMemMap* shm_wine = (FTMemMap*) lck_wine.mem; - TFreeTrackData* data = &shm_wine->data; + WineSHM* shm_posix = (WineSHM*) lck_posix.ptr(); + FTHeap* shm_wine = (FTHeap*) lck_wine.ptr(); + FTData* data = &shm_wine->data; create_registry_key(); while (1) { - (void) Sleep(10); lck_posix.lock(); if (shm_posix->stop) { lck_posix.unlock(); @@ -70,5 +76,6 @@ int main(void) shm_wine->table[i] = shm_posix->table[i]; lck_wine.unlock(); lck_posix.unlock(); + (void) Sleep(4); } } diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx index e7102600..b7dc531c 100644 --- a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx +++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx @@ -1,19 +1,16 @@ -#define OPENTRACK_COMPAT_BUNDLED - #ifndef __WIN32 -#define __WIN32 +# error "bad cross" #endif +#define OPENTRACK_COMPAT_BUNDLED #define PortableLockedShm ShmWine - -#include "ftnoir_protocol_ft/fttypes.h" #include "compat/compat.h" #include "compat/compat.cpp" -#include <string.h> +#include "wine-shm.h" void create_registry_key(void) { char dir[8192]; - + if (GetCurrentDirectoryA(8192, dir) < 8190) { HKEY hkpath; diff --git a/ftnoir_protocol_wine/wine-shm.h b/ftnoir_protocol_wine/wine-shm.h index ddbda8b5..c0f29cd3 100644 --- a/ftnoir_protocol_wine/wine-shm.h +++ b/ftnoir_protocol_wine/wine-shm.h @@ -3,6 +3,10 @@ #define WINE_SHM_NAME "facetracknoir-wine-shm" #define WINE_MTX_NAME "facetracknoir-wine-mtx" +#include <memory> + +template<typename t> using ptr = std::shared_ptr<t>; + struct WineSHM { double data[6]; int gameid, gameid2; diff --git a/ftnoir_tracker_aruco/ar_video_widget.cpp b/ftnoir_tracker_aruco/ar_video_widget.cpp index 9a089213..61a611ea 100644 --- a/ftnoir_tracker_aruco/ar_video_widget.cpp +++ b/ftnoir_tracker_aruco/ar_video_widget.cpp @@ -40,3 +40,15 @@ void ArucoVideoWidget::update_and_repaint() texture = qframe2; update(); } + +void ArucoVideoWidget::paintEvent(QPaintEvent* e) +{ + QMutexLocker foo(&mtx); + QPainter(this).drawImage(e->rect(), texture); +} + +ArucoVideoWidget::ArucoVideoWidget(QWidget* parent): QWidget(parent) +{ + connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint())); + timer.start(60); +}
\ No newline at end of file diff --git a/ftnoir_tracker_aruco/ar_video_widget.h b/ftnoir_tracker_aruco/ar_video_widget.h index e2cf4d9f..820ba7d0 100644 --- a/ftnoir_tracker_aruco/ar_video_widget.h +++ b/ftnoir_tracker_aruco/ar_video_widget.h @@ -22,26 +22,18 @@ class ArucoVideoWidget : public QWidget { Q_OBJECT - -public: - ArucoVideoWidget(QWidget *parent) : QWidget(parent) { - connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint())); - timer.start(60); - } - void update_image(const cv::Mat& frame); -protected slots: - void paintEvent( QPaintEvent* e ) { - QMutexLocker foo(&mtx); - QPainter painter(this); - painter.drawImage(e->rect(), texture); - } - void update_and_repaint(); - + private: QMutex mtx; QImage texture; QTimer timer; cv::Mat _frame; +private slots: + void update_and_repaint(); +public: + ArucoVideoWidget(QWidget *parent); + void update_image(const cv::Mat& frame); + void paintEvent( QPaintEvent*) override; }; #endif // VIDEOWIDGET_H diff --git a/ftnoir_tracker_aruco/aruco-trackercontrols.ui b/ftnoir_tracker_aruco/aruco-trackercontrols.ui index 1d5a4241..099dec02 100644 --- a/ftnoir_tracker_aruco/aruco-trackercontrols.ui +++ b/ftnoir_tracker_aruco/aruco-trackercontrols.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>615</width> - <height>326</height> + <width>562</width> + <height>178</height> </rect> </property> <property name="sizePolicy"> @@ -19,67 +19,160 @@ <verstretch>0</verstretch> </sizepolicy> </property> - <property name="maximumSize"> - <size> - <width>6666</width> - <height>6666</height> - </size> - </property> <property name="windowTitle"> - <string>HT tracker settings</string> + <string>Tracker settings</string> </property> <layout class="QGridLayout" name="gridLayout"> - <property name="spacing"> - <number>7</number> - </property> - <item row="9" column="1" rowspan="3"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Head position</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> + <item row="1" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="2" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>TY</string> + </widget> + </item> + <item row="0" column="0"> + <widget class="QFrame" name="frame"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="1"> + <widget class="QDoubleSpinBox" name="cameraFOV"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <property name="minimum"> + <double>35.000000000000000</double> + </property> + <property name="maximum"> + <double>180.000000000000000</double> + </property> + <property name="value"> + <double>52.000000000000000</double> </property> </widget> </item> <item row="1" column="0"> - <widget class="QLabel" name="label_5"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Frames per second</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Resolution</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> <property name="text"> - <string>TX</string> + <string>Horizontal FOV</string> </property> </widget> </item> <item row="1" column="1"> - <widget class="QDoubleSpinBox" name="cx"> + <widget class="QComboBox" name="cameraFPS"> <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimum"> - <double>-10000.000000000000000</double> + <item> + <property name="text"> + <string notr="true">Default</string> + </property> + </item> + <item> + <property name="text"> + <string>30</string> + </property> + </item> + <item> + <property name="text"> + <string>60</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>180</string> + </property> + </item> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="resolution"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="maximum"> - <double>10000.000000000000000</double> + <item> + <property name="text"> + <string>640x480</string> + </property> + </item> + <item> + <property name="text"> + <string>320x240</string> + </property> + </item> + <item> + <property name="text"> + <string>320x200</string> + </property> + </item> + <item> + <property name="text"> + <string>Default (not recommended!)</string> + </property> + </item> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Camera name</string> </property> </widget> </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_8"> + <item row="2" column="1"> + <widget class="QComboBox" name="cameraName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="1"> + <widget class="QFrame" name="frame_2"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> <property name="text"> - <string>TZ</string> + <string>Head X</string> </property> </widget> </item> - <item row="3" column="1"> - <widget class="QDoubleSpinBox" name="cz"> + <item row="2" column="1"> + <widget class="QDoubleSpinBox" name="cy"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> @@ -94,8 +187,8 @@ </property> </widget> </item> - <item row="2" column="1"> - <widget class="QDoubleSpinBox" name="cy"> + <item row="1" column="1"> + <widget class="QDoubleSpinBox" name="cx"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> @@ -110,264 +203,48 @@ </property> </widget> </item> - </layout> - </widget> - </item> - <item row="0" column="3" rowspan="3" colspan="2"> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Enable axes</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <property name="horizontalSpacing"> - <number>7</number> - </property> - <property name="leftMargin"> - <number>6</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>6</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item row="0" column="0"> - <widget class="QCheckBox" name="rx"> - <property name="text"> - <string>RX</string> + <item row="3" column="1"> + <widget class="QDoubleSpinBox" name="cz"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="tx"> - <property name="text"> - <string>TX</string> + <property name="minimum"> + <double>-10000.000000000000000</double> </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="ry"> - <property name="text"> - <string>RY</string> + <property name="maximum"> + <double>10000.000000000000000</double> </property> </widget> </item> - <item row="1" column="1"> - <widget class="QCheckBox" name="ty"> + <item row="3" column="0"> + <widget class="QLabel" name="label_8"> <property name="text"> - <string>TY</string> + <string>Head Z </string> </property> </widget> </item> <item row="2" column="0"> - <widget class="QCheckBox" name="rz"> + <widget class="QLabel" name="label_7"> <property name="text"> - <string>RZ</string> + <string>Head Y</string> </property> </widget> </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="tz"> + <item row="4" column="1"> + <widget class="QPushButton" name="btn_calibrate"> <property name="text"> - <string>TZ</string> + <string>Calibrate</string> </property> </widget> </item> </layout> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Frames per second</string> - </property> - </widget> - </item> - <item row="2" column="1" colspan="2"> - <widget class="QComboBox" name="cameraName"/> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QComboBox" name="cameraFPS"> - <item> - <property name="text"> - <string notr="true">Default</string> - </property> - </item> - <item> - <property name="text"> - <string>30</string> - </property> - </item> - <item> - <property name="text"> - <string>60</string> - </property> - </item> - <item> - <property name="text"> - <string>120</string> - </property> - </item> - <item> - <property name="text"> - <string>180</string> - </property> - </item> - </widget> - </item> - <item row="7" column="1"> - <widget class="QCheckBox" name="red_only"> - <property name="text"> - <string>Recommended!</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Camera name</string> - </property> - </widget> - </item> - <item row="0" column="1" colspan="2"> - <widget class="QDoubleSpinBox" name="cameraFOV"> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <property name="minimum"> - <double>35.000000000000000</double> - </property> - <property name="maximum"> - <double>180.000000000000000</double> - </property> - <property name="value"> - <double>52.000000000000000</double> - </property> - </widget> - </item> - <item row="6" column="2" rowspan="5" colspan="3"> - <widget class="QLabel" name="label_6"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string><html><head/><body><p>The ARUCO Library has been developed by the Ava group of the Univeristy of Cordoba, Spain</p><p>Rafael Muñoz Salinas &lt;<a href="mailto:rmsalinas@uco.es"><span style=" text-decoration: underline; color:#0057ae;">rmsalinas@uco.es</span></a>&gt;</p><p>&lt;<a href="https://github.com/rmsalinas/aruco"><span style=" text-decoration: underline; color:#0057ae;">https://github.com/rmsalinas/aruco</span></a>&gt;</p></body></html></string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="margin"> - <number>4</number> - </property> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="label_10"> - <property name="text"> - <string>Red channel only</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QComboBox" name="resolution"> - <item> - <property name="text"> - <string>640x480</string> - </property> - </item> - <item> - <property name="text"> - <string>320x240</string> - </property> - </item> - <item> - <property name="text"> - <string>320x200</string> - </property> - </item> - <item> - <property name="text"> - <string>Default (not recommended!)</string> - </property> - </item> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Horizontal FOV</string> - </property> - </widget> - </item> - <item row="11" column="4"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - <item row="8" column="1"> - <widget class="QDoubleSpinBox" name="marker_pitch"> - <property name="minimum"> - <double>-180.000000000000000</double> - </property> - <property name="maximum"> - <double>180.000000000000000</double> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Resolution</string> - </property> - </widget> - </item> - <item row="8" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Marker pitch</string> - </property> - </widget> - </item> </layout> </widget> - <tabstops> - <tabstop>cameraFOV</tabstop> - <tabstop>cameraFPS</tabstop> - <tabstop>cameraName</tabstop> - <tabstop>resolution</tabstop> - <tabstop>red_only</tabstop> - <tabstop>marker_pitch</tabstop> - <tabstop>cx</tabstop> - <tabstop>cy</tabstop> - <tabstop>cz</tabstop> - <tabstop>rx</tabstop> - <tabstop>ry</tabstop> - <tabstop>rz</tabstop> - <tabstop>tx</tabstop> - <tabstop>ty</tabstop> - <tabstop>tz</tabstop> - <tabstop>buttonBox</tabstop> - </tabstops> <resources/> <connections/> <designerdata> diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp index ae7ca0b5..fd8a8ce1 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp @@ -5,17 +5,16 @@ * copyright notice and this permission notice appear in all copies. */ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ftnoir_tracker_aruco.h" -#include "ui_aruco-trackercontrols.h" -#include "facetracknoir/global-settings.h" -#include <cmath> -#include <QMutexLocker> -#include <aruco.h> -#include <opencv2/opencv.hpp> -#include <opencv/highgui.h> #include <vector> #include <cstdio> +#include <cmath> +#include <algorithm> +#include <QMutexLocker> +#include "./include/markerdetector.h" +#include "ftnoir_tracker_aruco.h" +#include "facetracknoir/plugin-api.hpp" +#include <opencv2/core/core.hpp> +#include <opencv2/highgui/highgui.hpp> #if defined(_WIN32) # undef NOMINMAX @@ -30,51 +29,51 @@ static QList<QString> get_camera_names(void) { QList<QString> ret; #if defined(_WIN32) - // Create the System Device Enumerator. - HRESULT hr; - ICreateDevEnum *pSysDevEnum = NULL; - hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); - if (FAILED(hr)) - { - return ret; - } - // Obtain a class enumerator for the video compressor category. - IEnumMoniker *pEnumCat = NULL; - hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); - - if (hr == S_OK) { - // Enumerate the monikers. - IMoniker *pMoniker = NULL; - ULONG cFetched; - while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { - IPropertyBag *pPropBag; - hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); - if (SUCCEEDED(hr)) { - // To retrieve the filter's friendly name, do the following: - VARIANT varName; - VariantInit(&varName); - hr = pPropBag->Read(L"FriendlyName", &varName, 0); - if (SUCCEEDED(hr)) - { - // Display the name in your UI somehow. - QString str((QChar*)varName.bstrVal, wcslen(varName.bstrVal)); - ret.append(str); - } - VariantClear(&varName); - - ////// To create an instance of the filter, do the following: - ////IBaseFilter *pFilter; - ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, - //// (void**)&pFilter); - // Now add the filter to the graph. - //Remember to release pFilter later. - pPropBag->Release(); - } - pMoniker->Release(); - } - pEnumCat->Release(); - } - pSysDevEnum->Release(); + // Create the System Device Enumerator. + HRESULT hr; + ICreateDevEnum *pSysDevEnum = NULL; + hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); + if (FAILED(hr)) + { + return ret; + } + // Obtain a class enumerator for the video compressor category. + IEnumMoniker *pEnumCat = NULL; + hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); + + if (hr == S_OK) { + // Enumerate the monikers. + IMoniker *pMoniker = NULL; + ULONG cFetched; + while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); + if (SUCCEEDED(hr)) { + // To retrieve the filter's friendly name, do the following: + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + if (SUCCEEDED(hr)) + { + // Display the name in your UI somehow. + QString str((QChar*)varName.bstrVal, wcslen(varName.bstrVal)); + ret.append(str); + } + VariantClear(&varName); + + ////// To create an instance of the filter, do the following: + ////IBaseFilter *pFilter; + ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, + //// (void**)&pFilter); + // Now add the filter to the graph. + //Remember to release pFilter later. + pPropBag->Release(); + } + pMoniker->Release(); + } + pEnumCat->Release(); + } + pSysDevEnum->Release(); #else for (int i = 0; i < 16; i++) { char buf[128]; @@ -90,15 +89,15 @@ static QList<QString> get_camera_names(void) { } typedef struct { - int width; - int height; + int width; + int height; } resolution_tuple; static resolution_tuple resolution_choices[] = { - { 640, 480 }, - { 320, 240 }, - { 320, 200 }, - { 0, 0 } + { 640, 480 }, + { 320, 240 }, + { 320, 200 }, + { 0, 0 } }; Tracker::Tracker() : stop(false), layout(nullptr), videoWidget(nullptr) @@ -109,8 +108,8 @@ Tracker::~Tracker() { stop = true; wait(); - if (videoWidget) - delete videoWidget; + if (videoWidget) + delete videoWidget; if(layout) delete layout; qDebug() << "releasing camera, brace for impact"; @@ -137,12 +136,20 @@ void Tracker::StartTracker(QFrame* videoframe) #define HT_PI 3.1415926535 +void Tracker::getRT(cv::Matx33d& r_, cv::Vec3d& t_) +{ + QMutexLocker l(&mtx); + + r_ = r; + t_ = t; +} + void Tracker::run() { - int res = s.resolution; - if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple))) - res = 0; - resolution_tuple r = resolution_choices[res]; + int rint = s.resolution; + if (rint < 0 || rint >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple))) + rint = 0; + resolution_tuple res = resolution_choices[rint]; int fps; switch (static_cast<int>(s.force_fps)) { @@ -164,23 +171,19 @@ void Tracker::run() break; } camera = cv::VideoCapture(s.camera_index); - if (r.width) + if (res.width) { - camera.set(CV_CAP_PROP_FRAME_WIDTH, r.width); - camera.set(CV_CAP_PROP_FRAME_HEIGHT, r.height); + camera.set(CV_CAP_PROP_FRAME_WIDTH, res.width); + camera.set(CV_CAP_PROP_FRAME_HEIGHT, res.height); } if (fps) camera.set(CV_CAP_PROP_FPS, fps); - + aruco::MarkerDetector detector; detector.setDesiredSpeed(3); cv::Rect last_roi(65535, 65535, 0, 0); - cv::Mat color, color_, grayscale, rvec, tvec; - - const double stateful_coeff = 0.88; - if (!camera.isOpened()) { fprintf(stderr, "aruco tracker: can't open camera\n"); @@ -191,23 +194,17 @@ void Tracker::run() auto last_time = cv::getTickCount(); int cur_fps = 0; int last_fps = 0; - cv::Point2f last_centroid; - bool first = true; while (!stop) { - if (!camera.read(color_)) + cv::Mat color; + if (!camera.read(color)) continue; auto tm = cv::getTickCount(); - color_.copyTo(color); - if (s.red_only) - { - cv::Mat channel[3]; - cv::split(color, channel); - grayscale = channel[2]; - } else - cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY); - + + cv::Mat grayscale; + cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY); + const int scale = frame.cols > 480 ? 2 : 1; detector.setThresholdParams(scale > 1 ? 11 : 7, 4); @@ -225,27 +222,33 @@ void Tracker::run() const double size_min = 0.04; const double size_max = 0.38; - - if (last_roi.width > 0 && - (detector.detect(grayscale(last_roi), markers, cv::Mat(), cv::Mat(), -1, false), - markers.size() == 1 && markers[0].size() == 4)) + + bool roi_valid = false; + + if (last_roi.width > 0 && last_roi.height) { detector.setMinMaxSize(std::max(0.01, size_min * grayscale.cols / last_roi.width), std::min(1.0, size_max * grayscale.cols / last_roi.width)); - auto& m = markers.at(0); - for (int i = 0; i < 4; i++) + if (detector.detect(grayscale(last_roi), markers, cv::Mat(), cv::Mat(), -1, false), + markers.size() == 1 && markers[0].size() == 4) { - auto& p = m.at(i); - p.x += last_roi.x; - p.y += last_roi.y; + auto& m = markers.at(0); + for (int i = 0; i < 4; i++) + { + auto& p = m.at(i); + p.x += last_roi.x; + p.y += last_roi.y; + } + roi_valid = true; } } - else + + if (!roi_valid) { detector.setMinMaxSize(size_min, size_max); detector.detect(grayscale, markers, cv::Mat(), cv::Mat(), -1, false); } - + if (markers.size() == 1 && markers[0].size() == 4) { const auto& m = markers.at(0); for (int i = 0; i < 4; i++) @@ -268,97 +271,122 @@ void Tracker::run() frame = color.clone(); ::sprintf(buf, "Hz: %d", last_fps); - cv::putText(frame, buf, cv::Point(10, 32), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(0, 255, 0), scale); + cv::putText(frame, buf, cv::Point(10, 32), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(0, 255, 0), 1); ::sprintf(buf, "Jiffies: %ld", (long) (10000 * (time - tm) / freq)); - cv::putText(frame, buf, cv::Point(10, 54), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(80, 255, 0), scale); - + cv::putText(frame, buf, cv::Point(10, 54), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(80, 255, 0), 1); + if (markers.size() == 1 && markers[0].size() == 4) { const auto& m = markers.at(0); const float size = 40; - - const double p = s.marker_pitch; - const double sq = sin(p * HT_PI / 180); - const double cq = cos(p * HT_PI / 180); cv::Mat obj_points(4,3,CV_32FC1); - obj_points.at<float>(1,0)=-size + s.headpos_x; - obj_points.at<float>(1,1)=-size * cq + s.headpos_y; - obj_points.at<float>(1,2)=-size * sq + s.headpos_z; - obj_points.at<float>(2,0)=size + s.headpos_x; - obj_points.at<float>(2,1)=-size * cq + s.headpos_y; - obj_points.at<float>(2,2)=-size * sq + s.headpos_z; - obj_points.at<float>(3,0)=size + s.headpos_x; - obj_points.at<float>(3,1)=size * cq + s.headpos_y; - obj_points.at<float>(3,2)=size * sq + s.headpos_z; - obj_points.at<float>(0,0)=-size + s.headpos_x; - obj_points.at<float>(0,1)=size * cq + s.headpos_y; - obj_points.at<float>(0,2)=size * sq + s.headpos_z; - - last_roi = cv::Rect(65535, 65535, 0, 0); - + const int x1=1, x2=2, x3=3, x4=0; + obj_points.at<float>(x1,0)=-size + s.headpos_x; + obj_points.at<float>(x1,1)=-size + s.headpos_y; + obj_points.at<float>(x1,2)= 0 + s.headpos_z; + + obj_points.at<float>(x2,0)=size + s.headpos_x; + obj_points.at<float>(x2,1)=-size + s.headpos_y; + obj_points.at<float>(x2,2)= 0 + s.headpos_z; + + obj_points.at<float>(x3,0)=size + s.headpos_x; + obj_points.at<float>(x3,1)=size + s.headpos_y; + obj_points.at<float>(x3,2)= 0 + s.headpos_z; + + obj_points.at<float>(x4,0)= -size + s.headpos_x; + obj_points.at<float>(x4,1)= size + s.headpos_y; + obj_points.at<float>(x4,2)= 0 + s.headpos_z; + + cv::Vec3d rvec, tvec; + + cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, false, cv::P3P); + + std::vector<cv::Point2f> roi_projection(4); + + { + std::vector<cv::Point2f> repr2; + std::vector<cv::Point3f> centroid; + centroid.push_back(cv::Point3f(0, 0, 0)); + cv::projectPoints(centroid, rvec, tvec, intrinsics, dist_coeffs, repr2); + + { + auto s = cv::Scalar(255, 0, 255); + cv::circle(frame, repr2.at(0), 4, s, -1); + } + } + for (int i = 0; i < 4; i++) { - auto foo = m.at(i); - last_roi.x = std::min<int>(foo.x, last_roi.x); - last_roi.y = std::min<int>(foo.y, last_roi.y); - last_roi.width = std::max<int>(foo.x, last_roi.width); - last_roi.height = std::max<int>(foo.y, last_roi.height); + obj_points.at<float>(i, 0) -= s.headpos_x; + obj_points.at<float>(i, 1) -= s.headpos_y; + obj_points.at<float>(i, 2) -= s.headpos_z; } + + { + cv::Mat rvec_, tvec_; + cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec_, tvec_, false, cv::P3P); + tvec = tvec_; + } + + cv::Mat roi_points = obj_points * c_search_window; + cv::projectPoints(roi_points, rvec, tvec, intrinsics, dist_coeffs, roi_projection); + + last_roi = cv::Rect(color.cols-1, color.rows-1, 0, 0); + + for (int i = 0; i < 4; i++) { - last_roi.width -= last_roi.x; - last_roi.height -= last_roi.y; - last_roi.x -= last_roi.width * stateful_coeff; - last_roi.y -= last_roi.height * stateful_coeff; - last_roi.width *= stateful_coeff * 3; - last_roi.height *= stateful_coeff * 3; - last_roi.x = std::max<int>(0, last_roi.x); - last_roi.y = std::max<int>(0, last_roi.y); - last_roi.width = std::min<int>(grayscale.cols - last_roi.x, last_roi.width); - last_roi.height = std::min<int>(grayscale.rows - last_roi.y, last_roi.height); + auto proj = roi_projection[i]; + int min_x = std::min<int>(proj.x, last_roi.x), + min_y = std::min<int>(proj.y, last_roi.y); + + int max_x = std::max<int>(proj.x, last_roi.width), + max_y = std::max<int>(proj.y, last_roi.height); + + last_roi.x = min_x; + last_roi.y = min_y; + + last_roi.width = max_x; + last_roi.height = max_y; } + + if (last_roi.x < 0) + last_roi.x = 0; + if (last_roi.y < 0) + last_roi.y = 0; + + if (last_roi.width+1 > color.cols) + last_roi.width = color.cols-1; + + if (last_roi.height+1 > color.rows) + last_roi.height = color.rows-1; - cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, !first, cv::ITERATIVE); - first = false; - cv::Mat rotation_matrix = cv::Mat::zeros(3, 3, CV_64FC1); - cv::Mat junk1(3, 3, CV_64FC1), junk2(3, 3, CV_64FC1); - cv::Rodrigues(rvec, rotation_matrix); + last_roi.width -= last_roi.x; + last_roi.height -= last_roi.y; + + auto rmat = cv::Matx33d::zeros(); + cv::Matx33d m_r(3, 3, CV_64FC1), m_q(3, 3, CV_64FC1); + cv::Rodrigues(rvec, rmat); { - cv::Vec3d euler = cv::RQDecomp3x3(rotation_matrix, junk1, junk2); - - if (fabs(euler[0]) + fabs(s.marker_pitch) > 60) - { - first = true; - qDebug() << "reset levmarq due to pitch breakage"; - } + cv::Vec3d euler = cv::RQDecomp3x3(rmat, m_r, m_q); QMutexLocker lck(&mtx); for (int i = 0; i < 3; i++) - pose[i] = tvec.at<double>(i); - + pose[i] = tvec(i); pose[Yaw] = euler[1]; pose[Pitch] = -euler[0]; pose[Roll] = euler[2]; - } - std::vector<cv::Point2f> repr2; - std::vector<cv::Point3f> centroid; - centroid.push_back(cv::Point3f(0, 0, 0)); - cv::projectPoints(centroid, rvec, tvec, intrinsics, dist_coeffs, repr2); - - { - auto s = cv::Scalar(255, 0, 255); - cv::circle(frame, repr2.at(0), 4, s, -1); + r = rmat; + t = tvec; } - - last_centroid = repr2[0]; + + if (roi_valid) + cv::rectangle(frame, last_roi, cv::Scalar(255, 0, 255), 1); } else - { last_roi = cv::Rect(65535, 65535, 0, 0); - first = true; - } if (frame.rows > 0) videoWidget->update_image(frame); @@ -368,28 +396,22 @@ void Tracker::run() void Tracker::GetHeadPoseData(double *data) { QMutexLocker lck(&mtx); - - if (s.eyaw) - data[Yaw] = pose[Yaw]; - if (s.epitch) - data[Pitch] = pose[Pitch]; - if (s.eroll) - data[Roll] = pose[Roll]; - if (s.ex) - data[TX] = pose[TX] * .1; - if (s.ey) - data[TY] = pose[TY] * .1; - if (s.ez) - data[TZ] = pose[TZ] * .1; + + data[Yaw] = pose[Yaw]; + data[Pitch] = pose[Pitch]; + data[Roll] = pose[Roll]; + data[TX] = pose[TX] * .1; + data[TY] = pose[TY] * .1; + data[TZ] = pose[TZ] * .1; } class TrackerDll : public Metadata { - // ITrackerDll interface - void getFullName(QString *strToBeFilled); - void getShortName(QString *strToBeFilled); - void getDescription(QString *strToBeFilled); - void getIcon(QIcon *icon); + // ITrackerDll interface + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); }; //----------------------------------------------------------------------------- @@ -400,12 +422,12 @@ void TrackerDll::getFullName(QString *strToBeFilled) void TrackerDll::getShortName(QString *strToBeFilled) { - *strToBeFilled = "aruco"; + *strToBeFilled = "aruco"; } void TrackerDll::getDescription(QString *strToBeFilled) { - *strToBeFilled = ""; + *strToBeFilled = ""; } void TrackerDll::getIcon(QIcon *icon) @@ -417,28 +439,19 @@ void TrackerDll::getIcon(QIcon *icon) //----------------------------------------------------------------------------- //#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { - return new TrackerDll; + return new TrackerDll; } //#pragma comment(linker, "/export:GetTracker=_GetTracker@0") -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new Tracker; } -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Tracker-settings dialog object. - -// Export both decorated and undecorated names. -// GetTrackerDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetTrackerDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") - -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) { return new TrackerControls; } @@ -446,26 +459,54 @@ extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDial TrackerControls::TrackerControls() { tracker = nullptr; - ui.setupUi(this); + calib_timer.setInterval(200); + ui.setupUi(this); setAttribute(Qt::WA_NativeWindow, true); + ui.cameraName->addItems(get_camera_names()); tie_setting(s.camera_index, ui.cameraName); - tie_setting(s.resolution, ui.resolution); + tie_setting(s.resolution, ui.resolution); tie_setting(s.force_fps, ui.cameraFPS); tie_setting(s.fov, ui.cameraFOV); - tie_setting(s.eyaw, ui.rx); - tie_setting(s.epitch, ui.ry); - tie_setting(s.eroll, ui.rz); - tie_setting(s.ex, ui.tx); - tie_setting(s.ey, ui.ty); - tie_setting(s.ez, ui.tz); tie_setting(s.headpos_x, ui.cx); tie_setting(s.headpos_y, ui.cy); tie_setting(s.headpos_z, ui.cz); - tie_setting(s.red_only, ui.red_only); - tie_setting(s.marker_pitch, ui.marker_pitch); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - ui.cameraName->addItems(get_camera_names()); + connect(ui.btn_calibrate, SIGNAL(clicked()), this, SLOT(toggleCalibrate())); + connect(this, SIGNAL(destroyed()), this, SLOT(cleanupCalib())); + connect(&calib_timer, SIGNAL(timeout()), this, SLOT(update_tracker_calibration())); +} + +void TrackerControls::toggleCalibrate() +{ + if (!calib_timer.isActive()) + { + calibrator.reset(); + calib_timer.start(); + } else { + cleanupCalib(); + } +} + +void TrackerControls::cleanupCalib() +{ + if (calib_timer.isActive()) + calib_timer.stop(); +} + +void TrackerControls::update_tracker_calibration() +{ + if (calib_timer.isActive() && tracker) + { + cv::Matx33d r; + cv::Vec3d t; + tracker->getRT(r, t); + calibrator.update(r, t); + auto pos = calibrator.get_estimate() * .1; + s.headpos_x = pos(0); + s.headpos_y = pos(1); + s.headpos_z = pos(2); + } } void TrackerControls::doOK() @@ -473,11 +514,11 @@ void TrackerControls::doOK() s.b->save(); if (tracker) tracker->reload(); - this->close(); + this->close(); } void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h index 4cab84b5..3d37dacd 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h @@ -5,10 +5,8 @@ * copyright notice and this permission notice appear in all copies. */ -#ifndef FTNOIR_TRACKER_HT_H -#define FTNOIR_TRACKER_HT_H +#pragma once -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_aruco-trackercontrols.h" #include "ar_video_widget.h" #include <QObject> @@ -16,18 +14,20 @@ #include <QMutex> #include <QHBoxLayout> #include <QDialog> -#include <opencv2/opencv.hpp> -#include <opencv/highgui.h> +#include <QTimer> #include "facetracknoir/options.h" +#include "ftnoir_tracker_aruco/trans_calib.h" +#include "facetracknoir/plugin-api.hpp" + +#include <opencv2/core/core.hpp> +#include <opencv2/highgui/highgui.hpp> + using namespace options; struct settings { pbundle b; value<double> fov, headpos_x, headpos_y, headpos_z; value<int> camera_index, force_fps, resolution; - value<bool> red_only; - value<bool> eyaw, epitch, eroll, ex, ey, ez; - value<double> marker_pitch; settings() : b(bundle("aruco-tracker")), fov(b, "field-of-view", 56), @@ -36,59 +36,52 @@ struct settings { headpos_z(b, "headpos-z", 0), camera_index(b, "camera-index", 0), force_fps(b, "force-fps", 0), - resolution(b, "force-resolution", 0), - red_only(b, "red-only", false), - eyaw(b, "enable-y", true), - epitch(b, "enable-p", true), - eroll(b, "enable-r", true), - ex(b, "enable-x", true), - ey(b, "enable-y", true), - ez(b, "enable-z", true), - marker_pitch(b, "marker-pitch", 0) + resolution(b, "force-resolution", 0) {} }; class Tracker : protected QThread, public ITracker { Q_OBJECT + static constexpr double c_search_window = 2.2; public: - Tracker(); - virtual ~Tracker(); + Tracker(); + ~Tracker() override; void StartTracker(QFrame* frame); void GetHeadPoseData(double *data); void run(); void reload() { s.b->reload(); } + void getRT(cv::Matx33d &r, cv::Vec3d &t); private: QMutex mtx; volatile bool stop; QHBoxLayout* layout; - ArucoVideoWidget* videoWidget; + ArucoVideoWidget* videoWidget; settings s; double pose[6]; cv::Mat frame; cv::VideoCapture camera; + cv::Matx33d r; + cv::Vec3d t; }; -// Widget that has controls for FTNoIR protocol client-settings. class TrackerControls : public QWidget, public ITrackerDialog { Q_OBJECT public: TrackerControls(); - void registerTracker(ITracker * x) { - tracker = dynamic_cast<Tracker*>(x); - } - void unRegisterTracker() { - tracker = nullptr; - } + void registerTracker(ITracker * x) { tracker = dynamic_cast<Tracker*>(x); } + void unRegisterTracker() { tracker = nullptr; } private: - Ui::Form ui; + Ui::Form ui; Tracker* tracker; settings s; + TranslationCalibrator calibrator; + QTimer calib_timer; private slots: - void doOK(); - void doCancel(); + void doOK(); + void doCancel(); + void toggleCalibrate(); + void cleanupCalib(); + void update_tracker_calibration(); }; - -#endif - diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h index ffdc5262..66e57100 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h @@ -5,8 +5,7 @@ * copyright notice and this permission notice appear in all copies. */ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" //----------------------------------------------------------------------------- class TrackerDll : public Metadata diff --git a/ftnoir_tracker_aruco/include/boarddetector.h b/ftnoir_tracker_aruco/include/boarddetector.h index 4770b5c9..a0ee2361 100644 --- a/ftnoir_tracker_aruco/include/boarddetector.h +++ b/ftnoir_tracker_aruco/include/boarddetector.h @@ -134,6 +134,6 @@ private: }; -} +}; #endif diff --git a/ftnoir_tracker_aruco/include/cameraparameters.h b/ftnoir_tracker_aruco/include/cameraparameters.h index c3381a74..a419afbe 100644 --- a/ftnoir_tracker_aruco/include/cameraparameters.h +++ b/ftnoir_tracker_aruco/include/cameraparameters.h @@ -28,7 +28,7 @@ or implied, of Rafael Muñoz Salinas. #ifndef _Aruco_CameraParameters_H #define _Aruco_CameraParameters_H #include "exports.h" -#include <opencv2/opencv.hpp> +#include <opencv2/core/core.hpp> #include <string> using namespace std; namespace aruco @@ -105,7 +105,7 @@ public: * @param invert: indicates if the output projection matrix has to yield a horizontally inverted image because image data has not been stored in the order of glDrawPixels: bottom-to-top. */ void glGetProjectionMatrix( cv::Size orgImgSize, cv::Size size,double proj_matrix[16],double gnear,double gfar,bool invert=false )throw(cv::Exception); - + /** * setup camera for an Ogre project. * Use: @@ -117,7 +117,7 @@ public: * As in OpenGL, it assumes no camera distorsion */ void OgreGetProjectionMatrix( cv::Size orgImgSize, cv::Size size,double proj_matrix[16],double gnear,double gfar,bool invert=false )throw(cv::Exception); - + private: //GL routines diff --git a/ftnoir_tracker_aruco/include/cvdrawingutils.h b/ftnoir_tracker_aruco/include/cvdrawingutils.h index 38e9986e..ff67242f 100644 --- a/ftnoir_tracker_aruco/include/cvdrawingutils.h +++ b/ftnoir_tracker_aruco/include/cvdrawingutils.h @@ -46,7 +46,7 @@ namespace aruco static void draw3dCube(cv::Mat &Image,Board &m,const CameraParameters &CP); }; -} +}; #endif diff --git a/ftnoir_tracker_aruco/include/exports.h b/ftnoir_tracker_aruco/include/exports.h index 154605ec..aaeb94e4 100644 --- a/ftnoir_tracker_aruco/include/exports.h +++ b/ftnoir_tracker_aruco/include/exports.h @@ -25,7 +25,7 @@ The views and conclusions contained in the software and documentation are those authors and should not be interpreted as representing official policies, either expressed or implied, of Rafael Muñoz Salinas. ********************************/ - + #ifndef __OPENARUCO_CORE_TYPES_H__ @@ -37,9 +37,9 @@ or implied, of Rafael Muñoz Salinas. #if (defined WIN32 || defined _WIN32 || defined WINCE) && defined DSO_EXPORTS - #define ARUCO_EXPORTS __declspec(dllexport) + #define ARUCO_EXPORTS __declspec(dllexport) #else - #define ARUCO_EXPORTS + #define ARUCO_EXPORTS __attribute__ ((visibility ("default"))) #endif diff --git a/ftnoir_tracker_aruco/include/marker.h b/ftnoir_tracker_aruco/include/marker.h index dc6bb28c..89961002 100644 --- a/ftnoir_tracker_aruco/include/marker.h +++ b/ftnoir_tracker_aruco/include/marker.h @@ -29,7 +29,7 @@ or implied, of Rafael Muñoz Salinas. #define _Aruco_Marker_H #include <vector> #include <iostream> -#include <opencv2/opencv.hpp> +#include <opencv2/core/core.hpp> #include "exports.h" #include "cameraparameters.h" using namespace std; @@ -81,12 +81,12 @@ public: * @param setYPerperdicular If set the Y axis will be perpendicular to the surface. Otherwise, it will be the Z axis */ void calculateExtrinsics(float markerSize,cv::Mat CameraMatrix,cv::Mat Distorsion=cv::Mat(),bool setYPerperdicular=true)throw(cv::Exception); - + /**Given the extrinsic camera parameters returns the GL_MODELVIEW matrix for opengl. * Setting this matrix, the reference coordinate system will be set in this marker */ void glGetModelViewMatrix( double modelview_matrix[16])throw(cv::Exception); - + /** * Returns position vector and orientation quaternion for an Ogre scene node or entity. * Use: @@ -97,8 +97,8 @@ public: * mySceneNode->setOrientation( ogreOrient ); * ... */ - void OgreGetPoseParameters( double position[3], double orientation[4] )throw(cv::Exception); - + void OgreGetPoseParameters( double position[3], double orientation[4] )throw(cv::Exception); + /**Returns the centroid of the marker */ cv::Point2f getCenter()const; @@ -132,11 +132,11 @@ public: return str; } - - + + private: void rotateXAxis(cv::Mat &rotation); - + }; } diff --git a/ftnoir_tracker_aruco/include/markerdetector.h b/ftnoir_tracker_aruco/include/markerdetector.h index 4d6e7b90..6f489c34 100644 --- a/ftnoir_tracker_aruco/include/markerdetector.h +++ b/ftnoir_tracker_aruco/include/markerdetector.h @@ -27,7 +27,7 @@ or implied, of Rafael Muñoz Salinas. ********************************/ #ifndef _ARUCO_MarkerDetector_H #define _ARUCO_MarkerDetector_H -#include <opencv2/opencv.hpp> +#include <opencv2/core/core.hpp> #include <cstdio> #include <iostream> #include "cameraparameters.h" @@ -47,27 +47,25 @@ class ARUCO_EXPORTS MarkerDetector class MarkerCandidate: public Marker{ public: MarkerCandidate(){} - MarkerCandidate(const Marker &M): Marker(M){} + MarkerCandidate(const Marker &M): Marker(M){} MarkerCandidate(const MarkerCandidate &M): Marker(M){ contour=M.contour; idx=M.idx; } - MarkerCandidate operator=(const MarkerCandidate &M){ - if (this == &M) - return *this; + MarkerCandidate & operator=(const MarkerCandidate &M){ (*(Marker*)this)=(*(Marker*)&M); contour=M.contour; idx=M.idx; - return M; + return *this; } - + vector<cv::Point> contour;//all the points of its contour int idx;//index position in the global contour list }; public: /** - * See + * See */ MarkerDetector(); @@ -161,17 +159,17 @@ public: * of cols and rows. * @param min size of the contour to consider a possible marker as valid (0,1] * @param max size of the contour to consider a possible marker as valid [0,1) - * + * */ void setMinMaxSize(float min=0.03,float max=0.5)throw(cv::Exception); - + /**reads the min and max sizes employed * @param min output size of the contour to consider a possible marker as valid (0,1] * @param max output size of the contour to consider a possible marker as valid [0,1) - * + * */ void getMinMaxSize(float &min,float &max){min=_minSize;max=_maxSize;} - + /**Enables/Disables erosion process that is REQUIRED for chessboard like boards. * By default, this property is enabled */ @@ -210,10 +208,10 @@ public: markerIdDetector_ptrfunc=markerdetector_func; } - /** Use an smaller version of the input image for marker detection. + /** Use an smaller version of the input image for marker detection. * If your marker is small enough, you can employ an smaller image to perform the detection without noticeable reduction in the precision. * Internally, we are performing a pyrdown operation - * + * * @param level number of times the image size is divided by 2. Internally, we are performing a pyrdown. */ void pyrDown(unsigned int level){pyrdown_level=level;} @@ -247,17 +245,17 @@ public: * @return true if the operation succeed */ bool warp(cv::Mat &in,cv::Mat &out,cv::Size size, std::vector<cv::Point2f> points)throw (cv::Exception); - - - + + + /** Refine MarkerCandidate Corner using LINES method * @param candidate candidate to refine corners */ - void refineCandidateLines(MarkerCandidate &candidate); - - + void refineCandidateLines(MarkerCandidate &candidate); + + /**DEPRECATED!!! Use the member function in CameraParameters - * + * * Given the intrinsic camera parameters returns the GL_PROJECTION matrix for opengl. * PLease NOTE that when using OpenGL, it is assumed no camera distorsion! So, if it is not true, you should have * undistor image @@ -308,26 +306,26 @@ private: */ int perimeter(std::vector<cv::Point2f> &a); - + // //GL routines -// +// // static void argConvGLcpara2( double cparam[3][4], int width, int height, double gnear, double gfar, double m[16], bool invert )throw(cv::Exception); // static int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] )throw(cv::Exception); // static double norm( double a, double b, double c ); // static double dot( double a1, double a2, double a3, // double b1, double b2, double b3 ); -// +// //detection of the void findBestCornerInRegion_harris(const cv::Mat & grey,vector<cv::Point2f> & Corners,int blockSize); - - + + // auxiliar functions to perform LINES refinement void interpolate2Dline( const vector< cv::Point > &inPoints, cv::Point3f &outLine); - cv::Point2f getCrossPoint(const cv::Point3f& line1, const cv::Point3f& line2); - - - /**Given a vector vinout with elements and a boolean vector indicating the lements from it to remove, + cv::Point2f getCrossPoint(const cv::Point3f& line1, const cv::Point3f& line2); + + + /**Given a vector vinout with elements and a boolean vector indicating the lements from it to remove, * this function remove the elements * @param vinout * @param toRemove @@ -353,5 +351,9 @@ private: void draw(cv::Mat out,const std::vector<Marker> &markers ); }; -} + + + + +}; #endif diff --git a/ftnoir_tracker_aruco/trans_calib.cpp b/ftnoir_tracker_aruco/trans_calib.cpp new file mode 100644 index 00000000..369de449 --- /dev/null +++ b/ftnoir_tracker_aruco/trans_calib.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "trans_calib.h" + +using namespace cv; + +//----------------------------------------------------------------------------- +TranslationCalibrator::TranslationCalibrator() +{ + reset(); +} + +void TranslationCalibrator::reset() +{ + P = Matx66f::zeros(); + y = Vec6f(0,0,0, 0,0,0); +} + +void TranslationCalibrator::update(const Matx33d& R_CM_k, const Vec3d& t_CM_k) +{ + Matx<double, 6,3> H_k_T = Matx<double, 6,3>::zeros(); + for (int i=0; i<3; ++i) { + for (int j=0; j<3; ++j) { + H_k_T(i,j) = R_CM_k(j,i); + } + } + for (int i=0; i<3; ++i) + { + H_k_T(3+i,i) = 1.0; + } + P += H_k_T * H_k_T.t(); + y += H_k_T * t_CM_k; +} + +Vec3f TranslationCalibrator::get_estimate() +{ + Vec6f x = P.inv() * y; + return Vec3f(x[0], x[1], x[2]); +} diff --git a/FTNoIR_Tracker_PT/trans_calib.h b/ftnoir_tracker_aruco/trans_calib.h index f2521690..5a2d7c0f 100644 --- a/FTNoIR_Tracker_PT/trans_calib.h +++ b/ftnoir_tracker_aruco/trans_calib.h @@ -1,39 +1,39 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef TRANSCALIB_H
-#define TRANSCALIB_H
-
-#include <opencv2/opencv.hpp>
-
-//-----------------------------------------------------------------------------
-// Calibrates the translation from head to model = t_MH
-// by recursive least squares /
-// kalman filter in information form with identity noise covariance
-// measurement equation when head position = t_CH is fixed:
-// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k
-
-class TranslationCalibrator
-{
-public:
- TranslationCalibrator();
-
- // reset the calibration process
- void reset();
-
- // update the current estimate
- void update(const cv::Matx33f& R_CM_k, const cv::Vec3f& t_CM_k);
-
- // get the current estimate for t_MH
- cv::Vec3f get_estimate();
-
-protected:
- cv::Matx66f P; // normalized precision matrix = inverse covariance
- cv::Vec6f y; // P*(-t_MH, t_CH)
-};
-
-#endif //TRANSCALIB_H
\ No newline at end of file +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef TRANSCALIB_H +#define TRANSCALIB_H + +#include <opencv2/core/core.hpp> + +//----------------------------------------------------------------------------- +// Calibrates the translation from head to model = t_MH +// by recursive least squares / +// kalman filter in information form with identity noise covariance +// measurement equation when head position = t_CH is fixed: +// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k + +class TranslationCalibrator +{ +public: + TranslationCalibrator(); + + // reset the calibration process + void reset(); + + // update the current estimate + void update(const cv::Matx33d& R_CM_k, const cv::Vec3d& t_CM_k); + + // get the current estimate for t_MH + cv::Vec3f get_estimate(); + +private: + cv::Matx66f P; // normalized precision matrix = inverse covariance + cv::Vec6f y; // P*(-t_MH, t_CH) +}; + +#endif //TRANSCALIB_H diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h deleted file mode 100644 index 09723d84..00000000 --- a/ftnoir_tracker_base/ftnoir_tracker_base.h +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of the some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2010 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* This class implements a tracker-base * -*********************************************************************************/ -#ifndef FTNOIR_TRACKER_BASE_H -#define FTNOIR_TRACKER_BASE_H - -#include "ftnoir_tracker_base_global.h" -#include "ftnoir_tracker_types.h" -#include <QWidget> -#include <QFrame> -#include <QWaitCondition> -#include <QMutex> -#include <QFrame> - -//////////////////////////////////////////////////////////////////////////////// -// COM-Like abstract interface. -// This interface doesn't require __declspec(dllexport/dllimport) specifier. -// Method calls are dispatched via virtual table. -// Any C++ compiler can use it. -// Instances are obtained via factory function. -struct ITracker -{ - virtual ~ITracker() = 0; - virtual void StartTracker( QFrame* frame ) = 0; - virtual void GetHeadPoseData(double *data) = 0; - virtual int preferredHz() { return 200; } -}; - -inline ITracker::~ITracker() { } - -//////////////////////////////////////////////////////////////////////////////// -// COM-Like abstract interface. -// This interface doesn't require __declspec(dllexport/dllimport) specifier. -// Method calls are dispatched via virtual table. -// Any C++ compiler can use it. -// Instances are obtained via factory function. -struct ITrackerDialog -{ - virtual ~ITrackerDialog() {} - virtual void registerTracker(ITracker *tracker) = 0; - virtual void unRegisterTracker() = 0; -}; - -#endif // FTNOIR_TRACKER_BASE_H diff --git a/ftnoir_tracker_base/ftnoir_tracker_base_global.h b/ftnoir_tracker_base/ftnoir_tracker_base_global.h deleted file mode 100644 index e717d845..00000000 --- a/ftnoir_tracker_base/ftnoir_tracker_base_global.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H -#define FTNOIR_TRACKER_BASE_GLOBAL_H - -#include <QtGlobal> - -#ifndef FTNOIR_TRACKER_BASE_EXPORT -# ifndef OPENTRACK_MAIN -# if !defined(_MSC_VER) -# define FTNOIR_TRACKER_BASE_EXPORT __attribute__ ((visibility ("default"))) -# else -# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT -# endif -# else -# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -# endif -#endif - -#endif // FTNOIR_TRACKER_BASE_GLOBAL_H diff --git a/ftnoir_tracker_base/ftnoir_tracker_types.h b/ftnoir_tracker_base/ftnoir_tracker_types.h deleted file mode 100644 index d38baee4..00000000 --- a/ftnoir_tracker_base/ftnoir_tracker_types.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -enum Axis { - TX = 0, TY, TZ, Yaw, Pitch, Roll -}; diff --git a/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui b/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui new file mode 100644 index 00000000..48290bf2 --- /dev/null +++ b/ftnoir_tracker_freepie-udp/freepie-udp-controls.ui @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UI_freepie_udp_dialog</class> + <widget class="QWidget" name="UI_freepie_udp_dialog"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>198</width> + <height>71</height> + </rect> + </property> + <property name="windowTitle"> + <string>UDP tracker settings</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>UDP port</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="port"> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc b/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc new file mode 100644 index 00000000..3fd3edc4 --- /dev/null +++ b/ftnoir_tracker_freepie-udp/freepie-udp-res.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>glovepie.png</file> + </qresource> +</RCC> diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp new file mode 100644 index 00000000..ad505229 --- /dev/null +++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp @@ -0,0 +1,94 @@ +#include "ftnoir_tracker_freepie-udp.h" +#include "facetracknoir/plugin-support.h" + +#include <cinttypes> +#include <algorithm> + +TrackerImpl::TrackerImpl() : pose { 0,0,0, 0,0,0 }, should_quit(false) +{ +} + +TrackerImpl::~TrackerImpl() +{ + should_quit = true; + wait(); +} + +void TrackerImpl::run() { +#pragma pack(push, 1) + struct { + uint8_t pad1; + uint8_t flags; + uint8_t pad2; + float fl[12]; + } data; +#pragma pack(pop) + enum F { + flag_Raw = 1 << 0, + flag_Orient = 1 << 1, + Mask = flag_Raw | flag_Orient + }; + + while (1) { + if (should_quit) + break; + + float orient[3]; + bool filled = false; + + while (sock.hasPendingDatagrams()) + { + using t = decltype(data); + t tmp {0,0,0, {0,0,0, 0,0,0}}; + (void) sock.readDatagram(reinterpret_cast<char*>(&tmp), sizeof(data)); + + int flags = tmp.flags & F::Mask; + + switch (flags) + { + case flag_Raw: + continue; + case flag_Raw | flag_Orient: + for (int i = 0; i < 3; i++) + orient[i] = tmp.fl[i+9]; + break; + case flag_Orient: + for (int i = 0; i < 3; i++) + orient[i] = tmp.fl[i]; + break; + } + + filled = true; + data = tmp; + } + + if (filled) + { + QMutexLocker foo(&mtx); + static constexpr double d2r = 57.295781; + for (int i = 0; i < 3; i++) + pose[Yaw + i] = d2r * orient[i]; + } + usleep(4000); + } +} + +void TrackerImpl::StartTracker(QFrame*) +{ + (void) sock.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); + start(); +} + +void TrackerImpl::GetHeadPoseData(double *data) +{ + QMutexLocker foo(&mtx); + + data[Yaw] = pose[Yaw]; + data[Pitch] = pose[Pitch]; + data[Roll] = pose[Roll]; +} + +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() +{ + return new TrackerImpl; +} diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h new file mode 100644 index 00000000..de32e64b --- /dev/null +++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2014 Stanislaw Halik <sthalik@misaki.pl> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include <cinttypes> +#include <QUdpSocket> +#include <QThread> +#include "ui_freepie-udp-controls.h" +#include "facetracknoir/plugin-api.hpp" +#include "facetracknoir/options.h" +using namespace options; + +struct settings { + pbundle b; + value<int> port; + settings() : + b(bundle("freepie-udp-tracker")), + port(b, "port", 4237) + {} +}; + +class TrackerImpl : public ITracker, private QThread +{ +public: + TrackerImpl(); + ~TrackerImpl() override; + void StartTracker(QFrame *); + void GetHeadPoseData(double *data); +protected: + void run() override; +private: + double pose[6]; + QUdpSocket sock; + settings s; + QMutex mtx; + volatile bool should_quit; +}; + +class TrackerDialog : public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + TrackerDialog(); + void registerTracker(ITracker *) {} + void unRegisterTracker() {} +private: + Ui::UI_freepie_udp_dialog ui; + settings s; +private slots: + void doOK(); + void doCancel(); +}; + +class TrackerMeta : public Metadata +{ +public: + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); +}; + diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp new file mode 100644 index 00000000..6d6a951e --- /dev/null +++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dialog.cpp @@ -0,0 +1,27 @@ +#include "ftnoir_tracker_freepie-udp.h" +#include "facetracknoir/plugin-support.h" + +TrackerDialog::TrackerDialog() +{ + ui.setupUi(this); + + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + + tie_setting(s.port, ui.port); +} + +void TrackerDialog::doOK() { + s.b->save(); + this->close(); +} + +void TrackerDialog::doCancel() { + s.b->reload(); + this->close(); +} + +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog() +{ + return new TrackerDialog; +} diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp new file mode 100644 index 00000000..afcc8c6e --- /dev/null +++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp_dll.cpp @@ -0,0 +1,27 @@ +#include "ftnoir_tracker_freepie-udp.h" +#include "facetracknoir/plugin-support.h" + +void TrackerMeta::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = "FreePIE UDP"; +} + +void TrackerMeta::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = "FreePIE"; +} + +void TrackerMeta::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = "FreePIE UDP"; +} + +void TrackerMeta::getIcon(QIcon *icon) +{ + *icon = QIcon(":/glovepie.png"); +} + +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() +{ + return new TrackerMeta; +} diff --git a/ftnoir_tracker_freepie-udp/glovepie.png b/ftnoir_tracker_freepie-udp/glovepie.png Binary files differnew file mode 100644 index 00000000..2156b7af --- /dev/null +++ b/ftnoir_tracker_freepie-udp/glovepie.png diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp index 76a6ba71..a1cb33a5 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp @@ -1,10 +1,9 @@ #include "stdafx.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "headtracker-ftnoir.h" #include "ftnoir_tracker_ht.h" #include "ftnoir_tracker_ht_dll.h" #include "ui_ht-trackercontrols.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include <cmath> #if defined(_WIN32) @@ -139,7 +138,7 @@ void Tracker::load_settings(ht_config_t* config) Tracker::Tracker() : lck_shm(HT_SHM_NAME, HT_MUTEX_NAME, sizeof(ht_shm_t)), - shm(reinterpret_cast<ht_shm_t*>(lck_shm.mem)), + shm(reinterpret_cast<ht_shm_t*>(lck_shm.ptr())), videoWidget(nullptr), layout(nullptr) { @@ -197,24 +196,12 @@ void Tracker::GetHeadPoseData(double *data) shm->frame.width = 0; } if (shm->result.filled) { - if (s.enableRX) - data[Yaw] = shm->result.rotx; - if (s.enableRY) { - data[Pitch] = shm->result.roty; - } - if (s.enableRZ) { - data[Roll] = shm->result.rotz; - } - if (s.enableTX) - data[TX] = shm->result.tx; - if (s.enableTY) - data[TY] = shm->result.ty; - if (s.enableTZ) - data[TZ] = shm->result.tz; - if (fabs(data[Yaw]) > 60 || fabs(data[Pitch]) > 50 || fabs(data[Roll]) > 40) - { - shm->pause = true; - } + data[Yaw] = shm->result.rotx; + data[Pitch] = shm->result.roty; + data[Roll] = shm->result.rotz; + data[TX] = shm->result.tx; + data[TY] = shm->result.ty; + data[TZ] = shm->result.tz; } else { shm->pause = false; } @@ -224,7 +211,7 @@ void Tracker::GetHeadPoseData(double *data) //----------------------------------------------------------------------------- void TrackerDll::getFullName(QString *strToBeFilled) { - *strToBeFilled = "HT 1.0"; + *strToBeFilled = "HT face tracker"; } void TrackerDll::getShortName(QString *strToBeFilled) @@ -242,17 +229,17 @@ void TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/ht.png"); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new TrackerDll; } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new Tracker; } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) { return new TrackerControls; } @@ -267,12 +254,6 @@ TrackerControls::TrackerControls() tie_setting(s.camera_idx, ui.cameraName); tie_setting(s.fps, ui.cameraFPS); tie_setting(s.fov, ui.cameraFOV); - tie_setting(s.enableTX, ui.tx); - tie_setting(s.enableTY, ui.ty); - tie_setting(s.enableTZ, ui.tz); - tie_setting(s.enableRX, ui.rx); - tie_setting(s.enableRY, ui.ry); - tie_setting(s.enableRZ, ui.rz); tie_setting(s.resolution, ui.resolution); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); @@ -286,6 +267,6 @@ void TrackerControls::doOK() void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.h b/ftnoir_tracker_ht/ftnoir_tracker_ht.h index 583249dc..ea2cb75e 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.h @@ -9,28 +9,21 @@ #define FTNOIR_TRACKER_HT_H #include "stdafx.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "headtracker-ftnoir.h" #include "ui_ht-trackercontrols.h" #include "ht_video_widget.h" #include "compat/compat.h" #include <QObject> #include "facetracknoir/options.h" +#include "facetracknoir/plugin-api.hpp" using namespace options; struct settings { pbundle b; - value<bool> enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ; value<double> fov; value<int> fps, camera_idx, resolution; settings() : b(bundle("HT-Tracker")), - enableTX(b, "enable-tx", true), - enableTY(b, "enable-ty", true), - enableTZ(b, "enable-tz", true), - enableRX(b, "enable-rx", true), - enableRY(b, "enable-ry", true), - enableRZ(b, "enable-rz", true), fov(b, "fov", 56), fps(b, "fps", 0), camera_idx(b, "camera-index", 0), @@ -43,7 +36,7 @@ class Tracker : public QObject, public ITracker Q_OBJECT public: Tracker(); - virtual ~Tracker(); + ~Tracker() override; void StartTracker(QFrame* frame); void GetHeadPoseData(double *data); void load_settings(ht_config_t* config); diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h index ffdc5262..66e57100 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h @@ -5,8 +5,7 @@ * copyright notice and this permission notice appear in all copies. */ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" //----------------------------------------------------------------------------- class TrackerDll : public Metadata diff --git a/ftnoir_tracker_ht/ht-trackercontrols.ui b/ftnoir_tracker_ht/ht-trackercontrols.ui index f57022c8..0b94ffc5 100644 --- a/ftnoir_tracker_ht/ht-trackercontrols.ui +++ b/ftnoir_tracker_ht/ht-trackercontrols.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>531</width> - <height>166</height> + <width>354</width> + <height>158</height> </rect> </property> <property name="sizePolicy"> @@ -52,91 +52,6 @@ </property> </widget> </item> - <item row="0" column="2" rowspan="3"> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Enable axes</string> - </property> - <widget class="QCheckBox" name="rx"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RX</string> - </property> - </widget> - <widget class="QCheckBox" name="ry"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RY</string> - </property> - </widget> - <widget class="QCheckBox" name="rz"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RZ</string> - </property> - </widget> - <widget class="QCheckBox" name="tx"> - <property name="geometry"> - <rect> - <x>60</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TX</string> - </property> - </widget> - <widget class="QCheckBox" name="ty"> - <property name="geometry"> - <rect> - <x>60</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TY</string> - </property> - </widget> - <widget class="QCheckBox" name="tz"> - <property name="geometry"> - <rect> - <x>60</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TZ</string> - </property> - </widget> - </widget> - </item> <item row="1" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> @@ -214,7 +129,7 @@ </item> </widget> </item> - <item row="4" column="2"> + <item row="4" column="1"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> diff --git a/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui b/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui index e5e41bec..7cfac075 100644 --- a/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui +++ b/ftnoir_tracker_hydra/ftnoir_hydra_clientcontrols.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>172</width> - <height>145</height> + <width>190</width> + <height>62</height> </rect> </property> <property name="windowTitle"> @@ -26,167 +26,15 @@ <property name="autoFillBackground"> <bool>false</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>85</height> - </size> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>None whatsoever</string> </property> - <property name="title"> - <string>Enable Axis</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_61"> - <property name="text"> - <string>Pitch:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="chkEnablePitch"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>X:</string> - </property> - </widget> - </item> - <item row="0" column="3"> - <widget class="QCheckBox" name="chkEnableX"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_91"> - <property name="text"> - <string>Yaw:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QCheckBox" name="chkEnableYaw"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Y:</string> - </property> - </widget> - </item> - <item row="1" column="3"> - <widget class="QCheckBox" name="chkEnableY"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_111"> - <property name="text"> - <string>Roll:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="chkEnableRoll"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Z:</string> - </property> - </widget> - </item> - <item row="2" column="3"> - <widget class="QCheckBox" name="chkEnableZ"> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> </widget> </item> - <item> + <item row="1" column="0"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp index 70af2893..b7d078c2 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp @@ -1,20 +1,17 @@ /* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */ #include "ftnoir_tracker_hydra.h" -#include "facetracknoir/global-settings.h" -#include "facetracknoir/rotation.h" +#include "facetracknoir/plugin-support.h" #include <cstdio> #ifdef _WIN32 # define SIXENSE_STATIC_LIB # define SIXENSE_UTILS_STATIC_LIB #endif #include <sixense.h> -#include <sixense_math.hpp> -Hydra_Tracker::Hydra_Tracker() : should_quit(false) -{ - for (int i = 0; i < 6; i++) - newHeadPose[i] = 0; -} +Hydra_Tracker::Hydra_Tracker() : should_quit(false) {} + +#pragma GCC diagnostic ignored "-Wreorder" +#include <sixense_math.hpp> Hydra_Tracker::~Hydra_Tracker() { @@ -38,36 +35,16 @@ void Hydra_Tracker::GetHeadPoseData(double *data) float ypr[3]; mat.getEulerAngles().fill(ypr); - newHeadPose[Yaw] = ypr[0]; - newHeadPose[Pitch] = ypr[1]; - newHeadPose[Roll] = ypr[2]; - - - newHeadPose[TX] = acd.controllers[0].pos[0]/50.0f; - newHeadPose[TY] = acd.controllers[0].pos[1]/50.0f; - newHeadPose[TZ] = acd.controllers[0].pos[2]/50.0f; - - if (s.bEnableX) { - data[TX] = newHeadPose[TX]; - } - if (s.bEnableY) { - data[TY] = newHeadPose[TY]; - } - if (s.bEnableY) { - data[TZ] = newHeadPose[TZ]; - } - if (s.bEnableYaw) { - data[Yaw] = newHeadPose[Yaw] * 57.295781f; - } - if (s.bEnablePitch) { - data[Pitch] = newHeadPose[Pitch] * 57.295781f; - } - if (s.bEnableRoll) { - data[Roll] = newHeadPose[Roll] * 57.295781f; - } + data[TX] = acd.controllers[0].pos[0]/50.0; + data[TY] = acd.controllers[0].pos[1]/50.0; + data[TZ] = acd.controllers[0].pos[2]/50.0; + static constexpr double r2d = 57.295781; + data[Yaw] = ypr[0] * r2d; + data[Pitch] = ypr[1] * r2d; + data[Roll] = ypr[2] * r2d; } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new Hydra_Tracker; } diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h index 05a8b076..672efa28 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.h @@ -1,65 +1,49 @@ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_ftnoir_hydra_clientcontrols.h" -#include <QMessageBox> -#include <QWaitCondition> -#include <math.h> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "facetracknoir/options.h" using namespace options; struct settings { pbundle b; - value<bool> bEnableRoll, bEnablePitch, bEnableYaw, bEnableX, bEnableY, bEnableZ; settings() : - b(bundle("tracker-hydra")), - bEnableRoll(b, "enable-rz", true), - bEnablePitch(b, "enable-ry", true), - bEnableYaw(b, "enable-rx", true), - bEnableX(b, "enable-tx", true), - bEnableY(b, "enable-ty", true), - bEnableZ(b, "enable-tz", true) + b(bundle("tracker-hydra")) {} }; class Hydra_Tracker : public ITracker { public: - Hydra_Tracker(); + Hydra_Tracker(); ~Hydra_Tracker(); - void StartTracker(QFrame *) virt_override; - void GetHeadPoseData(double *data) virt_override; + void StartTracker(QFrame *) override; + void GetHeadPoseData(double *data) override; volatile bool should_quit; -protected: - void run(); // qthread override run method private: settings s; - bool isCalibrated; - double newHeadPose[6]; // Structure with new headpose QMutex mutex; - virtual int preferredHz() virt_override { return 250; } }; class TrackerControls: public QWidget, public ITrackerDialog { Q_OBJECT public: - explicit TrackerControls(); + explicit TrackerControls(); void registerTracker(ITracker *) {} void unRegisterTracker() {} private: settings s; - Ui::UIHydraControls ui; + Ui::UIHydraControls ui; private slots: - void doOK(); - void doCancel(); + void doOK(); + void doCancel(); }; class FTNoIR_TrackerDll : public Metadata { public: - void getFullName(QString *strToBeFilled); - void getShortName(QString *strToBeFilled); - void getDescription(QString *strToBeFilled); - void getIcon(QIcon *icon); + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); }; diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp index 14be2c37..c81ddce7 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp @@ -1,5 +1,5 @@ #include "ftnoir_tracker_hydra.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" TrackerControls::TrackerControls() : QWidget() @@ -9,13 +9,6 @@ QWidget() // Connect Qt signals to member-functions connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - - tie_setting(s.bEnableYaw, ui.chkEnableYaw); - tie_setting(s.bEnablePitch, ui.chkEnablePitch); - tie_setting(s.bEnableRoll, ui.chkEnableRoll); - tie_setting(s.bEnableX, ui.chkEnableX); - tie_setting(s.bEnableY, ui.chkEnableY); - tie_setting(s.bEnableZ, ui.chkEnableZ); } void TrackerControls::doOK() { @@ -24,11 +17,11 @@ void TrackerControls::doOK() { } void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); close(); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) { return new TrackerControls; } diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp index a2cc7c01..18efea05 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dll.cpp @@ -1,7 +1,7 @@ /* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */ #include "ftnoir_tracker_hydra.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) { @@ -23,16 +23,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/facetracknoir.png"); } -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Tracker object. - -// Export both decorated and undecorated names. -// GetTrackerDll - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetTrackerDll@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") - -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_TrackerDll; } diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp index f9789dce..bb1076dd 100644 --- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp @@ -1,17 +1,13 @@ #include "ftnoir_tracker_joystick.h" -#include "facetracknoir/global-settings.h" -#undef NDEBUG +#include "facetracknoir/plugin-support.h" #include <QMutexLocker> FTNoIR_Tracker::FTNoIR_Tracker() : g_pDI(nullptr), g_pJoystick(nullptr), - iter(-1), - mtx(QMutex::Recursive) + mtx(QMutex::Recursive), + iter(-1) { - for (int i = 0; i < 6; i++) - min_[i] = max_[i] = 0; - GUID bar = {0}; } void FTNoIR_Tracker::reload() @@ -45,13 +41,13 @@ FTNoIR_Tracker::~FTNoIR_Tracker() } } +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext ) { auto self = (FTNoIR_Tracker*) pContext; - // For axes that are returned, set the DIPROP_RANGE property for the - // enumerated axis in order to scale min/max values. if( pdidoi->dwType & DIDFT_AXIS ) { DIPROPRANGE diprg = {0}; @@ -59,15 +55,12 @@ static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER ); diprg.diph.dwHow = DIPH_BYID; diprg.diph.dwObj = pdidoi->dwType; + diprg.lMax = FTNoIR_Tracker::AXIS_MAX; + diprg.lMin = -FTNoIR_Tracker::AXIS_MAX; - // Set the range for the axis - - if( FAILED( self->g_pJoystick->GetProperty( DIPROP_RANGE, &diprg.diph ) ) ) + if( FAILED( self->g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) return DIENUM_STOP; - self->min_[self->iter] = diprg.lMin; - self->max_[self->iter] = diprg.lMax; - qDebug() << "axis" << self->iter << diprg.lMin << diprg.lMax; self->iter++; } @@ -138,8 +131,6 @@ void FTNoIR_Tracker::StartTracker(QFrame* frame) goto fail; } - qDebug() << "joy init success"; - return; fail: @@ -161,18 +152,26 @@ void FTNoIR_Tracker::GetHeadPoseData(double *data) if( !g_pDI || !g_pJoystick) return; - auto hr = g_pJoystick->Poll(); - if( FAILED( hr )) - { - hr = g_pJoystick->Acquire(); - for (int i = 0; hr == DIERR_INPUTLOST && i < 200; i++) - hr = g_pJoystick->Acquire(); - if (hr != DI_OK) + bool ok = false; + + for (int i = 0; i < 100; i++) + { + if (!FAILED(g_pJoystick->Poll())) { - qDebug() << "joy read failure" << hr; - return; + ok = true; + break; } - } + if (g_pJoystick->Acquire() != DI_OK) + continue; + else + ok = true; + break; + } + + if (!ok) + return; + + HRESULT hr = 0; if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof( js ), &js ) ) ) return; @@ -196,35 +195,12 @@ void FTNoIR_Tracker::GetHeadPoseData(double *data) 90, 180 }; - - int axes[] = { - s.axis_0, - s.axis_1, - s.axis_2, - s.axis_3, - s.axis_4, - s.axis_5 - }; - + for (int i = 0; i < 6; i++) - { - auto idx = axes[i] - 1; - if (idx < 0 || idx > 7) - { - data[i] = 0; - } - else { - auto mid = (min_[idx] + max_[idx]) / 2; - auto val = values[idx] - mid; - - auto max = (max_[idx] - min_[idx]) / 2; - auto min = (min_[idx] - max_[idx]) / -2; - data[i] = val * limits[i] / (double) (val >= 0 ? max : min); - } - } + data[i] = values[i] * limits[i] / AXIS_MAX; } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new FTNoIR_Tracker; } diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h index 06d06186..04a933db 100644 --- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h @@ -5,7 +5,6 @@ * copyright notice and this permission notice appear in all copies. */ #pragma once -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_ftnoir_tracker_joystick_controls.h" #include <QComboBox> #include <QCheckBox> @@ -16,7 +15,7 @@ #include <QMutex> #include <QFrame> #include <cmath> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #ifndef DIRECTINPUT_VERSION # define DIRECTINPUT_VERSION 0x800 #endif @@ -32,21 +31,9 @@ using namespace options; struct settings { pbundle b; - value<int> axis_0; - value<int> axis_1; - value<int> axis_2; - value<int> axis_3; - value<int> axis_4; - value<int> axis_5; value<QString> joyid; settings() : b(bundle("tracker-joystick")), - axis_0(b, "axis-0", 0), - axis_1(b, "axis-1", 0), - axis_2(b, "axis-2", 0), - axis_3(b, "axis-3", 0), - axis_4(b, "axis-4", 0), - axis_5(b, "axis-5", 0), joyid(b, "joy-id", "") {} }; @@ -61,12 +48,12 @@ public: void reload(); LPDIRECTINPUT8 g_pDI; LPDIRECTINPUTDEVICE8 g_pJoystick; - int min_[8], max_[8]; QMutex mtx; QFrame* frame; DIDEVICEINSTANCE def; int iter; // XXX bad style settings s; + static constexpr int AXIS_MAX = 65535; }; class TrackerControls: public QWidget, public ITrackerDialog diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui index 5d349169..424d1c44 100644 --- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui @@ -9,12 +9,12 @@ <rect> <x>0</x> <y>0</y> - <width>216</width> - <height>259</height> + <width>458</width> + <height>134</height> </rect> </property> <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -32,401 +32,61 @@ <property name="autoFillBackground"> <bool>false</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="groupBox_3"> + <layout class="QFormLayout" name="formLayout"> + <property name="horizontalSpacing"> + <number>6</number> + </property> + <property name="verticalSpacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>12</number> + </property> + <property name="topMargin"> + <number>6</number> + </property> + <property name="rightMargin"> + <number>12</number> + </property> + <property name="bottomMargin"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Joystick</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="joylist"> <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>85</height> - </size> - </property> - <property name="title"> - <string>Axis enablement</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>X</string> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Y</string> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="label_16"> - <property name="text"> - <string>Roll</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QComboBox" name="comboBox_5"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="7" column="1"> - <widget class="QComboBox" name="comboBox_6"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="5" column="1"> - <widget class="QComboBox" name="comboBox_4"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="3" column="1"> - <widget class="QComboBox" name="comboBox_2"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="1" column="1"> - <widget class="QComboBox" name="comboBox"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_14"> - <property name="text"> - <string>Yaw</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QComboBox" name="comboBox_3"> - <item> - <property name="text"> - <string/> - </property> - </item> - <item> - <property name="text"> - <string>#1</string> - </property> - </item> - <item> - <property name="text"> - <string>#2</string> - </property> - </item> - <item> - <property name="text"> - <string>#3</string> - </property> - </item> - <item> - <property name="text"> - <string>#4</string> - </property> - </item> - <item> - <property name="text"> - <string>#5</string> - </property> - </item> - <item> - <property name="text"> - <string>#6</string> - </property> - </item> - <item> - <property name="text"> - <string>#7</string> - </property> - </item> - <item> - <property name="text"> - <string>#8</string> - </property> - </item> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Z</string> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_15"> - <property name="text"> - <string>Pitch</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Joy Id</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QComboBox" name="joylist"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> </widget> </item> - <item> + <item row="2" column="0" colspan="2"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> </widget> </item> + <item row="1" column="0" colspan="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Only first 6 axes available. +Adjust order in mapping window "output remap" option.</string> + </property> + </widget> + </item> </layout> </widget> <tabstops> <tabstop>joylist</tabstop> - <tabstop>comboBox</tabstop> - <tabstop>comboBox_2</tabstop> - <tabstop>comboBox_3</tabstop> - <tabstop>comboBox_4</tabstop> - <tabstop>comboBox_5</tabstop> - <tabstop>comboBox_6</tabstop> <tabstop>buttonBox</tabstop> </tabstops> <resources/> diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp index b0766634..84e02fb0 100644 --- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp @@ -1,5 +1,5 @@ #include "ftnoir_tracker_joystick.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ) { @@ -19,13 +19,6 @@ TrackerControls::TrackerControls() : tracker(nullptr) connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - tie_setting(s.axis_0, ui.comboBox); - tie_setting(s.axis_1, ui.comboBox_2); - tie_setting(s.axis_2, ui.comboBox_3); - tie_setting(s.axis_3, ui.comboBox_4); - tie_setting(s.axis_4, ui.comboBox_5); - tie_setting(s.axis_5, ui.comboBox_6); - { auto hr = CoInitialize( nullptr ); LPDIRECTINPUT8 g_pDI = nullptr; @@ -56,11 +49,11 @@ void TrackerControls::doOK() { } void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) { return new TrackerControls; } diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp index 325d24a4..af1a9679 100644 --- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp @@ -1,6 +1,6 @@ #include "ftnoir_tracker_joystick.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) { @@ -22,7 +22,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/facetracknoir.png"); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_TrackerDll; } diff --git a/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui new file mode 100644 index 00000000..73b1f767 --- /dev/null +++ b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui @@ -0,0 +1,1207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICPTClientControls</class> + <widget class="QWidget" name="UICPTClientControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>453</width> + <height>621</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>PointTracker Settings</string> + </property> + <property name="windowIcon"> + <iconset resource="ftnoir_tracker_pt.qrc"> + <normaloff>:/Resources/Logo_IR.png</normaloff>:/Resources/Logo_IR.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_9"> + <property name="sizeConstraint"> + <enum>QLayout::SetFixedSize</enum> + </property> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox_5"> + <property name="title"> + <string>Status</string> + </property> + <layout class="QGridLayout" name="gridLayout_10"> + <item row="2" column="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Extracted Points:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_38"> + <property name="text"> + <string>Camera Info:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDialogButtonBox" name="buttonBox_2"> + <property name="standardButtons"> + <set>QDialogButtonBox::Apply</set> + </property> + <property name="centerButtons"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="caminfo_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>120</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="pointinfo_label"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="0"> + <widget class="QTabWidget" name="tabWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Camera</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Camera settings</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Device</string> + </property> + <property name="buddy"> + <cstring>camdevice_combo</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="camdevice_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumContentsLength"> + <number>10</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_36"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Width</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="res_x_spin"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Desired capture width</string> + </property> + <property name="suffix"> + <string> px</string> + </property> + <property name="maximum"> + <number>2000</number> + </property> + <property name="singleStep"> + <number>10</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_41"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Height</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="res_y_spin"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Desired capture height</string> + </property> + <property name="suffix"> + <string> px</string> + </property> + <property name="maximum"> + <number>2000</number> + </property> + <property name="singleStep"> + <number>10</number> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_37"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>FPS</string> + </property> + <property name="buddy"> + <cstring>fps_spin</cstring> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSpinBox" name="fps_spin"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Desired capture framerate</string> + </property> + <property name="suffix"> + <string> Hz</string> + </property> + <property name="maximum"> + <number>2000</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_4"> + <property name="title"> + <string>Camera orientation</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>Roll</string> + </property> + <property name="buddy"> + <cstring>camroll_combo</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="camroll_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Rotation of the camera image</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Pitch</string> + </property> + <property name="buddy"> + <cstring>campitch_spin</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="campitch_spin"> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> + </property> + <property name="toolTip"> + <string>The angle the camera is facing upwards</string> + </property> + <property name="suffix"> + <string> deg</string> + </property> + <property name="minimum"> + <number>-180</number> + </property> + <property name="maximum"> + <number>180</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>positive = upwards</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>Yaw</string> + </property> + <property name="buddy"> + <cstring>camyaw_spin</cstring> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="camyaw_spin"> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> + </property> + <property name="toolTip"> + <string>The angle the camera is facing leftwards</string> + </property> + <property name="suffix"> + <string> deg</string> + </property> + <property name="prefix"> + <string/> + </property> + <property name="minimum"> + <number>-180</number> + </property> + <property name="maximum"> + <number>180</number> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>positve = left</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Point extraction</string> + </property> + <layout class="QGridLayout" name="gridLayout_7"> + <item row="0" column="4"> + <widget class="QSpinBox" name="mindiam_spin"> + <property name="toolTip"> + <string>Minimum point diameter</string> + </property> + <property name="suffix"> + <string> px</string> + </property> + <property name="maximum"> + <number>1024</number> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QSlider" name="threshold_slider"> + <property name="toolTip"> + <string>Intensity threshold for point extraction</string> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>127</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBothSides</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QSpinBox" name="maxdiam_spin"> + <property name="toolTip"> + <string>Maximum point diameter</string> + </property> + <property name="suffix"> + <string> px</string> + </property> + <property name="maximum"> + <number>1024</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Max size</string> + </property> + <property name="buddy"> + <cstring>maxdiam_spin</cstring> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QSlider" name="threshold_secondary_slider"> + <property name="toolTip"> + <string>Per pixel hysteresis width (leave left if there is little difference between dot and non-dot, move right for increased stability against pixel noise)</string> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBothSides</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Threshold</string> + </property> + <property name="buddy"> + <cstring>threshold_slider</cstring> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_secondary"> + <property name="text"> + <string>Hysteresis</string> + </property> + <property name="buddy"> + <cstring>threshold_secondary_slider</cstring> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Min size</string> + </property> + <property name="buddy"> + <cstring>mindiam_spin</cstring> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_4"> + <attribute name="title"> + <string>Model</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_16"> + <item> + <widget class="QTabWidget" name="model_tabs"> + <property name="tabShape"> + <enum>QTabWidget::Rounded</enum> + </property> + <property name="currentIndex"> + <number>1</number> + </property> + <property name="usesScrollButtons"> + <bool>false</bool> + </property> + <property name="documentMode"> + <bool>false</bool> + </property> + <property name="tabsClosable"> + <bool>false</bool> + </property> + <widget class="QWidget" name="tab_5"> + <attribute name="title"> + <string>Clip</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBox_8"> + <property name="title"> + <string>Model Dimensions</string> + </property> + <widget class="QSpinBox" name="clip_tlength_spin"> + <property name="geometry"> + <rect> + <x>70</x> + <y>35</y> + <width>100</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QSpinBox" name="clip_bheight_spin"> + <property name="geometry"> + <rect> + <x>110</x> + <y>115</y> + <width>100</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QLabel" name="label_44"> + <property name="geometry"> + <rect> + <x>40</x> + <y>55</y> + <width>71</width> + <height>111</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_side.png</pixmap> + </property> + </widget> + <widget class="QLabel" name="label_50"> + <property name="geometry"> + <rect> + <x>10</x> + <y>35</y> + <width>46</width> + <height>13</height> + </rect> + </property> + <property name="text"> + <string>Side</string> + </property> + </widget> + <widget class="QSpinBox" name="clip_blength_spin"> + <property name="geometry"> + <rect> + <x>50</x> + <y>165</y> + <width>100</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QSpinBox" name="clip_theight_spin"> + <property name="geometry"> + <rect> + <x>110</x> + <y>75</y> + <width>100</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QLabel" name="label_51"> + <property name="geometry"> + <rect> + <x>255</x> + <y>40</y> + <width>46</width> + <height>13</height> + </rect> + </property> + <property name="text"> + <string>Front</string> + </property> + </widget> + <widget class="QLabel" name="label_45"> + <property name="geometry"> + <rect> + <x>265</x> + <y>60</y> + <width>21</width> + <height>111</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/clip_front.png</pixmap> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_6"> + <attribute name="title"> + <string>Cap</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_14"> + <item> + <widget class="QGroupBox" name="groupBox_9"> + <property name="title"> + <string>Model Dimensions</string> + </property> + <widget class="QLabel" name="label_46"> + <property name="geometry"> + <rect> + <x>30</x> + <y>90</y> + <width>111</width> + <height>81</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_side.png</pixmap> + </property> + </widget> + <widget class="QLabel" name="label_48"> + <property name="geometry"> + <rect> + <x>20</x> + <y>35</y> + <width>46</width> + <height>13</height> + </rect> + </property> + <property name="text"> + <string>Side</string> + </property> + </widget> + <widget class="QSpinBox" name="cap_length_spin"> + <property name="geometry"> + <rect> + <x>20</x> + <y>70</y> + <width>101</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QLabel" name="label_54"> + <property name="geometry"> + <rect> + <x>140</x> + <y>90</y> + <width>16</width> + <height>16</height> + </rect> + </property> + <property name="text"> + <string>R</string> + </property> + </widget> + <widget class="QLabel" name="label_55"> + <property name="geometry"> + <rect> + <x>290</x> + <y>85</y> + <width>16</width> + <height>16</height> + </rect> + </property> + <property name="text"> + <string>R</string> + </property> + </widget> + <widget class="QLabel" name="label_47"> + <property name="geometry"> + <rect> + <x>270</x> + <y>85</y> + <width>81</width> + <height>81</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/cap_front.png</pixmap> + </property> + </widget> + <widget class="QSpinBox" name="cap_width_spin"> + <property name="geometry"> + <rect> + <x>255</x> + <y>55</y> + <width>100</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + <widget class="QLabel" name="label_49"> + <property name="geometry"> + <rect> + <x>290</x> + <y>35</y> + <width>46</width> + <height>13</height> + </rect> + </property> + <property name="text"> + <string>Front</string> + </property> + </widget> + <widget class="QSpinBox" name="cap_height_spin"> + <property name="geometry"> + <rect> + <x>60</x> + <y>120</y> + <width>116</width> + <height>22</height> + </rect> + </property> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_7"> + <attribute name="title"> + <string>Custom</string> + </attribute> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBox_7"> + <property name="title"> + <string>Model Dimensions</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="3" column="1"> + <widget class="QLabel" name="label_57"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>z:</string> + </property> + </widget> + </item> + <item row="2" column="5"> + <widget class="QSpinBox" name="m2y_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_63"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>x:</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="m1x_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QSpinBox" name="m1y_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="3" column="5"> + <widget class="QSpinBox" name="m2z_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QSpinBox" name="m2x_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="0" column="0" colspan="6"> + <widget class="QLabel" name="label_56"> + <property name="text"> + <string><html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, e.g. millimeters, inches, parsecs...</p></body></html></string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QSpinBox" name="m1z_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QLabel" name="label_70"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>y:</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QLabel" name="label_67"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>x:</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_64"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_60"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html></string> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QLabel" name="label_69"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>z:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_58"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>y:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_10"> + <property name="title"> + <string>Model position</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="1" column="1"> + <widget class="QSpinBox" name="tx_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + </widget> + </item> + <item row="0" column="0" colspan="3"> + <widget class="QLabel" name="label_59"> + <property name="text"> + <string><html><head/><body><p>Translation from head center to model reference point<br/> in default pose</p></body></html></string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="ty_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_62"> + <property name="text"> + <string>y:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_66"> + <property name="text"> + <string>z:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_61"> + <property name="text"> + <string>x:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSpinBox" name="tz_spin"> + <property name="suffix"> + <string> units</string> + </property> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QPushButton" name="tcalib_button"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Calibrate</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>About</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_8"> + <item row="0" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string><html><head/><body><p><span style=" font-weight:600;">FTNoIR PointTracker Plugin<br/>Version 1.1</span></p><p><span style=" font-weight:600;">by Patrick Ruoff</span></p><p><a href="http://ftnoirpt.sourceforge.net/"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">Manual (external)</span></a></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_35"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="ftnoir_tracker_pt.qrc">:/Resources/Logo_IR.png</pixmap> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>tabWidget</tabstop> + <tabstop>camdevice_combo</tabstop> + <tabstop>res_x_spin</tabstop> + <tabstop>camroll_combo</tabstop> + <tabstop>campitch_spin</tabstop> + <tabstop>camyaw_spin</tabstop> + <tabstop>threshold_slider</tabstop> + <tabstop>model_tabs</tabstop> + <tabstop>m1x_spin</tabstop> + <tabstop>m1y_spin</tabstop> + <tabstop>m1z_spin</tabstop> + <tabstop>m2x_spin</tabstop> + <tabstop>m2y_spin</tabstop> + <tabstop>m2z_spin</tabstop> + <tabstop>tx_spin</tabstop> + <tabstop>ty_spin</tabstop> + <tabstop>tz_spin</tabstop> + </tabstops> + <resources> + <include location="ftnoir_tracker_pt.qrc"/> + </resources> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/FTNoIR_Tracker_PT/Resources/Logo_IR.png b/ftnoir_tracker_pt/Resources/Logo_IR.png Binary files differindex 95032a25..95032a25 100644 --- a/FTNoIR_Tracker_PT/Resources/Logo_IR.png +++ b/ftnoir_tracker_pt/Resources/Logo_IR.png diff --git a/FTNoIR_Tracker_PT/Resources/cap_front.png b/ftnoir_tracker_pt/Resources/cap_front.png Binary files differindex 14207a67..14207a67 100644 --- a/FTNoIR_Tracker_PT/Resources/cap_front.png +++ b/ftnoir_tracker_pt/Resources/cap_front.png diff --git a/FTNoIR_Tracker_PT/Resources/cap_side.png b/ftnoir_tracker_pt/Resources/cap_side.png Binary files differindex 5ad4ee65..5ad4ee65 100644 --- a/FTNoIR_Tracker_PT/Resources/cap_side.png +++ b/ftnoir_tracker_pt/Resources/cap_side.png diff --git a/FTNoIR_Tracker_PT/Resources/clip_front.png b/ftnoir_tracker_pt/Resources/clip_front.png Binary files differindex 04880138..04880138 100644 --- a/FTNoIR_Tracker_PT/Resources/clip_front.png +++ b/ftnoir_tracker_pt/Resources/clip_front.png diff --git a/FTNoIR_Tracker_PT/Resources/clip_side.png b/ftnoir_tracker_pt/Resources/clip_side.png Binary files differindex 72667ac7..72667ac7 100644 --- a/FTNoIR_Tracker_PT/Resources/clip_side.png +++ b/ftnoir_tracker_pt/Resources/clip_side.png diff --git a/FTNoIR_Tracker_PT/camera.cpp b/ftnoir_tracker_pt/camera.cpp index 754533c5..7c2c09ce 100644 --- a/FTNoIR_Tracker_PT/camera.cpp +++ b/ftnoir_tracker_pt/camera.cpp @@ -1,351 +1,328 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
- #if defined(OPENTRACK_API) && defined(_WIN32)
-#include <windows.h>
-#include <dshow.h>
-#endif
-
-#include "camera.h"
-#include <string>
-#include <QDebug>
-
-using namespace cv;
-
-#if defined(OPENTRACK_API) && (defined(__unix) || defined(__linux) || defined(__APPLE__))
-#include <unistd.h>
-#endif
-
-#ifdef OPENTRACK_API
-void get_camera_device_names(std::vector<std::string>& device_names) {
-# if defined(_WIN32)
- // Create the System Device Enumerator.
- HRESULT hr;
- ICreateDevEnum *pSysDevEnum = NULL;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
- if (FAILED(hr))
- {
- return;
- }
- // Obtain a class enumerator for the video compressor category.
- IEnumMoniker *pEnumCat = NULL;
- hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
-
- if (hr == S_OK) {
- // Enumerate the monikers.
- IMoniker *pMoniker = NULL;
- ULONG cFetched;
- while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
- // To retrieve the filter's friendly name, do the following:
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr))
- {
- auto wstr = std::wstring(varName.bstrVal);
- auto str = std::string(wstr.begin(), wstr.end());
- device_names.push_back(str);
- }
- VariantClear(&varName);
-
- ////// To create an instance of the filter, do the following:
- ////IBaseFilter *pFilter;
- ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
- //// (void**)&pFilter);
- // Now add the filter to the graph.
- //Remember to release pFilter later.
- pPropBag->Release();
- }
- pMoniker->Release();
- }
- pEnumCat->Release();
- }
- pSysDevEnum->Release();
-# else
- for (int i = 0; i < 16; i++) {
- char buf[128];
- sprintf(buf, "/dev/video%d", i);
- if (access(buf, R_OK | W_OK) == 0) {
- device_names.push_back(std::string(buf));
- }
- }
-# endif
-}
-#else
-// ----------------------------------------------------------------------------
-void get_camera_device_names(std::vector<std::string>& device_names)
-{
- videoInput VI;
- VI.listDevices();
- std::string device_name;
- for(int index = 0; ; ++index) {
- device_name = VI.getDeviceName(index);
- if (device_name.empty()) break;
- device_names.push_back(device_name);
- }
-}
-#endif
-
-// ----------------------------------------------------------------------------
-void Camera::set_device_index(int index)
-{
- if (desired_index != index)
- {
- desired_index = index;
- _set_device_index();
-
- // reset fps
- dt_valid = 0;
- dt_mean = 0;
- active_index = index;
- }
-}
-
-void Camera::set_f(float f)
-{
- if (cam_desired.f != f)
- {
- cam_desired.f = f;
- _set_f();
- }
-}
-void Camera::set_fps(int fps)
-{
- if (cam_desired.fps != fps)
- {
- cam_desired.fps = fps;
- _set_fps();
- }
-}
-
-void Camera::set_res(int x_res, int y_res)
-{
- if (cam_desired.res_x != x_res || cam_desired.res_y != y_res)
- {
- cam_desired.res_x = x_res;
- cam_desired.res_y = y_res;
- _set_res();
- _set_fps();
- }
-}
-
-bool Camera::get_frame(float dt, cv::Mat* frame)
-{
- bool new_frame = _get_frame(frame);
- // measure fps of valid frames
- const float dt_smoothing_const = 0.9;
- dt_valid += dt;
- if (new_frame)
- {
- dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid;
- cam_info.fps = 1.0 / dt_mean;
- dt_valid = 0;
- }
- return new_frame;
-}
-
-// ----------------------------------------------------------------------------
-#ifdef OPENTRACK_API
-void CVCamera::start()
-{
- cap = new VideoCapture(desired_index);
- // extract camera info
- if (cap->isOpened())
- {
- active = true;
- active_index = desired_index;
- cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
- cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
- } else {
- delete cap;
- cap = nullptr;
- }
-}
-
-void CVCamera::stop()
-{
- if (cap)
- {
- cap->release();
- delete cap;
- }
- active = false;
-}
-
-bool CVCamera::_get_frame(Mat* frame)
-{
- if (cap && cap->isOpened())
- {
- Mat img;
- /*
- * XXX some Windows webcams fail to decode first
- * frames and then some every once in a while
- * -sh
- */
- for (int i = 0; i < 100 && !cap->read(img); i++)
- ;;
-
- if (img.empty())
- return false;
-
- *frame = img;
- return true;
- }
- return false;
-}
-
-void CVCamera::_set_index()
-{
- if (active) restart();
-}
-
-void CVCamera::_set_f()
-{
- cam_info.f = cam_desired.f;
-}
-
-void CVCamera::_set_fps()
-{
- if (cap) cap->set(CV_CAP_PROP_FPS, cam_desired.fps);
-}
-
-void CVCamera::_set_res()
-{
- if (cap)
- {
- cap->set(CV_CAP_PROP_FRAME_WIDTH, cam_desired.res_x);
- cap->set(CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y);
- cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH);
- cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT);
- }
-}
-void CVCamera::_set_device_index()
-{
- if (cap)
- {
- cap->release();
- delete cap;
- }
- cap = new VideoCapture(desired_index);
-}
-
-#else
-// ----------------------------------------------------------------------------
-VICamera::VICamera() : frame_buffer(NULL)
-{
- VI.listDevices();
-}
-
-void VICamera::start()
-{
- if (desired_index >= 0)
- {
- if (cam_desired.res_x == 0 || cam_desired.res_y == 0)
- VI.setupDevice(desired_index);
- else
- VI.setupDevice(desired_index, cam_desired.res_x, cam_desired.res_y);
-
- active = true;
- active_index = desired_index;
-
- cam_info.res_x = VI.getWidth(active_index);
- cam_info.res_y = VI.getHeight(active_index);
- new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3);
- // If matrix is not continuous we have to copy manually via frame_buffer
- if (!new_frame.isContinuous()) {
- unsigned int size = VI.getSize(active_index);
- frame_buffer = new unsigned char[size];
- }
- }
-}
-
-void VICamera::stop()
-{
- if (active)
- {
- VI.stopDevice(active_index);
- }
- if (frame_buffer)
- {
- delete[] frame_buffer;
- frame_buffer = NULL;
- }
- active = false;
-}
-
-bool VICamera::_get_frame(Mat* frame)
-{
- if (active && VI.isFrameNew(active_index))
- {
- if (new_frame.isContinuous())
- {
- VI.getPixels(active_index, new_frame.data, false, true);
- }
- else
- {
- // If matrix is not continuous we have to copy manually via frame_buffer
- VI.getPixels(active_index, frame_buffer, false, true);
- new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3, frame_buffer).clone();
- }
- *frame = new_frame;
- return true;
- }
- return false;
-}
-
-void VICamera::_set_device_index()
-{
- if (active) restart();
-}
-
-void VICamera::_set_f()
-{
- cam_info.f = cam_desired.f;
-}
-
-void VICamera::_set_fps()
-{
- bool was_active = active;
- if (active) stop();
- VI.setIdealFramerate(desired_index, cam_desired.fps);
- if (was_active) start();
-}
-
-void VICamera::_set_res()
-{
- if (active) restart();
-}
-#endif
-
-// ----------------------------------------------------------------------------
-Mat FrameRotation::rotate_frame(Mat frame)
-{
- switch (rotation)
- {
- case CLOCKWISE:
- {
- Mat dst;
- transpose(frame, dst);
- flip(dst, dst, 1);
- return dst;
- }
-
- case COUNTER_CLOCKWISE:
- {
- Mat dst;
- transpose(frame, dst);
- flip(dst, dst, 0);
- return dst;
- }
-
- default:
- return frame;
- }
-}
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + + #if defined(OPENTRACK_API) && defined(_WIN32) +#include <windows.h> +#include <dshow.h> +#endif + +#include "camera.h" +#include <string> +#include <QDebug> + +using namespace cv; + +#if defined(OPENTRACK_API) && (defined(__unix) || defined(__linux) || defined(__APPLE__)) +#include <unistd.h> +#endif + +#ifdef OPENTRACK_API +void get_camera_device_names(std::vector<std::string>& device_names) { +# if defined(_WIN32) + // Create the System Device Enumerator. + HRESULT hr; + ICreateDevEnum *pSysDevEnum = NULL; + hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); + if (FAILED(hr)) + { + return; + } + // Obtain a class enumerator for the video compressor category. + IEnumMoniker *pEnumCat = NULL; + hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); + + if (hr == S_OK) { + // Enumerate the monikers. + IMoniker *pMoniker = NULL; + ULONG cFetched; + while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); + if (SUCCEEDED(hr)) { + // To retrieve the filter's friendly name, do the following: + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + if (SUCCEEDED(hr)) + { + auto wstr = std::wstring(varName.bstrVal); + auto str = std::string(wstr.begin(), wstr.end()); + device_names.push_back(str); + } + VariantClear(&varName); + + ////// To create an instance of the filter, do the following: + ////IBaseFilter *pFilter; + ////hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, + //// (void**)&pFilter); + // Now add the filter to the graph. + //Remember to release pFilter later. + pPropBag->Release(); + } + pMoniker->Release(); + } + pEnumCat->Release(); + } + pSysDevEnum->Release(); +# else + for (int i = 0; i < 16; i++) { + char buf[128]; + sprintf(buf, "/dev/video%d", i); + if (access(buf, R_OK | W_OK) == 0) { + device_names.push_back(std::string(buf)); + } + } +# endif +} +#else +// ---------------------------------------------------------------------------- +void get_camera_device_names(std::vector<std::string>& device_names) +{ + videoInput VI; + VI.listDevices(); + std::string device_name; + for(int index = 0; ; ++index) { + device_name = VI.getDeviceName(index); + if (device_name.empty()) break; + device_names.push_back(device_name); + } +} +#endif + +// ---------------------------------------------------------------------------- +void Camera::set_device_index(int index) +{ + if (desired_index != index) + { + desired_index = index; + _set_device_index(); + + // reset fps + dt_valid = 0; + dt_mean = 0; + active_index = index; + } +} + +void Camera::set_fps(int fps) +{ + if (cam_desired.fps != fps) + { + cam_desired.fps = fps; + _set_fps(); + } +} + +void Camera::set_res(int x_res, int y_res) +{ + if (cam_desired.res_x != x_res || cam_desired.res_y != y_res) + { + cam_desired.res_x = x_res; + cam_desired.res_y = y_res; + _set_res(); + _set_fps(); + } +} + +bool Camera::get_frame(float dt, cv::Mat* frame) +{ + bool new_frame = _get_frame(frame); + // measure fps of valid frames + const float dt_smoothing_const = 0.9; + dt_valid += dt; + if (new_frame) + { + dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid; + cam_info.fps = dt_mean > 1e-3 ? 1.0 / dt_mean : 0; + dt_valid = 0; + } + return new_frame; +} + +// ---------------------------------------------------------------------------- +#ifdef OPENTRACK_API +void CVCamera::start() +{ + cap = new VideoCapture(desired_index); + // extract camera info + if (cap->isOpened()) + { + active = true; + active_index = desired_index; + cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH); + cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT); + } else { + delete cap; + cap = nullptr; + } +} + +void CVCamera::stop() +{ + if (cap) + { + cap->release(); + delete cap; + } + active = false; +} + +bool CVCamera::_get_frame(Mat* frame) +{ + if (cap && cap->isOpened()) + { + Mat img; + for (int i = 0; i < 100 && !cap->read(img); i++) + ;; + + if (img.empty()) + return false; + + *frame = img; + return true; + } + return false; +} + +void CVCamera::_set_fps() +{ + if (cap) cap->set(CV_CAP_PROP_FPS, cam_desired.fps); +} + +void CVCamera::_set_res() +{ + if (cap) + { + cap->set(CV_CAP_PROP_FRAME_WIDTH, cam_desired.res_x); + cap->set(CV_CAP_PROP_FRAME_HEIGHT, cam_desired.res_y); + cam_info.res_x = cap->get(CV_CAP_PROP_FRAME_WIDTH); + cam_info.res_y = cap->get(CV_CAP_PROP_FRAME_HEIGHT); + } +} +void CVCamera::_set_device_index() +{ + if (cap) + { + cap->release(); + delete cap; + } + cap = new VideoCapture(desired_index); +} + +#else +// ---------------------------------------------------------------------------- +VICamera::VICamera() : frame_buffer(NULL) +{ + VI.listDevices(); +} + +void VICamera::start() +{ + if (desired_index >= 0) + { + if (cam_desired.res_x == 0 || cam_desired.res_y == 0) + VI.setupDevice(desired_index); + else + VI.setupDevice(desired_index, cam_desired.res_x, cam_desired.res_y); + + active = true; + active_index = desired_index; + + cam_info.res_x = VI.getWidth(active_index); + cam_info.res_y = VI.getHeight(active_index); + new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3); + // If matrix is not continuous we have to copy manually via frame_buffer + if (!new_frame.isContinuous()) { + unsigned int size = VI.getSize(active_index); + frame_buffer = new unsigned char[size]; + } + } +} + +void VICamera::stop() +{ + if (active) + { + VI.stopDevice(active_index); + } + if (frame_buffer) + { + delete[] frame_buffer; + frame_buffer = NULL; + } + active = false; +} + +bool VICamera::_get_frame(Mat* frame) +{ + if (active && VI.isFrameNew(active_index)) + { + if (new_frame.isContinuous()) + { + VI.getPixels(active_index, new_frame.data, false, true); + } + else + { + // If matrix is not continuous we have to copy manually via frame_buffer + VI.getPixels(active_index, frame_buffer, false, true); + new_frame = cv::Mat(cam_info.res_y, cam_info.res_x, CV_8UC3, frame_buffer).clone(); + } + *frame = new_frame; + return true; + } + return false; +} + +void VICamera::_set_device_index() +{ + if (active) restart(); +} + +void VICamera::_set_f() +{ + cam_info.f = cam_desired.f; +} + +void VICamera::_set_fps() +{ + bool was_active = active; + if (active) stop(); + VI.setIdealFramerate(desired_index, cam_desired.fps); + if (was_active) start(); +} + +void VICamera::_set_res() +{ + if (active) restart(); +} +#endif + +// ---------------------------------------------------------------------------- +Mat FrameRotation::rotate_frame(Mat frame) +{ + switch (rotation) + { + case CLOCKWISE: + { + Mat dst; + transpose(frame, dst); + flip(dst, dst, 1); + return dst; + } + + case COUNTER_CLOCKWISE: + { + Mat dst; + transpose(frame, dst); + flip(dst, dst, 0); + return dst; + } + + default: + return frame; + } +} diff --git a/FTNoIR_Tracker_PT/camera.h b/ftnoir_tracker_pt/camera.h index ea68c387..889bf2d3 100644 --- a/FTNoIR_Tracker_PT/camera.h +++ b/ftnoir_tracker_pt/camera.h @@ -1,145 +1,141 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef CAMERA_H
-#define CAMERA_H
-
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-# include <opencv2/highgui/highgui.hpp>
-# include <opencv2/highgui/highgui_c.h>
-#endif
-#include <string>
-
-// ----------------------------------------------------------------------------
-void get_camera_device_names(std::vector<std::string>& device_names);
-
-
-// ----------------------------------------------------------------------------
-struct CamInfo
-{
- CamInfo() : res_x(0), res_y(0), fps(0), f(1) {}
-
- int res_x;
- int res_y;
- int fps;
- float f; // (focal length) / (sensor width)
-};
-
-// ----------------------------------------------------------------------------
-// Base class for cameras, calculates the frame rate
-class Camera
-{
-public:
- Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1), active(false) {}
- virtual ~Camera() {}
-
- // start/stop capturing
- virtual void start() = 0;
- virtual void stop() = 0;
- void restart() { stop(); start(); }
-
- // calls corresponding template methods and reinitializes frame rate calculation
- void set_device_index(int index);
- void set_f(float f);
- void set_fps(int fps);
- void set_res(int x_res, int y_res);
-
- // gets a frame from the camera, dt: time since last call in seconds
- bool get_frame(float dt, cv::Mat* frame);
-
- // WARNING: returned references are valid as long as object
- const CamInfo& get_info() const { return cam_info; }
- const CamInfo& get_desired() const { return cam_desired; }
-
-protected:
- // get a frame from the camera
- virtual bool _get_frame(cv::Mat* frame) = 0;
-
- // update the camera using cam_desired, write res and f to cam_info if successful
- virtual void _set_device_index() = 0;
- virtual void _set_f() = 0;
- virtual void _set_fps() = 0;
- virtual void _set_res() = 0;
-
- float dt_valid;
- float dt_mean;
- int desired_index;
- int active_index;
- bool active;
- CamInfo cam_info;
- CamInfo cam_desired;
-};
-
-
-// ----------------------------------------------------------------------------
-// camera based on OpenCV's videoCapture
-#ifdef OPENTRACK_API
-class CVCamera : public Camera
-{
-public:
- CVCamera() : cap(NULL) {}
- ~CVCamera() { stop(); }
-
- virtual void start();
- virtual void stop();
-
-protected:
- virtual bool _get_frame(cv::Mat* frame);
- virtual void _set_index();
- virtual void _set_f();
- virtual void _set_fps();
- virtual void _set_res();
- virtual void _set_device_index();
-
- cv::VideoCapture* cap;
-};
-#else
-// ----------------------------------------------------------------------------
-// Camera based on the videoInput library
-class VICamera : public Camera
-{
-public:
- VICamera();
- ~VICamera() { stop(); }
-
- virtual void start();
- virtual void stop();
-
-protected:
- virtual bool _get_frame(cv::Mat* frame);
- virtual void _set_device_index();
- virtual void _set_f();
- virtual void _set_fps();
- virtual void _set_res();
-
- videoInput VI;
- cv::Mat new_frame;
- unsigned char* frame_buffer;
-};
-#endif
-
-enum RotationType
-{
- CLOCKWISE = 0,
- ZERO = 1,
- COUNTER_CLOCKWISE = 2
-};
-
-// ----------------------------------------------------------------------------
-class FrameRotation
-{
-public:
- RotationType rotation;
-
- cv::Mat rotate_frame(cv::Mat frame);
-};
-
-#endif //CAMERA_H
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef CAMERA_H +#define CAMERA_H + +#include <opencv2/core/core.hpp> +#ifndef OPENTRACK_API +# include <boost/shared_ptr.hpp> +#else +# include <memory> +# include <opencv2/highgui/highgui.hpp> +# include <opencv2/highgui/highgui_c.h> +#endif +#include <string> + +// ---------------------------------------------------------------------------- +void get_camera_device_names(std::vector<std::string>& device_names); + + +// ---------------------------------------------------------------------------- +struct CamInfo +{ + CamInfo() : res_x(0), res_y(0), fps(0) {} + + int res_x; + int res_y; + int fps; +}; + +// ---------------------------------------------------------------------------- +// Base class for cameras, calculates the frame rate +class Camera +{ +public: + Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1), active(false) {} + virtual ~Camera() = 0; + + // start/stop capturing + virtual void start() = 0; + virtual void stop() = 0; + void restart() { stop(); start(); } + + // calls corresponding template methods and reinitializes frame rate calculation + void set_device_index(int index); + void set_fps(int fps); + void set_res(int x_res, int y_res); + + // gets a frame from the camera, dt: time since last call in seconds + bool get_frame(float dt, cv::Mat* frame); + + // WARNING: returned references are valid as long as object + const CamInfo& get_info() const { return cam_info; } + const CamInfo& get_desired() const { return cam_desired; } + +protected: + // get a frame from the camera + virtual bool _get_frame(cv::Mat* frame) = 0; + + // update the camera using cam_desired, write res and f to cam_info if successful + virtual void _set_device_index() = 0; + virtual void _set_fps() = 0; + virtual void _set_res() = 0; +private: + float dt_valid; + float dt_mean; +protected: + int desired_index; + int active_index; + bool active; + CamInfo cam_info; + CamInfo cam_desired; +}; +inline Camera::~Camera() {} + +// ---------------------------------------------------------------------------- +// camera based on OpenCV's videoCapture +#ifdef OPENTRACK_API +class CVCamera : public Camera +{ +public: + CVCamera() : cap(NULL) {} + ~CVCamera() { stop(); } + + void start() override; + void stop() override; + +protected: + bool _get_frame(cv::Mat* frame) override; + void _set_fps() override; + void _set_res() override; + void _set_device_index() override; + +private: + cv::VideoCapture* cap; +}; +#else +// ---------------------------------------------------------------------------- +// Camera based on the videoInput library +class VICamera : public Camera +{ +public: + VICamera(); + ~VICamera() { stop(); } + + virtual void start(); + virtual void stop(); + +protected: + virtual bool _get_frame(cv::Mat* frame); + virtual void _set_device_index(); + virtual void _set_fps(); + virtual void _set_res(); + + videoInput VI; + cv::Mat new_frame; + unsigned char* frame_buffer; +}; +#endif + +enum RotationType +{ + CLOCKWISE = 0, + ZERO = 1, + COUNTER_CLOCKWISE = 2 +}; + +// ---------------------------------------------------------------------------- +class FrameRotation +{ +public: + RotationType rotation; + + cv::Mat rotate_frame(cv::Mat frame); +}; + +#endif //CAMERA_H diff --git a/FTNoIR_Tracker_PT/doc/index.htm b/ftnoir_tracker_pt/doc/index.htm index 87b7356f..87b7356f 100644 --- a/FTNoIR_Tracker_PT/doc/index.htm +++ b/ftnoir_tracker_pt/doc/index.htm diff --git a/FTNoIR_Tracker_PT/doc/logo.png b/ftnoir_tracker_pt/doc/logo.png Binary files differindex 95032a25..95032a25 100644 --- a/FTNoIR_Tracker_PT/doc/logo.png +++ b/ftnoir_tracker_pt/doc/logo.png diff --git a/FTNoIR_Tracker_PT/doc/ptrack.ico b/ftnoir_tracker_pt/doc/ptrack.ico Binary files differindex c4b2aedc..c4b2aedc 100644 --- a/FTNoIR_Tracker_PT/doc/ptrack.ico +++ b/ftnoir_tracker_pt/doc/ptrack.ico diff --git a/FTNoIR_Tracker_PT/doc/settings1.png b/ftnoir_tracker_pt/doc/settings1.png Binary files differindex 35b84c5c..35b84c5c 100644 --- a/FTNoIR_Tracker_PT/doc/settings1.png +++ b/ftnoir_tracker_pt/doc/settings1.png diff --git a/FTNoIR_Tracker_PT/doc/settings2.png b/ftnoir_tracker_pt/doc/settings2.png Binary files differindex c6cfd1f3..c6cfd1f3 100644 --- a/FTNoIR_Tracker_PT/doc/settings2.png +++ b/ftnoir_tracker_pt/doc/settings2.png diff --git a/FTNoIR_Tracker_PT/doc/settings3.png b/ftnoir_tracker_pt/doc/settings3.png Binary files differindex 5922403d..5922403d 100644 --- a/FTNoIR_Tracker_PT/doc/settings3.png +++ b/ftnoir_tracker_pt/doc/settings3.png diff --git a/FTNoIR_Tracker_PT/doc/style.css b/ftnoir_tracker_pt/doc/style.css index a8d3e333..0c3d29a6 100644 --- a/FTNoIR_Tracker_PT/doc/style.css +++ b/ftnoir_tracker_pt/doc/style.css @@ -1,131 +1,131 @@ -body {
- width: 1000px;
- font-size: 13px;
- color: #000000;
- padding: 0;
- margin: 0 auto;
- background: #444444;
- font-family: verdana,arial;
-}
-
-table {
- border-width: 3px;
- border-color: #0000FF;
- border-style: ridge;
- margin-top: 5px;
- background-color: #E0E0FF;
-}
-
-table.blind {
- border: none;
- background-color: #E6E6E6;
-}
-
-fieldset.blind {
- border: none;
-}
-
-h1 { font-size: 160%; }
-h2 { font-size: 140%; }
-h3 { font-size: 115%; }
-
-.indent {
- margin-left: 25px;
-}
-
-p
-{
- margin-left: 10px;
-}
-
-li
-{
- margin: 10px;
-}
-
-
-dl
-{
- /*width: 80%;*/
- border-bottom: 1px solid #999;
-}
-
-dt
-{
- padding-top: 5px;
- font-weight: bold;
- border-top: 1px solid #999;
-}
-
-dd
-{
- padding: 5px;
-}
-
-
-hr {
- color: #688938;
-}
-
-a:link, a:visited {
- color: #0000BF;
-}
-a:hover {
- color: #0000FF;
-}
-
-a.nav {
- position: relative;
- top: -30px;
- display: block;
- visibility: hidden;
-}
-
-#navbar {
- width: 1000px;
- height: 30px;
- background-color:#1a1a1b;
- position: fixed;
- margin: 0 auto;
- padding: 0;
-}
-
-#navbar ul
-{
- list-style-type: none;
- margin: 0 auto;
- padding: 0;
- overflow: hidden;
-}
-
-#navbar li
-{
- margin: 0 auto;
- padding: 5px;
- float:left;
-}
-
-#navbar a:link,a:visited
-{
- display:block;
- width:150px;
- font-weight:bold;
- color:#e85d02;
- text-align:center;
- /*padding:4px;*/
- text-decoration:none;
- /*text-transform:uppercase;*/
-}
-
-#navbar a:hover,a:active
-{
- color:#ffffff;
-}
-
-#content {
- background-color:#ffffff;
- padding: 15px;
- padding-top: 40px;
- padding-right: 40px;
- margin: 0 auto;
-}
+body { + width: 1000px; + font-size: 13px; + color: #000000; + padding: 0; + margin: 0 auto; + background: #444444; + font-family: verdana,arial; +} + +table { + border-width: 3px; + border-color: #0000FF; + border-style: ridge; + margin-top: 5px; + background-color: #E0E0FF; +} + +table.blind { + border: none; + background-color: #E6E6E6; +} + +fieldset.blind { + border: none; +} + +h1 { font-size: 160%; } +h2 { font-size: 140%; } +h3 { font-size: 115%; } + +.indent { + margin-left: 25px; +} + +p +{ + margin-left: 10px; +} + +li +{ + margin: 10px; +} + + +dl +{ + /*width: 80%;*/ + border-bottom: 1px solid #999; +} + +dt +{ + padding-top: 5px; + font-weight: bold; + border-top: 1px solid #999; +} + +dd +{ + padding: 5px; +} + + +hr { + color: #688938; +} + +a:link, a:visited { + color: #0000BF; +} +a:hover { + color: #0000FF; +} + +a.nav { + position: relative; + top: -30px; + display: block; + visibility: hidden; +} + +#navbar { + width: 1000px; + height: 30px; + background-color:#1a1a1b; + position: fixed; + margin: 0 auto; + padding: 0; +} + +#navbar ul +{ + list-style-type: none; + margin: 0 auto; + padding: 0; + overflow: hidden; +} + +#navbar li +{ + margin: 0 auto; + padding: 5px; + float:left; +} + +#navbar a:link,a:visited +{ + display:block; + width:150px; + font-weight:bold; + color:#e85d02; + text-align:center; + /*padding:4px;*/ + text-decoration:none; + /*text-transform:uppercase;*/ +} + +#navbar a:hover,a:active +{ + color:#ffffff; +} + +#content { + background-color:#ffffff; + padding: 15px; + padding-top: 40px; + padding-right: 40px; + margin: 0 auto; +} diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp index ef72f9a2..8b77b681 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp @@ -1,265 +1,226 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "ftnoir_tracker_pt.h"
-#include <QHBoxLayout>
-#include <cmath>
-#include <QDebug>
-#include <QFile>
-#include <QCoreApplication>
-
-using namespace std;
-using namespace cv;
-using namespace boost;
-
-//#define PT_PERF_LOG //log performance
-
-const float rad2deg = 180.0/3.14159265;
-const float deg2rad = 1.0/rad2deg;
-
-//-----------------------------------------------------------------------------
-Tracker::Tracker()
- : mutex(QMutex::Recursive),
- commands(0),
- video_widget(NULL),
- video_frame(NULL),
- tracking_valid(false),
- new_settings(nullptr)
-
-{
- qDebug()<<"Tracker::Tracker";
-}
-
-Tracker::~Tracker()
-{
- qDebug()<<"Tracker::~Tracker";
- // terminate tracker thread
- set_command(ABORT);
- wait();
- s.video_widget = false;
- delete video_widget;
- video_widget = NULL;
- if (video_frame->layout()) delete video_frame->layout();
-}
-
-void Tracker::set_command(Command command)
-{
- //QMutexLocker lock(&mutex);
- commands |= command;
-}
-
-void Tracker::reset_command(Command command)
-{
- //QMutexLocker lock(&mutex);
- commands &= ~command;
-}
-
-void Tracker::run()
-{
- qDebug()<<"Tracker:: Thread started";
-
-#ifdef PT_PERF_LOG
- QFile log_file(QCoreApplication::applicationDirPath() + "/PointTrackerPerformance.txt");
- if (!log_file.open(QIODevice::WriteOnly | QIODevice::Text)) return;
- QTextStream log_stream(&log_file);
-#endif
-
- time.start();
- double dt;
- bool new_frame;
- forever
- {
- if (commands & ABORT) break;
- if (commands & PAUSE) continue;
- commands = 0;
- apply_inner();
- dt = time.start() / 1000000000.;
-
- new_frame = camera.get_frame(dt, &frame);
-
- if (new_frame && !frame.empty())
- {
- QMutexLocker lock(&mutex);
-
- frame = frame_rotation.rotate_frame(frame);
- const std::vector<cv::Vec2f>& points = point_extractor.extract_points(frame, dt, true);
- for (auto p : points)
- {
- auto p2 = cv::Point(p[0] * frame.cols + frame.cols/2, -p[1] * frame.cols + frame.rows/2);
- cv::Scalar color(0, 255, 0);
- cv::line(frame,
- cv::Point(p2.x - 20, p2.y),
- cv::Point(p2.x + 20, p2.y),
- color,
- 4);
- cv::line(frame,
- cv::Point(p2.x, p2.y - 20),
- cv::Point(p2.x, p2.y + 20),
- color,
- 4);
- }
- tracking_valid = point_tracker.track(points, camera.get_info().f, dt);
- video_widget->update_image(frame);
- }
-#ifdef PT_PERF_LOG
- log_stream<<"dt: "<<dt;
- if (!frame.empty()) log_stream<<" fps: "<<camera.get_info().fps;
- log_stream<<"\n";
-#endif
- }
-
- qDebug()<<"Tracker:: Thread stopping";
-}
-void Tracker::apply(settings& s)
-{
- // caller guarantees object lifetime
- new_settings = &s;
-}
-
-void Tracker::apply_inner()
-{
- settings* tmp = new_settings.exchange(nullptr);
- if (tmp == nullptr)
- return;
- auto& s = *tmp;
- qDebug()<<"Tracker:: Applying settings";
- camera.set_device_index(s.cam_index);
- camera.set_res(s.cam_res_x, s.cam_res_y);
- camera.set_fps(s.cam_fps);
- camera.set_f(s.cam_f);
- frame_rotation.rotation = static_cast<RotationType>(static_cast<int>(s.cam_roll));
- point_extractor.threshold_val = s.threshold;
- point_extractor.threshold_secondary_val = s.threshold_secondary;
- point_extractor.min_size = s.min_point_size;
- point_extractor.max_size = s.max_point_size;
- {
- cv::Vec3f M01(s.m01_x, s.m01_y, s.m01_z);
- cv::Vec3f M02(s.m02_x, s.m02_y, s.m02_z);
- point_tracker.point_model = boost::shared_ptr<PointModel>(new PointModel(M01, M02));
- }
- point_tracker.dynamic_pose_resolution = s.dyn_pose_res;
- point_tracker.dt_reset = s.reset_time / 1000.0;
- t_MH = cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z);
- R_GC = Matx33f( cos(deg2rad*s.cam_yaw), 0, sin(deg2rad*s.cam_yaw),
- 0, 1, 0,
- -sin(deg2rad*s.cam_yaw), 0, cos(deg2rad*s.cam_yaw));
- R_GC = R_GC * Matx33f( 1, 0, 0,
- 0, cos(deg2rad*s.cam_pitch), sin(deg2rad*s.cam_pitch),
- 0, -sin(deg2rad*s.cam_pitch), cos(deg2rad*s.cam_pitch));
-
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- X_GH_0 = R_GC * X_MH;
-
- qDebug()<<"Tracker::apply ends";
-}
-
-void Tracker::reset()
-{
- QMutexLocker lock(&mutex);
- point_tracker.reset();
-}
-
-void Tracker::center()
-{
- point_tracker.reset(); // we also do a reset here since there is no reset shortkey yet
- QMutexLocker lock(&mutex);
- FrameTrafo X_CM_0 = point_tracker.get_pose();
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- X_GH_0 = R_GC * X_CM_0 * X_MH;
-}
-
-bool Tracker::get_frame_and_points(cv::Mat& frame_copy, boost::shared_ptr< std::vector<Vec2f> >& points)
-{
- QMutexLocker lock(&mutex);
- if (frame.empty()) return false;
-
- // copy the frame and points from the tracker thread
- frame_copy = frame.clone();
- points = boost::shared_ptr< vector<Vec2f> >(new vector<Vec2f>(point_extractor.get_points()));
- return true;
-}
-
-void Tracker::refreshVideo()
-{
- if (video_widget) video_widget->update_frame_and_points();
-}
-
-void Tracker::StartTracker(QFrame *parent_window)
-{
- this->video_frame = parent_window;
- video_frame->setAttribute(Qt::WA_NativeWindow);
- video_frame->show();
- video_widget = new PTVideoWidget(video_frame, this);
- QHBoxLayout* video_layout = new QHBoxLayout(parent_window);
- video_layout->setContentsMargins(0, 0, 0, 0);
- video_layout->addWidget(video_widget);
- video_frame->setLayout(video_layout);
- video_widget->resize(video_frame->width(), video_frame->height());
- camera.start();
- apply(s);
- start();
- reset_command(PAUSE);
-}
-
-#ifndef OPENTRACK_API
-void Tracker::StopTracker(bool exit)
-{
- set_command(PAUSE);
-}
-#endif
-
-#ifdef OPENTRACK_API
-#define THeadPoseData double
-#endif
-
-void Tracker::GetHeadPoseData(THeadPoseData *data)
-{
- {
- QMutexLocker lock(&mutex);
-
- if (!tracking_valid) return;
-
- FrameTrafo X_CM = point_tracker.get_pose();
- FrameTrafo X_MH(Matx33f::eye(), t_MH);
- FrameTrafo X_GH = R_GC * X_CM * X_MH;
- Matx33f R = X_GH.R * X_GH_0.R.t();
- Vec3f t = X_GH.t - X_GH_0.t;
-
- // get translation(s)
- if (s.bEnableX) data[TX] = t[0] / 10.0; // convert to cm
- if (s.bEnableY) data[TY] = t[1] / 10.0;
- if (s.bEnableZ) data[TZ] = t[2] / 10.0;
-
- // translate rotation matrix from opengl (G) to roll-pitch-yaw (E) frame
- // -z -> x, y -> z, x -> -y
- Matx33f R_EG( 0, 0,-1,
- -1, 0, 0,
- 0, 1, 0);
- R = R_EG * R * R_EG.t();
-
- // extract rotation angles
- float alpha, beta, gamma;
- beta = atan2( -R(2,0), sqrt(R(2,1)*R(2,1) + R(2,2)*R(2,2)) );
- alpha = atan2( R(1,0), R(0,0));
- gamma = atan2( R(2,1), R(2,2));
-
- if (s.bEnableYaw) data[Yaw] = rad2deg * alpha;
- if (s.bEnablePitch) data[Pitch] = - rad2deg * beta; // FTNoIR expects a minus here
- if (s.bEnableRoll) data[Roll] = rad2deg * gamma;
- }
-}
-
-//-----------------------------------------------------------------------------
-#ifdef OPENTRACK_API
-extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
-#else
-#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
-FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
-#endif
-{
- return new Tracker;
-}
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "ftnoir_tracker_pt.h" +#include <QHBoxLayout> +#include <cmath> +#include <QDebug> +#include <QFile> +#include <QCoreApplication> + +using namespace std; +using namespace cv; + +//#define PT_PERF_LOG //log performance + +//----------------------------------------------------------------------------- +Tracker::Tracker() + : mutex(QMutex::Recursive), + commands(0), + video_widget(NULL), + video_frame(NULL), + new_settings(nullptr) +{ +} + +Tracker::~Tracker() +{ + set_command(ABORT); + wait(); + delete video_widget; + video_widget = NULL; + if (video_frame->layout()) delete video_frame->layout(); +} + +void Tracker::set_command(Command command) +{ + //QMutexLocker lock(&mutex); + commands |= command; +} + +void Tracker::reset_command(Command command) +{ + //QMutexLocker lock(&mutex); + commands &= ~command; +} + +void Tracker::run() +{ +#ifdef PT_PERF_LOG + QFile log_file(QCoreApplication::applicationDirPath() + "/PointTrackerPerformance.txt"); + if (!log_file.open(QIODevice::WriteOnly | QIODevice::Text)) return; + QTextStream log_stream(&log_file); +#endif + time.start(); + while((commands & ABORT) == 0) + { + apply_inner(); + const double dt = time.start() * 1e-9; + const bool new_frame = camera.get_frame(dt, &frame); + + if (new_frame && !frame.empty()) + { + QMutexLocker lock(&mutex); + + frame = frame_rotation.rotate_frame(frame); + const std::vector<cv::Vec2f>& points = point_extractor.extract_points(frame); + for (auto p : points) + { + auto p2 = cv::Point(p[0] * frame.cols + frame.cols/2, -p[1] * frame.cols + frame.rows/2); + cv::Scalar color(0, 255, 0); + cv::line(frame, + cv::Point(p2.x - 20, p2.y), + cv::Point(p2.x + 20, p2.y), + color, + 4); + cv::line(frame, + cv::Point(p2.x, p2.y - 20), + cv::Point(p2.x, p2.y + 20), + color, + 4); + } + if (points.size() == PointModel::N_POINTS) + point_tracker.track(points, model); + video_widget->update_image(frame); + } +#ifdef PT_PERF_LOG + log_stream<<"dt: "<<dt; + if (!frame.empty()) log_stream<<" fps: "<<camera.get_info().fps; + log_stream<<"\n"; +#endif + } + + qDebug()<<"Tracker:: Thread stopping"; +} +void Tracker::apply(settings& s) +{ + // caller guarantees object lifetime + new_settings = &s; +} + +void Tracker::apply_inner() +{ + settings* tmp = new_settings.exchange(nullptr); + if (tmp == nullptr) + return; + reset(); + auto& s = *tmp; + qDebug()<<"Tracker:: Applying settings"; + + { + cv::Vec3f M01(s.m01_x, s.m01_y, s.m01_z); + cv::Vec3f M02(s.m02_x, s.m02_y, s.m02_z); + model = PointModel(M01, M02); + } + camera.set_device_index(s.cam_index); + camera.set_res(s.cam_res_x, s.cam_res_y); + camera.set_fps(s.cam_fps); + frame_rotation.rotation = static_cast<RotationType>(static_cast<int>(s.cam_roll)); + point_extractor.threshold_val = s.threshold; + point_extractor.threshold_secondary_val = s.threshold_secondary; + point_extractor.min_size = s.min_point_size; + point_extractor.max_size = s.max_point_size; + t_MH = cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z); + R_GC = Matx33f( cos(deg2rad*s.cam_yaw), 0, sin(deg2rad*s.cam_yaw), + 0, 1, 0, + -sin(deg2rad*s.cam_yaw), 0, cos(deg2rad*s.cam_yaw)); + R_GC = R_GC * Matx33f( 1, 0, 0, + 0, cos(deg2rad*s.cam_pitch), sin(deg2rad*s.cam_pitch), + 0, -sin(deg2rad*s.cam_pitch), cos(deg2rad*s.cam_pitch)); + + FrameTrafo X_MH(Matx33f::eye(), t_MH); + X_GH_0 = R_GC * X_MH; + qDebug()<<"Tracker::apply ends"; +} + +void Tracker::reset() +{ + QMutexLocker lock(&mutex); + point_tracker.reset(); +} + +void Tracker::center() +{ + point_tracker.reset(); // we also do a reset here since there is no reset shortkey yet + QMutexLocker lock(&mutex); + FrameTrafo X_CM_0 = point_tracker.get_pose(); + FrameTrafo X_MH(Matx33f::eye(), t_MH); + X_GH_0 = R_GC * X_CM_0 * X_MH; +} + +void Tracker::StartTracker(QFrame *parent_window) +{ + this->video_frame = parent_window; + video_frame->setAttribute(Qt::WA_NativeWindow); + video_frame->show(); + video_widget = new PTVideoWidget(video_frame); + QHBoxLayout* video_layout = new QHBoxLayout(parent_window); + video_layout->setContentsMargins(0, 0, 0, 0); + video_layout->addWidget(video_widget); + video_frame->setLayout(video_layout); + video_widget->resize(video_frame->width(), video_frame->height()); + camera.start(); + apply(s); + start(); +} + +#ifndef OPENTRACK_API +void Tracker::StopTracker(bool exit) +{ + set_command(PAUSE); +} +#endif + +#ifdef OPENTRACK_API +#define THeadPoseData double +#endif + +void Tracker::GetHeadPoseData(THeadPoseData *data) +{ + { + QMutexLocker lock(&mutex); + + FrameTrafo X_CM = point_tracker.get_pose(); + FrameTrafo X_MH(Matx33f::eye(), t_MH); + FrameTrafo X_GH = R_GC * X_CM * X_MH; + Matx33f R = X_GH.R * X_GH_0.R.t(); + Vec3f t = X_GH.t - X_GH_0.t; + + // get translation(s) + data[TX] = t[0] / 10.0; // convert to cm + data[TY] = t[1] / 10.0; + data[TZ] = t[2] / 10.0; + + // translate rotation matrix from opengl (G) to roll-pitch-yaw (E) frame + // -z -> x, y -> z, x -> -y + Matx33f R_EG( 0, 0,-1, + -1, 0, 0, + 0, 1, 0); + R = R_EG * R * R_EG.t(); + + // extract rotation angles + float alpha, beta, gamma; + beta = atan2( -R(2,0), sqrt(R(2,1)*R(2,1) + R(2,2)*R(2,2)) ); + alpha = atan2( R(1,0), R(0,0)); + gamma = atan2( R(2,1), R(2,2)); + + data[Yaw] = rad2deg * alpha; + data[Pitch] = - rad2deg * beta; // FTNoIR expects a minus here + data[Roll] = rad2deg * gamma; + } +} + +//----------------------------------------------------------------------------- +#ifdef OPENTRACK_API +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() +#else +#pragma comment(linker, "/export:GetTracker=_GetTracker@0") +OPENTRACK_EXPORT ITrackerPtr __stdcall GetTracker() +#endif +{ + return new Tracker; +} diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.h b/ftnoir_tracker_pt/ftnoir_tracker_pt.h new file mode 100644 index 00000000..fff8d4ab --- /dev/null +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef FTNOIR_TRACKER_PT_H +#define FTNOIR_TRACKER_PT_H + +#ifdef OPENTRACK_API +# include "facetracknoir/plugin-api.hpp" +#endif +#include "ftnoir_tracker_pt_settings.h" +#include "camera.h" +#include "point_extractor.h" +#include "point_tracker.h" +#include "pt_video_widget.h" +#include "facetracknoir/timer.hpp" + +#include <QThread> +#include <QMutex> +#include <QMutexLocker> +#include <QTime> +#include <opencv2/core/core.hpp> +#include <atomic> +#ifndef OPENTRACK_API +# include <boost/shared_ptr.hpp> +#else +# include <memory> +#endif +#include <vector> + +//----------------------------------------------------------------------------- +// Constantly processes the tracking chain in a separate thread +class Tracker : public ITracker, protected QThread +{ +public: + Tracker(); + ~Tracker() override; + void StartTracker(QFrame* parent_window) override; + void GetHeadPoseData(double* data) override; + + void apply(settings& s); + void apply_inner(); + void center(); + void reset(); // reset the trackers internal state variables + + void get_pose(FrameTrafo* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.get_pose(); } + int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); } + void get_cam_info(CamInfo* info) { QMutexLocker lock(&mutex); *info = camera.get_info(); } +protected: + void run() override; +private: + QMutex mutex; + // thread commands + enum Command { + ABORT = 1<<0 + }; + void set_command(Command command); + void reset_command(Command command); + volatile int commands; + + CVCamera camera; + FrameRotation frame_rotation; + PointExtractor point_extractor; + PointTracker point_tracker; + + FrameTrafo X_GH_0; // for centering + cv::Vec3f t_MH; // translation from model frame to head frame + cv::Matx33f R_GC; // rotation from opengl reference frame to camera frame + + // --- ui --- + cv::Mat frame; // the output frame for display + + PTVideoWidget* video_widget; + QFrame* video_frame; + + settings s; + std::atomic<settings*> new_settings; + Timer time; + + static constexpr double rad2deg = 180.0/3.14159265; + static constexpr double deg2rad = 3.14159265/180.0; + + PointModel model; +}; + +#undef VideoWidget + +#endif // FTNOIR_TRACKER_PT_H diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.qrc b/ftnoir_tracker_pt/ftnoir_tracker_pt.qrc index a8f9a1af..a8f9a1af 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt.qrc +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.qrc diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp new file mode 100644 index 00000000..981cbea0 --- /dev/null +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp @@ -0,0 +1,258 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "ftnoir_tracker_pt_dialog.h" + +#include <QMessageBox> +#include <QDebug> +#include <opencv2/core/core.hpp> +#ifndef OPENTRACK_API +# include <boost/shared_ptr.hpp> +#else +# include <memory> +#endif +#include <vector> + +using namespace std; + +//----------------------------------------------------------------------------- +TrackerDialog::TrackerDialog() + : tracker(NULL), + timer(this), + trans_calib_running(false) +{ + ui.setupUi( this ); + + vector<string> device_names; + get_camera_device_names(device_names); + for (vector<string>::iterator iter = device_names.begin(); iter != device_names.end(); ++iter) + { + ui.camdevice_combo->addItem(iter->c_str()); + } + + ui.camroll_combo->addItem("-90"); + ui.camroll_combo->addItem("0"); + ui.camroll_combo->addItem("90"); + + tie_setting(s.cam_index, ui.camdevice_combo); + tie_setting(s.cam_res_x, ui.res_x_spin); + tie_setting(s.cam_res_y, ui.res_y_spin); + tie_setting(s.cam_fps, ui.fps_spin); + tie_setting(s.cam_roll, ui.camroll_combo); + tie_setting(s.cam_pitch, ui.campitch_spin); + tie_setting(s.cam_yaw, ui.camyaw_spin); + + tie_setting(s.threshold_secondary, ui.threshold_secondary_slider); + tie_setting(s.threshold, ui.threshold_slider); + + tie_setting(s.min_point_size, ui.mindiam_spin); + tie_setting(s.max_point_size, ui.maxdiam_spin); + + tie_setting(s.clip_by, ui.clip_bheight_spin); + tie_setting(s.clip_bz, ui.clip_blength_spin); + tie_setting(s.clip_ty, ui.clip_theight_spin); + tie_setting(s.clip_tz, ui.clip_tlength_spin); + + tie_setting(s.cap_x, ui.cap_width_spin); + tie_setting(s.cap_y, ui.cap_height_spin); + tie_setting(s.cap_z, ui.cap_length_spin); + + tie_setting(s.m01_x, ui.m1x_spin); + tie_setting(s.m01_y, ui.m1y_spin); + tie_setting(s.m01_z, ui.m1z_spin); + + tie_setting(s.m02_x, ui.m2x_spin); + tie_setting(s.m02_y, ui.m2y_spin); + tie_setting(s.m02_z, ui.m2z_spin); + + tie_setting(s.t_MH_x, ui.tx_spin); + tie_setting(s.t_MH_y, ui.ty_spin); + tie_setting(s.t_MH_z, ui.tz_spin); + + connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) ); + + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + + ui.model_tabs->setCurrentIndex(s.active_model_panel); + + connect(ui.model_tabs, SIGNAL(currentChanged(int)), this, SLOT(set_model(int))); + connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info())); + timer.start(100); + + connect(ui.buttonBox_2, SIGNAL(clicked(QAbstractButton*)), this, SLOT(do_apply_without_saving(QAbstractButton*))); +} + +void TrackerDialog::set_model_clip() +{ + s.m01_x = 0; + s.m01_y = static_cast<double>(s.clip_ty); + s.m01_z = -static_cast<double>(s.clip_tz); + s.m02_x = 0; + s.m02_y = -static_cast<double>(s.clip_by); + s.m02_z = -static_cast<double>(s.clip_bz); + + settings_changed(); +} + +void TrackerDialog::set_model_cap() +{ + s.m01_x = -static_cast<double>(s.cap_x); + s.m01_y = -static_cast<double>(s.cap_y); + s.m01_z = -static_cast<double>(s.cap_z); + s.m02_x = static_cast<double>(s.cap_x); + s.m02_y = -static_cast<double>(s.cap_y); + s.m02_z = -static_cast<double>(s.cap_z); + + settings_changed(); +} + +void TrackerDialog::set_model_custom() +{ + settings_changed(); +} + +void TrackerDialog::set_model(int val) +{ + s.active_model_panel = val; +} + +void TrackerDialog::startstop_trans_calib(bool start) +{ + if (start) + { + qDebug()<<"TrackerDialog:: Starting translation calibration"; + trans_calib.reset(); + trans_calib_running = true; + } + else + { + qDebug()<<"TrackerDialog:: Stoppping translation calibration"; + trans_calib_running = false; + { + auto tmp = trans_calib.get_estimate(); + s.t_MH_x = tmp[0]; + s.t_MH_y = tmp[1]; + s.t_MH_z = tmp[2]; + } + settings_changed(); + } +} + +void TrackerDialog::poll_tracker_info() +{ + if (tracker) + { + QString to_print; + + // display caminfo + CamInfo info; + tracker->get_cam_info(&info); + to_print = QString::number(info.res_x)+"x"+QString::number(info.res_y)+" @ "+QString::number(info.fps)+" FPS"; + ui.caminfo_label->setText(to_print); + + // display pointinfo + int n_points = tracker->get_n_points(); + to_print = QString::number(n_points); + if (n_points == 3) + to_print += " OK!"; + else + to_print += " BAD!"; + ui.pointinfo_label->setText(to_print); + + // update calibration + if (trans_calib_running) trans_calib_step(); + } + else + { + QString to_print = "Tracker offline"; + ui.caminfo_label->setText(to_print); + ui.pointinfo_label->setText(to_print); + } +} + +void TrackerDialog::trans_calib_step() +{ + if (tracker) + { + FrameTrafo X_CM; + tracker->get_pose(&X_CM); + trans_calib.update(X_CM.R, X_CM.t); + cv::Vec3f t_MH = trans_calib.get_estimate(); + s.t_MH_x = t_MH[0]; + s.t_MH_y = t_MH[1]; + s.t_MH_z = t_MH[2]; + } +} + +void TrackerDialog::settings_changed() +{ + if (tracker) tracker->apply(s); +} + +void TrackerDialog::save() +{ + do_apply_without_saving(nullptr); + s.b->save(); +} + +void TrackerDialog::doOK() +{ + save(); + close(); +} + +void TrackerDialog::do_apply_without_saving(QAbstractButton*) +{ + switch (s.active_model_panel) { + default: + case 0: + set_model_clip(); + break; + case 1: + set_model_cap(); + break; + case 2: + set_model_custom(); + break; + } + if (tracker) tracker->apply(s); +} + +void TrackerDialog::doApply() +{ + save(); +} + +void TrackerDialog::doCancel() +{ + s.b->reload(); + close(); +} + +void TrackerDialog::registerTracker(ITracker *t) +{ + qDebug()<<"TrackerDialog:: Tracker registered"; + tracker = static_cast<Tracker*>(t); + if (isVisible() & s.b->modifiedp()) + tracker->apply(s); + ui.tcalib_button->setEnabled(true); + //ui.center_button->setEnabled(true); +} + +void TrackerDialog::unRegisterTracker() +{ + qDebug()<<"TrackerDialog:: Tracker un-registered"; + tracker = NULL; + ui.tcalib_button->setEnabled(false); + //ui.center_button->setEnabled(false); +} + +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) +{ + return new TrackerDialog; +} diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h index 0325160d..bff12dd0 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dialog.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h @@ -1,70 +1,62 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef FTNOIR_TRACKER_PT_DIALOG_H
-#define FTNOIR_TRACKER_PT_DIALOG_H
-
-#ifdef OPENTRACK_API
-#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-#else
-#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
-#endif
-#include "ftnoir_tracker_pt_settings.h"
-#include "ftnoir_tracker_pt.h"
-#include "trans_calib.h"
-#include "pt_video_widget.h"
-#include "ui_FTNoIR_PT_Controls.h"
-
-#include <QTimer>
-
-//-----------------------------------------------------------------------------
-// The dialog that shows up when the user presses "Settings"
-class TrackerDialog : public QWidget, Ui::UICPTClientControls, public ITrackerDialog
-{
- Q_OBJECT
-public:
- TrackerDialog();
- void registerTracker(ITracker *tracker);
- void unRegisterTracker();
- void save();
- void trans_calib_step();
-
-public slots:
- void doCenter();
- void doReset();
- void doOK();
- void doApply();
- void doCancel();
- void do_apply_without_saving();
-
- void startstop_trans_calib(bool start);
- void widget_destroyed(QObject* obj);
- void create_video_widget();
- void poll_tracker_info();
- void set_model(int idx);
-
-protected:
- void destroy_video_widget(bool do_delete = true);
-
- void set_model_clip();
- void set_model_cap();
- void set_model_custom();
-
- void settings_changed();
-
- settings s;
- Tracker* tracker;
- VideoWidgetDialog* video_widget_dialog;
- QTimer timer;
-
- TranslationCalibrator trans_calib;
- bool trans_calib_running;
-
- Ui::UICPTClientControls ui;
-};
-
-#endif //FTNOIR_TRACKER_PT_DIALOG_H
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef FTNOIR_TRACKER_PT_DIALOG_H +#define FTNOIR_TRACKER_PT_DIALOG_H + +#ifdef OPENTRACK_API +# include "facetracknoir/plugin-api.hpp" +#else +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#endif +#include "ftnoir_tracker_pt_settings.h" +#include "ftnoir_tracker_pt.h" +#include "trans_calib.h" +#include "pt_video_widget.h" +#include "ui_FTNoIR_PT_Controls.h" + +#include <QTimer> + +//----------------------------------------------------------------------------- +// The dialog that shows up when the user presses "Settings" +class TrackerDialog : public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + TrackerDialog(); + void registerTracker(ITracker *tracker) override; + void unRegisterTracker() override; + void save(); + void trans_calib_step(); + +public slots: + void doOK(); + void doCancel(); + void doApply(); + void do_apply_without_saving(QAbstractButton *); + + void startstop_trans_calib(bool start); + void poll_tracker_info(); + void set_model(int idx); +private: + void set_model_clip(); + void set_model_cap(); + void set_model_custom(); + + void settings_changed(); + + settings s; + Tracker* tracker; + QTimer timer; + + TranslationCalibrator trans_calib; + bool trans_calib_running; + + Ui::UICPTClientControls ui; +}; + +#endif //FTNOIR_TRACKER_PT_DIALOG_H diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp index f3fbbef7..fb756a86 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp @@ -1,42 +1,42 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "ftnoir_tracker_pt_dll.h"
-#include <QIcon>
-
-//-----------------------------------------------------------------------------
-void TrackerDll::getFullName(QString *strToBeFilled)
-{
- *strToBeFilled = "PointTracker 1.1";
-}
-
-void TrackerDll::getShortName(QString *strToBeFilled)
-{
- *strToBeFilled = "PointTracker";
-}
-
-void TrackerDll::getDescription(QString *strToBeFilled)
-{
- *strToBeFilled = "Tracks a 3-point model with know geometry like Freetrack / TrackIR";
-}
-
-void TrackerDll::getIcon(QIcon *icon)
-{
- *icon = QIcon(":/Resources/Logo_IR.png");
-}
-
-
-#ifdef OPENTRACK_API
-# include "facetracknoir/global-settings.h"
-extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
-#else
-# pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
-FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
-#endif
-{
- return new TrackerDll;
-}
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "ftnoir_tracker_pt_dll.h" +#include <QIcon> + +//----------------------------------------------------------------------------- +void TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = "PointTracker 1.1"; +} + +void TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = "PointTracker"; +} + +void TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = "Tracks a 3-point model with know geometry like Freetrack / TrackIR"; +} + +void TrackerDll::getIcon(QIcon *icon) +{ + *icon = QIcon(":/Resources/Logo_IR.png"); +} + + +#ifdef OPENTRACK_API +# include "facetracknoir/plugin-support.h" +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() +#else +# pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") +OPENTRACK_EXPORT ITrackerDllPtr __stdcall GetTrackerDll() +#endif +{ + return new TrackerDll; +} diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h index 1d30e7e5..50f66a35 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_dll.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h @@ -1,27 +1,26 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#if defined(OPENTRACK_API)
-# include "ftnoir_tracker_base/ftnoir_tracker_base.h"
-# include "facetracknoir/global-settings.h"
-#else
-# include "../ftnoir_tracker_base/ftnoir_tracker_base.h"
-#endif
-
-//-----------------------------------------------------------------------------
-class TrackerDll :
-#if defined(OPENTRACK_API)
- public Metadata
-#else
- public ITrackerDll
-#endif
-{
- void getFullName(QString *strToBeFilled);
- void getShortName(QString *strToBeFilled);
- void getDescription(QString *strToBeFilled);
- void getIcon(QIcon *icon);
-};
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#if defined(OPENTRACK_API) +# include "facetracknoir/plugin-api.hpp" +#else +# include "../ftnoir_tracker_base/ftnoir_tracker_base.h" +#endif + +//----------------------------------------------------------------------------- +class TrackerDll : +#if defined(OPENTRACK_API) + public Metadata +#else + public ITrackerDll +#endif +{ + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); +}; diff --git a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_settings.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h index 109090b3..e8cac679 100644 --- a/FTNoIR_Tracker_PT/ftnoir_tracker_pt_settings.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h @@ -1,90 +1,75 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#ifndef FTNOIR_TRACKER_PT_SETTINGS_H
-#define FTNOIR_TRACKER_PT_SETTINGS_H
-
-#include <opencv2/opencv.hpp>
-#include "point_tracker.h"
-
-#include "facetracknoir/options.h"
-using namespace options;
-
-struct settings
-{
- pbundle b;
- value<int> cam_index,
- cam_res_x,
- cam_res_y,
- cam_fps,
- cam_roll,
- cam_pitch,
- cam_yaw,
- threshold,
- threshold_secondary,
- min_point_size,
- max_point_size;
- value<double> cam_f;
-
- value<int> m01_x, m01_y, m01_z;
- value<int> m02_x, m02_y, m02_z;
- value<bool> dyn_pose_res, video_widget;
-
- value<int> t_MH_x, t_MH_y, t_MH_z;
-
- value<int> reset_time;
-
- value<bool> bEnableYaw, bEnablePitch, bEnableRoll;
- value<bool> bEnableX, bEnableY, bEnableZ;
-
- value<int> clip_ty, clip_tz, clip_by, clip_bz;
- value<int> active_model_panel, cap_x, cap_y, cap_z;
-
- settings() :
- b(bundle("tracker-pt")),
- cam_index(b, "camera-index", 0),
- cam_res_x(b, "camera-res-width", 640),
- cam_res_y(b, "camera-res-height", 480),
- cam_fps(b, "camera-fps", 30),
- cam_roll(b, "camera-roll", 1),
- cam_pitch(b, "camera-pitch", 0),
- cam_yaw(b, "camera-yaw", 0),
- threshold(b, "threshold-primary", 128),
- threshold_secondary(b, "threshold-secondary", 128),
- min_point_size(b, "min-point-size", 10),
- max_point_size(b, "max-point-size", 50),
- cam_f(b, "camera-focal-length", 1),
- m01_x(b, "m_01-x", 0),
- m01_y(b, "m_01-y", 0),
- m01_z(b, "m_01-z", 0),
- m02_x(b, "m_02-x", 0),
- m02_y(b, "m_02-y", 0),
- m02_z(b, "m_02-z", 0),
- dyn_pose_res(b, "dynamic-pose-resolution", false),
- video_widget(b, "video-widget", true),
- t_MH_x(b, "model-centroid-x", 0),
- t_MH_y(b, "model-centroid-y", 0),
- t_MH_z(b, "model-centroid-z", 0),
- reset_time(b, "reset-time", 2000),
- bEnableYaw(b, "enable-yaw", true),
- bEnablePitch(b, "enable-pitch", true),
- bEnableRoll(b, "enable-roll", true),
- bEnableX(b, "enable-x", true),
- bEnableY(b, "enable-y", true),
- bEnableZ(b, "enable-z", true),
- clip_ty(b, "clip-ty", 0),
- clip_tz(b, "clip-tz", 0),
- clip_by(b, "clip-by", 0),
- clip_bz(b, "clip-bz", 0),
- active_model_panel(b, "active-model-panel", 0),
- cap_x(b, "cap-x", 0),
- cap_y(b, "cap-y", 0),
- cap_z(b, "cap-z", 0)
- {}
-};
-
-#endif //FTNOIR_TRACKER_PT_SETTINGS_H
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef FTNOIR_TRACKER_PT_SETTINGS_H +#define FTNOIR_TRACKER_PT_SETTINGS_H + +#include <opencv2/core/core.hpp> +#include "point_tracker.h" + +#include "facetracknoir/options.h" +using namespace options; + +struct settings +{ + pbundle b; + value<int> cam_index, + cam_res_x, + cam_res_y, + cam_fps, + cam_roll, + cam_pitch, + cam_yaw, + threshold, + threshold_secondary, + min_point_size, + max_point_size; + + value<int> m01_x, m01_y, m01_z; + value<int> m02_x, m02_y, m02_z; + + value<int> t_MH_x, t_MH_y, t_MH_z; + + value<int> clip_ty, clip_tz, clip_by, clip_bz; + value<int> active_model_panel, cap_x, cap_y, cap_z; + + // XXX todo red channel only, good for crapola CCD sensors -sh 20140922 + + settings() : + b(bundle("tracker-pt")), + cam_index(b, "camera-index", 0), + cam_res_x(b, "camera-res-width", 640), + cam_res_y(b, "camera-res-height", 480), + cam_fps(b, "camera-fps", 30), + cam_roll(b, "camera-roll", 1), + cam_pitch(b, "camera-pitch", 0), + cam_yaw(b, "camera-yaw", 0), + threshold(b, "threshold-primary", 128), + threshold_secondary(b, "threshold-secondary", 128), + min_point_size(b, "min-point-size", 10), + max_point_size(b, "max-point-size", 50), + m01_x(b, "m_01-x", 0), + m01_y(b, "m_01-y", 0), + m01_z(b, "m_01-z", 0), + m02_x(b, "m_02-x", 0), + m02_y(b, "m_02-y", 0), + m02_z(b, "m_02-z", 0), + t_MH_x(b, "model-centroid-x", 0), + t_MH_y(b, "model-centroid-y", 0), + t_MH_z(b, "model-centroid-z", 0), + clip_ty(b, "clip-ty", 0), + clip_tz(b, "clip-tz", 0), + clip_by(b, "clip-by", 0), + clip_bz(b, "clip-bz", 0), + active_model_panel(b, "active-model-panel", 0), + cap_x(b, "cap-x", 0), + cap_y(b, "cap-y", 0), + cap_z(b, "cap-z", 0) + {} +}; + +#endif //FTNOIR_TRACKER_PT_SETTINGS_H diff --git a/FTNoIR_Tracker_PT/point_extractor.cpp b/ftnoir_tracker_pt/point_extractor.cpp index d9ff0a5b..819bf5e8 100644 --- a/FTNoIR_Tracker_PT/point_extractor.cpp +++ b/ftnoir_tracker_pt/point_extractor.cpp @@ -1,163 +1,161 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "point_extractor.h"
-#include <QDebug>
-
-
-using namespace cv;
-using namespace std;
-
-
-PointExtractor::PointExtractor(){
- //if (!AllocConsole()){}
- //else SetConsoleTitle("debug");
- //freopen("CON", "w", stdout);
- //freopen("CON", "w", stderr);
-}
-// ----------------------------------------------------------------------------
-const vector<Vec2f>& PointExtractor::extract_points(Mat frame, float dt, bool draw_output)
-{
- const int W = frame.cols;
- const int H = frame.rows;
-
- if (frame_last.cols != W || frame_last.rows != H)
- {
- frame_last = cv::Mat();
- }
-
- // clear old points
- points.clear();
-
- // convert to grayscale
- Mat frame_gray;
- cvtColor(frame, frame_gray, CV_RGB2GRAY);
-
- int secondary = threshold_secondary_val;
-
- // mask for everything that passes the threshold (or: the upper threshold of the hysteresis)
- Mat frame_bin;
- // only used if draw_output
- Mat frame_bin_copy;
- // mask for everything that passes
- Mat frame_bin_low;
- // mask for lower-threshold && combined result of last, needs to remain in scope until drawing, but is only used if secondary != 0
- Mat frame_last_and_low;
-
- if(secondary==0){
- threshold(frame_gray, frame_bin, threshold_val, 255, THRESH_BINARY);
- }else{
- // we recombine a number of buffers, this might be slower than a single loop of per-pixel logic
- // but it might as well be faster if openCV makes good use of SIMD
- float t = threshold_val;
- //float hyst = float(threshold_secondary_val)/512.;
- //threshold(frame_gray, frame_bin, (t + ((255.-t)*hyst)), 255, THRESH_BINARY);
- float hyst = float(threshold_secondary_val)/256.;
- threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY);
- threshold(frame_gray, frame_bin_low,std::max(float(1), t - (t*hyst)), 255, THRESH_BINARY);
-
- if(draw_output) frame_bin.copyTo(frame_bin_copy);
- if(frame_last.empty()){
- frame_bin.copyTo(frame_last);
- }else{
- // keep pixels from last if they are above lower threshold
- bitwise_and(frame_last, frame_bin_low, frame_last_and_low);
- // union of pixels >= higher threshold and pixels >= lower threshold
- bitwise_or(frame_bin, frame_last_and_low, frame_last);
- frame_last.copyTo(frame_bin);
- }
- }
- unsigned int region_size_min = 3.14*min_size*min_size/4.0;
- unsigned int region_size_max = 3.14*max_size*max_size/4.0;
-
- int blob_index = 1;
- for (int y=0; y<H; y++)
- {
- if (blob_index >= 255) break;
- for (int x=0; x<W; x++)
- {
- if (blob_index >= 255) break;
-
- // find connected components with floodfill
- if (frame_bin.at<unsigned char>(y,x) != 255) continue;
- Rect rect;
-
- floodFill(frame_bin, Point(x,y), Scalar(blob_index), &rect, Scalar(0), Scalar(0), FLOODFILL_FIXED_RANGE);
- blob_index++;
-
- // calculate the size of the connected component
- unsigned int region_size = 0;
- for (int i=rect.y; i < (rect.y+rect.height); i++)
- {
- for (int j=rect.x; j < (rect.x+rect.width); j++)
- {
- if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
- region_size++;
- }
- }
-
- if (region_size < region_size_min || region_size > region_size_max) continue;
-
- // calculate the center of mass:
- // mx = (sum_ij j*f(frame_grey_ij)) / (sum_ij f(frame_grey_ij))
- // my = ...
- // f maps from [threshold,256] -> [0, 1], lower values are mapped to 0
- float m = 0;
- float mx = 0;
- float my = 0;
- for (int i=rect.y; i < (rect.y+rect.height); i++)
- {
- for (int j=rect.x; j < (rect.x+rect.width); j++)
- {
- if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue;
- float val;
-
- if(secondary==0){
- val = frame_gray.at<unsigned char>(i,j);
- val = float(val - threshold_val)/(256 - threshold_val);
- val = val*val; // makes it more stable (less emphasis on low values, more on the peak)
- }else{
- //hysteresis point detection gets stability from ignoring pixel noise so we decidedly leave the actual pixel values out of the picture
- val = frame_last.at<unsigned char>(i,j) / 256.;
- }
-
- m += val;
- mx += j * val;
- my += i * val;
- }
- }
-
- // convert to centered camera coordinate system with y axis upwards
- Vec2f c;
- c[0] = (mx/m - W/2)/W;
- c[1] = -(my/m - H/2)/W;
- //qDebug()<<blob_index<<" => "<<c[0]<<" "<<c[1];
- points.push_back(c);
- }
- }
-
- // draw output image
- if (draw_output) {
- vector<Mat> channels;
- if(secondary==0){
- frame_bin.setTo(170, frame_bin);
- channels.push_back(frame_gray + frame_bin);
- channels.push_back(frame_gray - frame_bin);
- channels.push_back(frame_gray - frame_bin);
- }else{
- frame_bin_copy.setTo(120, frame_bin_copy);
- frame_bin_low.setTo(90, frame_bin_low);
- channels.push_back(frame_gray + frame_bin_copy);
- channels.push_back(frame_gray + frame_last_and_low);
- channels.push_back(frame_gray + frame_bin_low);
- //channels.push_back(frame_gray + frame_bin);
- }
- merge(channels, frame);
- }
-
- return points;
-}
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "point_extractor.h" +#include <QDebug> + + +using namespace cv; +using namespace std; + + +PointExtractor::PointExtractor(){ + //if (!AllocConsole()){} + //else SetConsoleTitle("debug"); + //freopen("CON", "w", stdout); + //freopen("CON", "w", stderr); +} +// ---------------------------------------------------------------------------- +const vector<Vec2f>& PointExtractor::extract_points(Mat& frame) +{ + const int W = frame.cols; + const int H = frame.rows; + + if (frame_last.cols != W || frame_last.rows != H) + { + frame_last = cv::Mat(); + } + + // clear old points + points.clear(); + + // convert to grayscale + Mat frame_gray; + cvtColor(frame, frame_gray, CV_RGB2GRAY); + + int secondary = threshold_secondary_val; + + // mask for everything that passes the threshold (or: the upper threshold of the hysteresis) + Mat frame_bin; + // only used if draw_output + Mat frame_bin_copy; + // mask for everything that passes + Mat frame_bin_low; + // mask for lower-threshold && combined result of last, needs to remain in scope until drawing, but is only used if secondary != 0 + Mat frame_last_and_low; + + if(secondary==0){ + threshold(frame_gray, frame_bin, threshold_val, 255, THRESH_BINARY); + }else{ + // we recombine a number of buffers, this might be slower than a single loop of per-pixel logic + // but it might as well be faster if openCV makes good use of SIMD + float t = threshold_val; + //float hyst = float(threshold_secondary_val)/512.; + //threshold(frame_gray, frame_bin, (t + ((255.-t)*hyst)), 255, THRESH_BINARY); + float hyst = float(threshold_secondary_val)/256.; + threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY); + threshold(frame_gray, frame_bin_low,std::max(float(1), t - (t*hyst)), 255, THRESH_BINARY); + + frame_bin.copyTo(frame_bin_copy); + if(frame_last.empty()){ + frame_bin.copyTo(frame_last); + }else{ + // keep pixels from last if they are above lower threshold + bitwise_and(frame_last, frame_bin_low, frame_last_and_low); + // union of pixels >= higher threshold and pixels >= lower threshold + bitwise_or(frame_bin, frame_last_and_low, frame_last); + frame_last.copyTo(frame_bin); + } + } + unsigned int region_size_min = 3.14*min_size*min_size/4.0; + unsigned int region_size_max = 3.14*max_size*max_size/4.0; + + int blob_index = 1; + for (int y=0; y<H; y++) + { + if (blob_index >= 255) break; + for (int x=0; x<W; x++) + { + if (blob_index >= 255) break; + + // find connected components with floodfill + if (frame_bin.at<unsigned char>(y,x) != 255) continue; + Rect rect; + + floodFill(frame_bin, Point(x,y), Scalar(blob_index), &rect, Scalar(0), Scalar(0), FLOODFILL_FIXED_RANGE); + blob_index++; + + // calculate the size of the connected component + unsigned int region_size = 0; + for (int i=rect.y; i < (rect.y+rect.height); i++) + { + for (int j=rect.x; j < (rect.x+rect.width); j++) + { + if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue; + region_size++; + } + } + + if (region_size < region_size_min || region_size > region_size_max) continue; + + // calculate the center of mass: + // mx = (sum_ij j*f(frame_grey_ij)) / (sum_ij f(frame_grey_ij)) + // my = ... + // f maps from [threshold,256] -> [0, 1], lower values are mapped to 0 + float m = 0; + float mx = 0; + float my = 0; + for (int i=rect.y; i < (rect.y+rect.height); i++) + { + for (int j=rect.x; j < (rect.x+rect.width); j++) + { + if (frame_bin.at<unsigned char>(i,j) != blob_index-1) continue; + float val; + + if(secondary==0){ + val = frame_gray.at<unsigned char>(i,j); + val = float(val - threshold_val)/(256 - threshold_val); + val = val*val; // makes it more stable (less emphasis on low values, more on the peak) + }else{ + //hysteresis point detection gets stability from ignoring pixel noise so we decidedly leave the actual pixel values out of the picture + val = frame_last.at<unsigned char>(i,j) / 256.; + } + + m += val; + mx += j * val; + my += i * val; + } + } + + // convert to centered camera coordinate system with y axis upwards + Vec2f c; + c[0] = (mx/m - W/2)/W; + c[1] = -(my/m - H/2)/W; + //qDebug()<<blob_index<<" => "<<c[0]<<" "<<c[1]; + points.push_back(c); + } + } + + // draw output image + vector<Mat> channels; + if(secondary==0){ + frame_bin.setTo(170, frame_bin); + channels.push_back(frame_gray + frame_bin); + channels.push_back(frame_gray - frame_bin); + channels.push_back(frame_gray - frame_bin); + }else{ + frame_bin_copy.setTo(120, frame_bin_copy); + frame_bin_low.setTo(90, frame_bin_low); + channels.push_back(frame_gray + frame_bin_copy); + channels.push_back(frame_gray + frame_last_and_low); + channels.push_back(frame_gray + frame_bin_low); + //channels.push_back(frame_gray + frame_bin); + } + merge(channels, frame); + + return points; +} diff --git a/ftnoir_tracker_pt/point_extractor.h b/ftnoir_tracker_pt/point_extractor.h new file mode 100644 index 00000000..5252b68d --- /dev/null +++ b/ftnoir_tracker_pt/point_extractor.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef POINTEXTRACTOR_H +#define POINTEXTRACTOR_H + +#include <opencv2/core/core.hpp> +#include <opencv2/imgproc/imgproc.hpp> + +// ---------------------------------------------------------------------------- +// Extracts points from an opencv image +class PointExtractor +{ +public: + // extracts points from frame and draws some processing info into frame, if draw_output is set + // dt: time since last call in seconds + // WARNING: returned reference is valid as long as object + const std::vector<cv::Vec2f>& extract_points(cv::Mat &frame); + const std::vector<cv::Vec2f>& get_points() { return points; } + PointExtractor(); + + int threshold_val; + int threshold_secondary_val; + int min_size, max_size; + +private: + std::vector<cv::Vec2f> points; + cv::Mat frame_last; +}; + +#endif //POINTEXTRACTOR_H diff --git a/ftnoir_tracker_pt/point_tracker.cpp b/ftnoir_tracker_pt/point_tracker.cpp new file mode 100644 index 00000000..8a633c5d --- /dev/null +++ b/ftnoir_tracker_pt/point_tracker.cpp @@ -0,0 +1,289 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "point_tracker.h" + +#include <vector> +#include <algorithm> +#include <cmath> + +#include <QDebug> + +using namespace cv; +using namespace std; + +const float PI = 3.14159265358979323846f; + +// ---------------------------------------------------------------------------- +static void get_row(const Matx33f& m, int i, Vec3f& v) +{ + v[0] = m(i,0); + v[1] = m(i,1); + v[2] = m(i,2); +} + +static void set_row(Matx33f& m, int i, const Vec3f& v) +{ + m(i,0) = v[0]; + m(i,1) = v[1]; + m(i,2) = v[2]; +} + +PointModel::PointModel() : + M01 { 0, 0, 0 }, + M02 { 0, 0, 0 } +{ +} + +PointModel::PointModel(Vec3f M01, Vec3f M02) + : M01(M01), M02(M02) +{ + // calculate u + u = M01.cross(M02); + u /= norm(u); + + // calculate projection matrix on M01,M02 plane + float s11 = M01.dot(M01); + float s12 = M01.dot(M02); + float s22 = M02.dot(M02); + P = 1.0/(s11*s22-s12*s12) * Matx22f(s22, -s12, + -s12, s11); + // calculate d and d_order for simple freetrack-like point correspondence + vector<Vec2f> points; + points.push_back(Vec2f(0,0)); + points.push_back(Vec2f(M01[0], M01[1])); + points.push_back(Vec2f(M02[0], M02[1])); + // fit line to orthographically projected points + // ERROR: yields wrong results with colinear points?! + /* + Vec4f line; + fitLine(points, line, CV_DIST_L2, 0, 0.01, 0.01); + d[0] = line[0]; d[1] = line[1]; + */ + // TODO: fix this + d = Vec2f(M01[0]-M02[0], M01[1]-M02[1]); + + // sort model points + get_d_order(points, d_order); +} + +#ifdef OPENTRACK_API +static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b) +{ + return a.first < b.first; +} +#endif + +void PointModel::get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const +{ + // get sort indices with respect to d scalar product + vector< pair<float,int> > d_vals; + for (unsigned i = 0; i<points.size(); ++i) + d_vals.push_back(pair<float, int>(d.dot(points[i]), i)); + + std::sort(d_vals.begin(), + d_vals.end(), +#ifdef OPENTRACK_API + d_vals_sort +#else + comp +#endif + ); + + for (unsigned i = 0; i<points.size(); ++i) + d_order[i] = d_vals[i].second; +} + + +// ---------------------------------------------------------------------------- +PointTracker::PointTracker() +{ + X_CM.t[2] = 1000; // default position: 1 m away from cam; +} + +void PointTracker::reset() +{ + // enter init phase + X_CM = FrameTrafo(); +} + +void PointTracker::track(const vector<Vec2f>& projected_points, const PointModel& model) +{ + const PointOrder& order = find_correspondences(projected_points, model); + int iters = POSIT(model, order); + qDebug()<<"POSIT iterations:"<<iters; +} + +PointTracker::PointOrder PointTracker::find_correspondences(const std::vector<cv::Vec2f>& projected_points, const PointModel& model) +{ + // ... otherwise we look at the distance to the projection of the expected model points + // project model points under current pose + Vec2f p_exp[3]; + p_exp[0] = project(Vec3f(0,0,0)); + p_exp[1] = project(model.get_M01()); + p_exp[2] = project(model.get_M02()); + + // set correspondences by minimum distance to projected model point + bool point_taken[PointModel::N_POINTS]; + for (int i=0; i<PointModel::N_POINTS; ++i) + point_taken[i] = false; + + PointOrder p; + for (int i=0; i<PointModel::N_POINTS; ++i) + p.points[i] = Vec2f(0, 0); + + for (int i=0; i<PointModel::N_POINTS; ++i) + { + float min_sdist = 1e4; + int min_idx = 0; + // find closest point to projected model point i + for (int j=0; j<PointModel::N_POINTS; ++j) + { + Vec2f d = p_exp[i]-projected_points[j]; + float sdist = d.dot(d); + if (sdist < min_sdist) + { + min_idx = j; + min_sdist = sdist; + } + } + // if one point is closest to more than one model point, abort + if (point_taken[min_idx]) return p; + point_taken[min_idx] = true; + p.points[i] = projected_points[min_idx]; + } + return p; +} + + + +int PointTracker::POSIT(const PointModel& model, const PointOrder& order_) +{ + // POSIT algorithm for coplanar points as presented in + // [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"] + // we use the same notation as in the paper here + + // The expected rotation used for resolving the ambiguity in POSIT: + // In every iteration step the rotation closer to R_expected is taken + Matx33f R_expected; + R_expected = X_CM.R; // later we want to be close to the last (predicted) rotation + + // initial pose = last (predicted) pose + Vec3f k; + get_row(R_expected, 2, k); + float Z0 = std::abs(X_CM.t[2]) < 1e-3 ? 1e3 : X_CM.t[2]; + + float old_epsilon_1 = 0; + float old_epsilon_2 = 0; + float epsilon_1 = 1; + float epsilon_2 = 1; + + Vec3f I0, J0; + Vec2f I0_coeff, J0_coeff; + + Vec3f I_1, J_1, I_2, J_2; + Matx33f R_1, R_2; + Matx33f* R_current; + + const int MAX_ITER = 100; + const float EPS_THRESHOLD = 1e-4; + + const cv::Vec2f* order = order_.points; + + int i=1; + for (; i<MAX_ITER; ++i) + { + epsilon_1 = k.dot(model.M01)/Z0; + epsilon_2 = k.dot(model.M02)/Z0; + + // vector of scalar products <I0, M0i> and <J0, M0i> + Vec2f I0_M0i(order[1][0]*(1.0 + epsilon_1) - order[0][0], + order[2][0]*(1.0 + epsilon_2) - order[0][0]); + Vec2f J0_M0i(order[1][1]*(1.0 + epsilon_1) - order[0][1], + order[2][1]*(1.0 + epsilon_2) - order[0][1]); + + // construct projection of I, J onto M0i plane: I0 and J0 + I0_coeff = model.P * I0_M0i; + J0_coeff = model.P * J0_M0i; + I0 = I0_coeff[0]*model.M01 + I0_coeff[1]*model.M02; + J0 = J0_coeff[0]*model.M01 + J0_coeff[1]*model.M02; + + // calculate u component of I, J + float II0 = I0.dot(I0); + float IJ0 = I0.dot(J0); + float JJ0 = J0.dot(J0); + float rho, theta; + if (JJ0 == II0) { + rho = sqrt(abs(2*IJ0)); + theta = -PI/4; + if (IJ0<0) theta *= -1; + } + else { + rho = sqrt(sqrt( (JJ0-II0)*(JJ0-II0) + 4*IJ0*IJ0 )); + theta = atan( -2*IJ0 / (JJ0-II0) ); + if (JJ0 - II0 < 0) theta += PI; + theta /= 2; + } + + // construct the two solutions + I_1 = I0 + rho*cos(theta)*model.u; + I_2 = I0 - rho*cos(theta)*model.u; + + J_1 = J0 + rho*sin(theta)*model.u; + J_2 = J0 - rho*sin(theta)*model.u; + + float norm_const = 1.0/norm(I_1); // all have the same norm + + // create rotation matrices + I_1 *= norm_const; J_1 *= norm_const; + I_2 *= norm_const; J_2 *= norm_const; + + set_row(R_1, 0, I_1); + set_row(R_1, 1, J_1); + set_row(R_1, 2, I_1.cross(J_1)); + + set_row(R_2, 0, I_2); + set_row(R_2, 1, J_2); + set_row(R_2, 2, I_2.cross(J_2)); + + // the single translation solution + Z0 = norm_const * focal_length; + + // pick the rotation solution closer to the expected one + // in simple metric d(A,B) = || I - A * B^T || + float R_1_deviation = norm(Matx33f::eye() - R_expected * R_1.t()); + float R_2_deviation = norm(Matx33f::eye() - R_expected * R_2.t()); + + if (R_1_deviation < R_2_deviation) + R_current = &R_1; + else + R_current = &R_2; + + get_row(*R_current, 2, k); + + // check for convergence condition + if (abs(epsilon_1 - old_epsilon_1) + abs(epsilon_2 - old_epsilon_2) < EPS_THRESHOLD) + break; + old_epsilon_1 = epsilon_1; + old_epsilon_2 = epsilon_2; + } + + // apply results + X_CM.R = *R_current; + X_CM.t[0] = order[0][0] * Z0/focal_length; + X_CM.t[1] = order[0][1] * Z0/focal_length; + X_CM.t[2] = Z0; + + return i; + + //Rodrigues(X_CM.R, r); + //qDebug()<<"iter: "<<i; + //qDebug()<<"t: "<<X_CM.t[0]<<' '<<X_CM.t[1]<<' '<<X_CM.t[2]; + //Vec3f r; + // + //qDebug()<<"r: "<<r[0]<<' '<<r[1]<<' '<<r[2]<<'\n'; +} diff --git a/ftnoir_tracker_pt/point_tracker.h b/ftnoir_tracker_pt/point_tracker.h new file mode 100644 index 00000000..d65494a4 --- /dev/null +++ b/ftnoir_tracker_pt/point_tracker.h @@ -0,0 +1,114 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef POINTTRACKER_H +#define POINTTRACKER_H + +#include <opencv2/core/core.hpp> +#ifndef OPENTRACK_API +# include <boost/shared_ptr.hpp> +#else +# include <memory> +#endif +#include <vector> + +// ---------------------------------------------------------------------------- +// Affine frame trafo +class FrameTrafo +{ +public: + FrameTrafo() : R(cv::Matx33f::eye()), t(0,0,0) {} + FrameTrafo(const cv::Matx33f& R, const cv::Vec3f& t) : R(R),t(t) {} + + cv::Matx33f R; + cv::Vec3f t; +}; + +inline FrameTrafo operator*(const FrameTrafo& X, const FrameTrafo& Y) +{ + return FrameTrafo(X.R*Y.R, X.R*Y.t + X.t); +} + +inline FrameTrafo operator*(const cv::Matx33f& X, const FrameTrafo& Y) +{ + return FrameTrafo(X*Y.R, X*Y.t); +} + +inline FrameTrafo operator*(const FrameTrafo& X, const cv::Matx33f& Y) +{ + return FrameTrafo(X.R*Y, X.t); +} + +inline cv::Vec3f operator*(const FrameTrafo& X, const cv::Vec3f& v) +{ + return X.R*v + X.t; +} + + +// ---------------------------------------------------------------------------- +// Describes a 3-point model +// nomenclature as in +// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"] +class PointModel +{ + friend class PointTracker; +public: + static constexpr int N_POINTS = 3; + + PointModel(cv::Vec3f M01, cv::Vec3f M02); + PointModel(); + + inline const cv::Vec3f& get_M01() const { return M01; } + inline const cv::Vec3f& get_M02() const { return M02; } + +private: + cv::Vec3f M01; // M01 in model frame + cv::Vec3f M02; // M02 in model frame + + cv::Vec3f u; // unit vector perpendicular to M01,M02-plane + + cv::Matx22f P; + + cv::Vec2f d; // determinant vector for point correspondence + int d_order[3]; // sorting of projected model points with respect to d scalar product + + void get_d_order(const std::vector<cv::Vec2f>& points, int d_order[]) const; +}; + +// ---------------------------------------------------------------------------- +// Tracks a 3-point model +// implementing the POSIT algorithm for coplanar points as presented in +// [Denis Oberkampf, Daniel F. DeMenthon, Larry S. Davis: "Iterative Pose Estimation Using Coplanar Feature Points"] +class PointTracker +{ +public: + PointTracker(); + // track the pose using the set of normalized point coordinates (x pos in range -0.5:0.5) + // f : (focal length)/(sensor width) + // dt : time since last call + void track(const std::vector<cv::Vec2f>& projected_points, const PointModel& model); + FrameTrafo get_pose() const { return X_CM; } + void reset(); + +private: + // the points in model order + typedef struct { cv::Vec2f points[PointModel::N_POINTS]; } PointOrder; + static constexpr float focal_length = 1.0f; + + inline cv::Vec2f project(const cv::Vec3f& v_M) + { + cv::Vec3f v_C = X_CM * v_M; + return cv::Vec2f(focal_length*v_C[0]/v_C[2], focal_length*v_C[1]/v_C[2]); + } + + PointOrder find_correspondences(const std::vector<cv::Vec2f>& projected_points, const PointModel &model); + int POSIT(const PointModel& point_model, const PointOrder& order); // The POSIT algorithm, returns the number of iterations + + FrameTrafo X_CM; // trafo from model to camera +}; + +#endif //POINTTRACKER_H diff --git a/FTNoIR_Tracker_PT/pt_video_widget.cpp b/ftnoir_tracker_pt/pt_video_widget.cpp index 02817cbf..aefb8199 100644 --- a/FTNoIR_Tracker_PT/pt_video_widget.cpp +++ b/ftnoir_tracker_pt/pt_video_widget.cpp @@ -1,64 +1,46 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 20130312, WVR: Add 7 lines to resizeGL after resize_frame. This should lower CPU-load.
- */
-
-#include "pt_video_widget.h"
-
-#include <QDebug>
-#include <QHBoxLayout>
-
-using namespace cv;
-using namespace std;
-
-void PTVideoWidget::update_image(const cv::Mat& frame)
-{
- QMutexLocker foo(&mtx);
- _frame = frame.clone();
- freshp = true;
-}
-
-// ----------------------------------------------------------------------------
-VideoWidgetDialog::VideoWidgetDialog(QWidget *parent, FrameProvider* provider)
- : QDialog(parent),
- video_widget(NULL)
-{
- const int VIDEO_FRAME_WIDTH = 640;
- const int VIDEO_FRAME_HEIGHT = 480;
-
- video_widget = new PTVideoWidget(this, provider);
-
- QHBoxLayout* layout = new QHBoxLayout();
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(video_widget);
- if (this->layout()) delete this->layout();
- setLayout(layout);
- resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT);
-}
-
-void PTVideoWidget::update_and_repaint()
-{
- QMutexLocker foo(&mtx);
- if (_frame.empty() || !freshp)
- return;
- freshp = false;
- QImage qframe = QImage(_frame.cols, _frame.rows, QImage::Format_RGB888);
- uchar* data = qframe.bits();
- const int pitch = qframe.bytesPerLine();
- for (int y = 0; y < _frame.rows; y++)
- for (int x = 0; x < _frame.cols; x++)
- {
- const auto& elt = _frame.at<Vec3b>(y, x);
- const cv::Scalar elt2 = static_cast<cv::Scalar>(elt);
- data[y * pitch + x * 3 + 0] = elt2.val[2];
- data[y * pitch + x * 3 + 1] = elt2.val[1];
- data[y * pitch + x * 3 + 2] = elt2.val[0];
- }
- qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation);
- texture = qframe;
- update();
-}
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * 20130312, WVR: Add 7 lines to resizeGL after resize_frame. This should lower CPU-load. + */ + +#include "pt_video_widget.h" + +#include <QDebug> +#include <QHBoxLayout> + +using namespace cv; +using namespace std; + +void PTVideoWidget::update_image(const cv::Mat& frame) +{ + QMutexLocker foo(&mtx); + _frame = frame.clone(); + freshp = true; +} + +void PTVideoWidget::update_and_repaint() +{ + QMutexLocker foo(&mtx); + if (_frame.empty() || !freshp) + return; + freshp = false; + QImage qframe = QImage(_frame.cols, _frame.rows, QImage::Format_RGB888); + uchar* data = qframe.bits(); + const int pitch = qframe.bytesPerLine(); + for (int y = 0; y < _frame.rows; y++) + for (int x = 0; x < _frame.cols; x++) + { + const auto& elt = _frame.at<Vec3b>(y, x); + const cv::Scalar elt2 = static_cast<cv::Scalar>(elt); + data[y * pitch + x * 3 + 0] = elt2.val[2]; + data[y * pitch + x * 3 + 1] = elt2.val[1]; + data[y * pitch + x * 3 + 2] = elt2.val[0]; + } + qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); + texture = qframe; + update(); +} diff --git a/FTNoIR_Tracker_PT/pt_video_widget.h b/ftnoir_tracker_pt/pt_video_widget.h index 25d593c3..f2b41d63 100644 --- a/FTNoIR_Tracker_PT/pt_video_widget.h +++ b/ftnoir_tracker_pt/pt_video_widget.h @@ -1,71 +1,56 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#pragma once
-
-#include "frame_observer.h"
-#include <QObject>
-#include <QTime>
-#include <QDialog>
-#include <opencv2/opencv.hpp>
-#ifndef OPENTRACK_API
-# include <QGLWidget>
-# include <boost/shared_ptr.hpp>
-#else
-# include "FTNoIR_Tracker_PT/boost-compat.h"
-# if defined(_WIN32)
-# include <dshow.h>
-# endif
-#endif
-#include <QPainter>
-#include <QPaintEvent>
-#include <QTimer>
-
-class PTVideoWidget : public QWidget, public FrameObserver
-{
- Q_OBJECT
-
-public:
- PTVideoWidget(QWidget *parent, FrameProvider* provider) :
- QWidget(parent),
- /* to avoid linker errors */ FrameObserver(provider),
- freshp(false)
- {
- connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()));
- timer.start(40);
- }
- void update_image(const cv::Mat &frame);
- void update_frame_and_points() {}
-protected slots:
- void paintEvent( QPaintEvent* e ) {
- QMutexLocker foo(&mtx);
- QPainter painter(this);
- painter.drawImage(e->rect(), texture);
- }
- void update_and_repaint();
-private:
- QMutex mtx;
- QImage texture;
- QTimer timer;
- cv::Mat _frame;
- bool freshp;
-};
-
-// ----------------------------------------------------------------------------
-// A VideoWidget embedded in a dialog frame
-class VideoWidgetDialog : public QDialog
-{
- Q_OBJECT
-public:
- VideoWidgetDialog(QWidget *parent, FrameProvider* provider);
- virtual ~VideoWidgetDialog() {}
-
- PTVideoWidget* get_video_widget() { return video_widget; }
-
-private:
- PTVideoWidget* video_widget;
-};
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#include <QObject> +#include <QTime> +#include <QDialog> +#include <opencv2/core/core.hpp> +#ifndef OPENTRACK_API +# include <QGLWidget> +# include <boost/shared_ptr.hpp> +#else +# include <memory> +# if defined(_WIN32) +# include <dshow.h> +# endif +#endif +#include <QPainter> +#include <QPaintEvent> +#include <QTimer> +#include <QMutex> +#include <QMutexLocker> + +class PTVideoWidget : public QWidget +{ + Q_OBJECT + +public: + PTVideoWidget(QWidget *parent) : + QWidget(parent), + freshp(false) + { + connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint())); + timer.start(40); + } + void update_image(const cv::Mat &frame); + void update_frame_and_points() {} +protected slots: + void paintEvent( QPaintEvent* e ) { + QMutexLocker foo(&mtx); + QPainter painter(this); + painter.drawImage(e->rect(), texture); + } + void update_and_repaint(); +private: + QMutex mtx; + QImage texture; + QTimer timer; + cv::Mat _frame; + volatile bool freshp; +}; diff --git a/FTNoIR_Tracker_PT/trans_calib.cpp b/ftnoir_tracker_pt/trans_calib.cpp index 9b75a1b6..729a0b7f 100644 --- a/FTNoIR_Tracker_PT/trans_calib.cpp +++ b/ftnoir_tracker_pt/trans_calib.cpp @@ -1,44 +1,44 @@ -/* Copyright (c) 2012 Patrick Ruoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-
-#include "trans_calib.h"
-
-using namespace cv;
-
-//-----------------------------------------------------------------------------
-TranslationCalibrator::TranslationCalibrator()
-{
- reset();
-}
-
-void TranslationCalibrator::reset()
-{
- P = Matx66f::zeros();
- y = Vec6f(0,0,0, 0,0,0);
-}
-
-void TranslationCalibrator::update(const Matx33f& R_CM_k, const Vec3f& t_CM_k)
-{
- Matx<float, 6,3> H_k_T = Matx<float, 6,3>::zeros();
- for (int i=0; i<3; ++i) {
- for (int j=0; j<3; ++j) {
- H_k_T(i,j) = R_CM_k(j,i);
- }
- }
- for (int i=0; i<3; ++i)
- {
- H_k_T(3+i,i) = 1.0;
- }
- P += H_k_T * H_k_T.t();
- y += H_k_T * t_CM_k;
-}
-
-Vec3f TranslationCalibrator::get_estimate()
-{
- Vec6f x = P.inv() * y;
- return Vec3f(-x[0], -x[1], -x[2]);
+/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "trans_calib.h" + +using namespace cv; + +//----------------------------------------------------------------------------- +TranslationCalibrator::TranslationCalibrator() +{ + reset(); +} + +void TranslationCalibrator::reset() +{ + P = Matx66f::zeros(); + y = Vec6f(0,0,0, 0,0,0); +} + +void TranslationCalibrator::update(const Matx33f& R_CM_k, const Vec3f& t_CM_k) +{ + Matx<float, 6,3> H_k_T = Matx<float, 6,3>::zeros(); + for (int i=0; i<3; ++i) { + for (int j=0; j<3; ++j) { + H_k_T(i,j) = R_CM_k(j,i); + } + } + for (int i=0; i<3; ++i) + { + H_k_T(3+i,i) = 1.0; + } + P += H_k_T * H_k_T.t(); + y += H_k_T * t_CM_k; +} + +Vec3f TranslationCalibrator::get_estimate() +{ + Vec6f x = P.inv() * y; + return Vec3f(-x[0], -x[1], -x[2]); }
\ No newline at end of file diff --git a/ftnoir_tracker_pt/trans_calib.h b/ftnoir_tracker_pt/trans_calib.h new file mode 100644 index 00000000..c2c02b38 --- /dev/null +++ b/ftnoir_tracker_pt/trans_calib.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef TRANSCALIB_H +#define TRANSCALIB_H + +#include <opencv2/core/core.hpp> + +//----------------------------------------------------------------------------- +// Calibrates the translation from head to model = t_MH +// by recursive least squares / +// kalman filter in information form with identity noise covariance +// measurement equation when head position = t_CH is fixed: +// (R_CM_k , Id)*(-t_MH, t_CH) = t_CM_k + +class TranslationCalibrator +{ +public: + TranslationCalibrator(); + + // reset the calibration process + void reset(); + + // update the current estimate + void update(const cv::Matx33f& R_CM_k, const cv::Vec3f& t_CM_k); + + // get the current estimate for t_MH + cv::Vec3f get_estimate(); + +private: + cv::Matx66f P; // normalized precision matrix = inverse covariance + cv::Vec6f y; // P*(-t_MH, t_CH) +}; + +#endif //TRANSCALIB_H diff --git a/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui b/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui index a9168239..20c8f00b 100644 --- a/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui +++ b/ftnoir_tracker_rift/ftnoir_rift_clientcontrols.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>209</width> - <height>288</height> + <width>218</width> + <height>200</height> </rect> </property> <property name="sizePolicy"> @@ -34,126 +34,6 @@ </property> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0"> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Enable Axis</string> - </property> - <property name="flat"> - <bool>false</bool> - </property> - <layout class="QFormLayout" name="formLayout_2"> - <item row="0" column="0"> - <widget class="QLabel" name="label_6"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Pitch:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="chkEnablePitch"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_9"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Yaw:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QCheckBox" name="chkEnableYaw"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_11"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Roll:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="chkEnableRoll"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>20</width> - <height>16777215</height> - </size> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="1" column="0"> <widget class="QGroupBox" name="groupBox"> <property name="title"> <string>Yaw spring</string> @@ -271,7 +151,7 @@ </layout> </widget> </item> - <item row="2" column="0"> + <item row="1" column="0"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp index b548db71..68a520ad 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp @@ -1,92 +1,74 @@ /* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */ #include "ftnoir_tracker_rift.h" -#include "facetracknoir/global-settings.h" -#include "OVR.h" +#include "facetracknoir/plugin-support.h" +#include "OVR_CAPI.h" +#include "Kernel/OVR_Math.h" #include <cstdio> using namespace OVR; -Rift_Tracker::Rift_Tracker() +Rift_Tracker::Rift_Tracker() : old_yaw(0), hmd(nullptr) { - should_quit = false; - pManager = NULL; - pSensor = NULL; - pSFusion = NULL; - old_yaw = 0; } Rift_Tracker::~Rift_Tracker() { - if (pSensor) - pSensor->Release(); - if (pSFusion) - delete pSFusion; - if (pManager) - pManager->Release(); - System::Destroy(); + ovrHmd_Destroy(hmd); + ovr_Shutdown(); } void Rift_Tracker::StartTracker(QFrame*) { - System::Init(Log::ConfigureDefaultLog(LogMask_All)); - pManager = DeviceManager::Create(); - if (pManager != NULL) + ovr_Initialize(); + hmd = ovrHmd_Create(0); + if (hmd) { - DeviceEnumerator<OVR::SensorDevice> enumerator = pManager->EnumerateDevices<OVR::SensorDevice>(); - if (enumerator.IsAvailable()) - { - pSensor = enumerator.CreateDevice(); - - if (pSensor){ - pSFusion = new OVR::SensorFusion(); - pSFusion->Reset(); - pSFusion->AttachToSensor(pSensor); - }else{ - QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to create Rift sensor",QMessageBox::Ok,QMessageBox::NoButton); - } - - }else{ - QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to enumerate Rift tracker",QMessageBox::Ok,QMessageBox::NoButton); - } - }else{ - QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to start Rift tracker",QMessageBox::Ok,QMessageBox::NoButton); - } + ovrHmd_ConfigureTracking(hmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, ovrTrackingCap_Orientation); + } + else + { + // XXX need change ITracker et al api to allow for failure reporting + // this qmessagebox doesn't give any relevant details either -sh 20141012 + QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to start Rift tracker",QMessageBox::Ok,QMessageBox::NoButton); + } } void Rift_Tracker::GetHeadPoseData(double *data) { - if (pSFusion != NULL && pSensor != NULL) { - Quatf hmdOrient = pSFusion->GetOrientation(); - double newHeadPose[6]; - - float yaw = 0.0f; - float pitch = 0.0f; - float roll = 0.0f; - hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch , &roll); - newHeadPose[Pitch] = pitch; - newHeadPose[Roll] = roll; - newHeadPose[Yaw] = yaw; - if (s.useYawSpring) - { - newHeadPose[Yaw] = old_yaw*s.persistence + (yaw-old_yaw); - if(newHeadPose[Yaw]>s.deadzone)newHeadPose[Yaw]-= s.constant_drift; - if(newHeadPose[Yaw]<-s.deadzone)newHeadPose[Yaw]+= s.constant_drift; - old_yaw=yaw; - } - if (s.bEnableYaw) { - data[Yaw] = newHeadPose[Yaw] * 57.295781f; - } - if (s.bEnablePitch) { - data[Pitch] = newHeadPose[Pitch] * 57.295781f; - } - if (s.bEnableRoll) { - data[Roll] = newHeadPose[Roll] * 57.295781f; + if (hmd) + { + ovrHSWDisplayState hsw; + if (ovrHmd_GetHSWDisplayState(hmd, &hsw), hsw.Displayed) + ovrHmd_DismissHSWDisplay(hmd); + ovrTrackingState ss = ovrHmd_GetTrackingState(hmd, 0); + if(ss.StatusFlags & ovrStatus_OrientationTracked) { + auto pose = ss.HeadPose.ThePose; + Quatf quat = pose.Orientation; + float yaw, pitch, roll; + quat.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll); + // XXX TODO move to core + if (s.useYawSpring) + { + yaw = old_yaw*s.persistence + (yaw-old_yaw); + if(yaw > s.deadzone) + yaw -= s.constant_drift; + if(yaw < -s.deadzone) + yaw += s.constant_drift; + old_yaw=yaw; + } + constexpr double d2r = 57.295781; + data[Yaw] = yaw * d2r; + data[Pitch] = pitch * -d2r; + data[Roll] = roll * d2r; + data[TX] = pose.Position.x * -1e2; + data[TY] = pose.Position.y * 1e2; + data[TZ] = pose.Position.z * 1e2; } } } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new Rift_Tracker; } diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift.h b/ftnoir_tracker_rift/ftnoir_tracker_rift.h index 7162b7ca..b862555c 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift.h +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift.h @@ -1,10 +1,9 @@ #pragma once -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_ftnoir_rift_clientcontrols.h" #include <QMessageBox> #include <QWaitCondition> #include <cmath> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-api.hpp" #include "OVR.h" #include <memory> #include "facetracknoir/options.h" @@ -12,13 +11,10 @@ using namespace options; struct settings { pbundle b; - value<bool> bEnableYaw, bEnablePitch, bEnableRoll, useYawSpring; + value<bool> useYawSpring; value<double> constant_drift, persistence, deadzone; settings() : b(bundle("Rift")), - bEnableYaw(b, "EnableYaw", true), - bEnablePitch(b, "EnablePitch", true), - bEnableRoll(b, "EnableRoll", true), useYawSpring(b, "yaw-spring", false), constant_drift(b, "constant-drift", 0.000005), persistence(b, "persistence", 0.99999), @@ -29,55 +25,46 @@ struct settings { class Rift_Tracker : public ITracker { public: - Rift_Tracker(); - virtual ~Rift_Tracker() virt_override; - - void StartTracker(QFrame *) virt_override; - void GetHeadPoseData(double *data) virt_override; - virtual int preferredHz() virt_override { return 250; } - volatile bool should_quit; -protected: - void run(); // qthread override run method - + Rift_Tracker(); + ~Rift_Tracker() override; + void StartTracker(QFrame *) override; + void GetHeadPoseData(double *data) override; private: - static bool isInitialised; - OVR::DeviceManager* pManager; - OVR::SensorDevice* pSensor; - OVR::SensorFusion* pSFusion; - settings s; double old_yaw; + ovrHmd hmd; + settings s; }; class TrackerControls: public QWidget, public ITrackerDialog { Q_OBJECT public: - explicit TrackerControls(); + explicit TrackerControls(); void registerTracker(ITracker *) {} - void unRegisterTracker() {} + void unRegisterTracker() {} private: - Ui::UIRiftControls ui; + Ui::UIRiftControls ui; settings s; private slots: - void doOK(); - void doCancel(); + void doOK(); + void doCancel(); }; class FTNoIR_TrackerDll : public Metadata { public: - FTNoIR_TrackerDll(); - ~FTNoIR_TrackerDll(); - void getFullName(QString *strToBeFilled); - void getShortName(QString *strToBeFilled); - void getDescription(QString *strToBeFilled); - void getIcon(QIcon *icon); + FTNoIR_TrackerDll(); + ~FTNoIR_TrackerDll(); + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); private: - QString trackerFullName; // Trackers' name and description - QString trackerShortName; - QString trackerDescription; + QString trackerFullName; // Trackers' name and description + QString trackerShortName; + QString trackerDescription; }; diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp index ad532100..38c7457e 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp @@ -1,19 +1,14 @@ #include "ftnoir_tracker_rift.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" TrackerControls::TrackerControls() : QWidget() { - ui.setupUi( this ); + ui.setupUi( this ); - // Connect Qt signals to member-functions connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - tie_setting(s.bEnableYaw, ui.chkEnableYaw); - tie_setting(s.bEnablePitch, ui.chkEnablePitch); - tie_setting(s.bEnableRoll, ui.chkEnableRoll); - tie_setting(s.constant_drift, ui.constantDrift); tie_setting(s.deadzone, ui.deadzone); tie_setting(s.persistence, ui.persistence); @@ -26,11 +21,11 @@ void TrackerControls::doOK() { } void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); close(); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog() { return new TrackerControls; } diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp index 2b24411c..902c8051 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift_dll.cpp @@ -1,7 +1,7 @@ /* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */ #include "ftnoir_tracker_rift.h" #include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" FTNoIR_TrackerDll::FTNoIR_TrackerDll() { //populate the description strings @@ -35,7 +35,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/rift_tiny.png"); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_TrackerDll; } diff --git a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui index 5c602792..4a5624cf 100644 --- a/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui +++ b/ftnoir_tracker_udp/ftnoir_ftnclientcontrols.ui @@ -1,384 +1,66 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>UICFTNClientControls</class>
- <widget class="QWidget" name="UICFTNClientControls">
- <property name="windowModality">
- <enum>Qt::NonModal</enum>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>411</width>
- <height>232</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>UDP tracker settings</string>
- </property>
- <property name="windowIcon">
- <iconset>
- <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="_vertical_layout">
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Port-number</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="spinPortNumber">
- <property name="minimum">
- <number>5550</number>
- </property>
- <property name="maximum">
- <number>10000</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>85</height>
- </size>
- </property>
- <property name="title">
- <string>Enable Axis</string>
- </property>
- <widget class="QWidget" name="layoutWidget">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>20</y>
- <width>147</width>
- <height>68</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Roll:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Pitch:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Yaw:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="chkEnableRoll">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="styleSheet">
- <string notr="true"/>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="chkEnablePitch">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QCheckBox" name="chkEnableYaw">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>X:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QCheckBox" name="chkEnableX">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="3">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Y:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="4">
- <widget class="QCheckBox" name="chkEnableY">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QLabel" name="label_16">
- <property name="text">
- <string>Z:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="4">
- <widget class="QCheckBox" name="chkEnableZ">
- <property name="maximumSize">
- <size>
- <width>20</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Enter the port-number for the remote PC.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Remember: you may have to change firewall-settings too!</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetDefaultConstraint</enum>
- </property>
- <item>
- <widget class="QPushButton" name="btnOK">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>spinPortNumber</tabstop>
- <tabstop>btnOK</tabstop>
- <tabstop>btnCancel</tabstop>
- </tabstops>
- <resources/>
- <connections/>
- <slots>
- <slot>startEngineClicked()</slot>
- <slot>stopEngineClicked()</slot>
- <slot>cameraSettingsClicked()</slot>
- </slots>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UICFTNClientControls</class> + <widget class="QWidget" name="UICFTNClientControls"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>216</width> + <height>71</height> + </rect> + </property> + <property name="windowTitle"> + <string>UDP tracker settings</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Port</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinPortNumber"> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>spinPortNumber</tabstop> + </tabstops> + <resources/> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp index 02ae21f0..136e075d 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp @@ -1,37 +1,7 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #include "ftnoir_tracker_udp.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" -FTNoIR_Tracker::FTNoIR_Tracker() : should_quit(false) -{ - should_quit = false; - - for (int i = 0; i < 6; i++) - newHeadPose[i] = 0; -} +FTNoIR_Tracker::FTNoIR_Tracker() : last_recv_pose { 0,0,0, 0,0,0 }, should_quit(false) {} FTNoIR_Tracker::~FTNoIR_Tracker() { @@ -39,45 +9,34 @@ FTNoIR_Tracker::~FTNoIR_Tracker() wait(); } -/** QThread run @override **/ void FTNoIR_Tracker::run() { - forever { + QByteArray datagram; + datagram.resize(sizeof(last_recv_pose)); + for (;;) { if (should_quit) break; - while (inSocket.hasPendingDatagrams()) { - QMutexLocker foo(&mutex); - QByteArray datagram; - datagram.resize(sizeof(newHeadPose)); - inSocket.readDatagram((char * ) newHeadPose, sizeof(double[6])); + QMutexLocker foo(&mutex); + while (sock.hasPendingDatagrams()) { + sock.readDatagram((char * ) last_recv_pose, sizeof(double[6])); } - usleep(10000); - } + msleep(1); + } } void FTNoIR_Tracker::StartTracker(QFrame*) { - (void) inSocket.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); + (void) sock.bind(QHostAddress::Any, (int) s.port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); start(); } void FTNoIR_Tracker::GetHeadPoseData(double *data) { QMutexLocker foo(&mutex); - if (s.enable_x) - data[TX] = newHeadPose[TX]; - if (s.enable_y) - data[TY] = newHeadPose[TY]; - if (s.enable_z) - data[TZ] = newHeadPose[TZ]; - if (s.enable_yaw) - data[Yaw] = newHeadPose[Yaw]; - if (s.enable_pitch) - data[Pitch] = newHeadPose[Pitch]; - if (s.enable_roll) - data[Roll] = newHeadPose[Roll]; + for (int i = 0; i < 6; i++) + data[i] = last_recv_pose[i]; } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() { return new FTNoIR_Tracker; } diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.h b/ftnoir_tracker_udp/ftnoir_tracker_udp.h index 62eb67df..a6f2e6d3 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.h +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.h @@ -1,58 +1,43 @@ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#pragma once #include "ui_ftnoir_ftnclientcontrols.h" -#include <QThread> #include <QUdpSocket> -#include <QMessageBox> -#include <QMutex> -#include <QWaitCondition> -#include <math.h> -#include "facetracknoir/global-settings.h" +#include <QThread> +#include <cmath> +#include "facetracknoir/plugin-api.hpp" #include "facetracknoir/options.h" using namespace options; struct settings { pbundle b; value<int> port; - value<bool> enable_roll, enable_pitch, enable_yaw, - enable_x, enable_y, enable_z; settings() : b(bundle("udp-tracker")), - port(b, "port", 4242), - enable_roll(b, "enable-roll", true), - enable_pitch(b, "enable-pitch", true), - enable_yaw(b, "enable-yaw", true), - enable_x(b, "enable-x", true), - enable_y(b, "enable-y", true), - enable_z(b, "enable-y", true) + port(b, "port", 4242) {} }; -class FTNoIR_Tracker : public ITracker, public QThread +class FTNoIR_Tracker : public ITracker, protected QThread { public: FTNoIR_Tracker(); ~FTNoIR_Tracker(); void StartTracker(QFrame *); void GetHeadPoseData(double *data); - volatile bool should_quit; protected: - void run(); // qthread override run method + void run() override; private: - QUdpSocket inSocket; - QHostAddress destIP; - QHostAddress srcIP; - double newHeadPose[6]; + QUdpSocket sock; + double last_recv_pose[6]; QMutex mutex; settings s; + volatile bool should_quit; }; -// Widget that has controls for FTNoIR protocol client-settings. class TrackerControls: public QWidget, public ITrackerDialog { Q_OBJECT public: - - explicit TrackerControls(); + TrackerControls(); void registerTracker(ITracker *) {} void unRegisterTracker() {} private: @@ -63,9 +48,6 @@ private slots: void doCancel(); }; -//******************************************************************************************************* -// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker -//******************************************************************************************************* class FTNoIR_TrackerDll : public Metadata { public: @@ -74,4 +56,3 @@ public: void getDescription(QString *strToBeFilled); void getIcon(QIcon *icon); }; - diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp index 8d1b99f2..062b1899 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp @@ -1,44 +1,14 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #include "ftnoir_tracker_udp.h" -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" TrackerControls::TrackerControls() : QWidget() { ui.setupUi( this ); - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - tie_setting(s.enable_x, ui.chkEnableX); - tie_setting(s.enable_y, ui.chkEnableY); - tie_setting(s.enable_z, ui.chkEnableZ); - tie_setting(s.enable_yaw, ui.chkEnableYaw); - tie_setting(s.enable_pitch, ui.chkEnablePitch); - tie_setting(s.enable_roll, ui.chkEnableRoll); tie_setting(s.port, ui.spinPortNumber); } @@ -48,11 +18,11 @@ void TrackerControls::doOK() { } void TrackerControls::doCancel() { - s.b->revert(); + s.b->reload(); this->close(); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( ) { return new TrackerControls; } diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp index 22dc7daa..7cd23552 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp @@ -1,30 +1,5 @@ -/******************************************************************************** -* FaceTrackNoIR This program is a private project of some enthusiastic * -* gamers from Holland, who don't like to pay much for * -* head-tracking. * -* * -* Copyright (C) 2012 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* Homepage * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU General Public License as published by the * -* Free Software Foundation; either version 3 of the License, or (at your * -* option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but * -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * -* more details. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see <http://www.gnu.org/licenses/>. * -* * -********************************************************************************/ #include "ftnoir_tracker_udp.h" -#include <QDebug> -#include "facetracknoir/global-settings.h" +#include "facetracknoir/plugin-support.h" void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) { @@ -46,7 +21,7 @@ void FTNoIR_TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/facetracknoir.png"); } -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() { return new FTNoIR_TrackerDll; } diff --git a/make-tar.sh b/make-tar.sh new file mode 100644 index 00000000..26b65dcb --- /dev/null +++ b/make-tar.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +prefix="$1" +filename="$2" + +if : && + make install && + cd $(dirname -- "${prefix}") && + tar Jcf "${filename}" $(basename "${prefix}") +then + ls -lh -- "${filename}" +else + rm -fv -- "${filename}" + exit 1 +fi + +exit 0 diff --git a/opentrack-api/context.cpp b/opentrack-api/context.cpp deleted file mode 100644 index 04fa5ac2..00000000 --- a/opentrack-api/context.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "opentrack-guts.h" -#include "opentrack.h" - -#if defined(__APPLE__) -# define SONAME "dylib" -#elif defined(_WIN32) -# define SONAME "dll" -#else -# define SONAME "so" -#endif - -#include <iostream> - -#ifdef _MSC_VER -# define LIB_PREFIX "" -#else -# define LIB_PREFIX "lib" -#endif - -static Metadata* get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon) -{ - Metadata* meta; - if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) - return NULL; - meta->getFullName(&longName); - meta->getIcon(&icon); - return meta; -} - -static QList<opentrack_meta> list_files(QString filter) -{ - QList<opentrack_meta> ret; - QStringList filenames = QDir((qApp->applicationDirPath())).entryList( - QStringList() << (LIB_PREFIX + filter + ("*." SONAME)), - QDir::Files, QDir::Name ); - for ( int i = 0; i < filenames.size(); i++) { - QIcon icon; - QString long_name; - QString str = filenames.at(i); - DynamicLibrary* lib = new DynamicLibrary(str); - qDebug() << "Loading" << str; - std::cout.flush(); - Metadata* meta; - if (!(meta = get_metadata(lib, long_name, icon))) - { - delete lib; - continue; - } - /* TODO perhaps return full name and somesuch */ - delete meta; - QString prefix(LIB_PREFIX + filter); - QString suffix("." SONAME); - if (str.size() > prefix.size() + suffix.size() && str.startsWith(prefix) && str.endsWith(suffix)) - { - auto str2 = str.mid(prefix.size(), str.size() - prefix.size() - suffix.size()); - opentrack_meta item(str2, lib); - ret.push_back(item); - } - } - - return ret; -} - -opentrack_ctx::opentrack_ctx(int argc, char** argv, void* window_parent) : - app(argc, argv), - meta_list(list_files("opentrack-tracker-")), - fake_frame(window_parent) -{ - const int count = meta_list.size(); - list = new char*[count + 1]; - for (int i = 0; i < count; i++) - { - QByteArray tmp = meta_list.at(i).path.toUtf8(); - int len = tmp.size(); - auto foo = new char[len+1]; - for (int j = 0; j < len; j++) - foo[j] = tmp.at(j); - foo[len] = '\0'; - list[i] = foo; - } - list[count] = NULL; -} - -opentrack_ctx::~opentrack_ctx() -{ - for (int i = 0; list[i]; i++) - { - delete[] list[i]; - } - delete[] list; -} - -extern "C" -{ - -OPENTRACK_EXPORT const char** opentrack_enum_trackers(opentrack ctx) -{ - return const_cast<const char**>(ctx->list); -} - -OPENTRACK_EXPORT opentrack opentrack_make_ctx(int argc, char** argv, void* window_parent) -{ - return new opentrack_ctx(argc, argv, window_parent); -} - -OPENTRACK_EXPORT void opentrack_finalize_ctx(opentrack foo) -{ - delete foo; -} - -} - diff --git a/opentrack-api/gnuc-version-script.txt b/opentrack-api/gnuc-version-script.txt deleted file mode 100644 index cd3a568d..00000000 --- a/opentrack-api/gnuc-version-script.txt +++ /dev/null @@ -1,12 +0,0 @@ -{ - global: - opentrack_make_ctx; - opentrack_finalize_ctx; - opentrack_enum_trackers; - opentrack_make_tracker; - opentrack_tracker_start; - opentrack_tracker_tick; - opentrack_finalize_tracker; - local: - *; -}; diff --git a/opentrack-api/opentrack-guts.h b/opentrack-api/opentrack-guts.h deleted file mode 100644 index c8e3309a..00000000 --- a/opentrack-api/opentrack-guts.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include <QFrame> -#include <QDir> -#include <QList> -#include <QStringList> -#include <QDebug> -#include <QIcon> -#include <QShowEvent> -#include <iostream> -#include <cstring> -#include <QString> -#include <QApplication> -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "facetracknoir/global-settings.h" -#include <memory> - -typedef ITracker* opentrack_tracker; - -class opentrack_meta { -public: - QString path; - std::shared_ptr<DynamicLibrary> lib; - - opentrack_meta(QString& path, DynamicLibrary* lib) : - path(path), lib(lib) - {} -}; - -class MyFrame : public QFrame { - Q_OBJECT -public: - MyFrame(void* parent) - { - if (parent == (void*) -1) - { - show(); - setVisible(false); - hide(); - } - else - { - create((WId) parent); - } - } - explicit MyFrame() {} -}; - -typedef class opentrack_ctx { -public: - QApplication app; - char** list; - QList<opentrack_meta> meta_list; - MyFrame fake_frame; - opentrack_ctx(int argc, char** argv, void* window_parent); - ~opentrack_ctx(); -} *opentrack; diff --git a/opentrack-api/opentrack.h b/opentrack-api/opentrack.h deleted file mode 100644 index 88ba6cf0..00000000 --- a/opentrack-api/opentrack.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif -#ifndef IN_OPENTRACK -/* opaque pointers, forward definitions */ -struct opentrack_opaque_ctx; -typedef struct opentrack_opaque_ctx* opentrack; -struct opentrack_opaque_tracker; -typedef struct opentrack_opaque_tracker* opentrack_tracker; -#endif - -#ifdef IN_OPENTRACK -# ifdef _WIN32 -# define OPENTRACK_EXPORT __declspec(dllexport) -# else -# define OPENTRACK_EXPORT -# endif -#else -# ifdef _WIN32 -# define OPENTRACK_EXPORT __declspec(dllimport) -# else -# define OPENTRACK_EXPORT -# endif -#endif - -/* for `opentrack_tracker_tick', individual headpose elts */ -#ifndef IN_OPENTRACK -enum opentrack_dof { - TX = 0, - TY, - TZ, - Yaw, - Pitch, - Roll, - DOF_count -}; -#endif - -OPENTRACK_EXPORT opentrack opentrack_make_ctx(int argc, char** argv, void* window_parent); -OPENTRACK_EXPORT void opentrack_finalize_ctx(opentrack self); - -/* no need to free the return value; invalid to modify it */ -OPENTRACK_EXPORT const char** opentrack_enum_trackers(opentrack self); - -/* - * don't `opentrack_tracker_tick an unstarted tracker, it's invalid to do so - * it's also invalid to start a finalized tracker - */ -OPENTRACK_EXPORT opentrack_tracker opentrack_make_tracker(opentrack ctx, const char* name); -OPENTRACK_EXPORT void opentrack_tracker_start(opentrack self, opentrack_tracker tracker); -OPENTRACK_EXPORT void opentrack_tracker_tick(opentrack_tracker tracker, double* headpose); -OPENTRACK_EXPORT void opentrack_finalize_tracker(opentrack_tracker tracker); -#ifdef __cplusplus -} -#endif - diff --git a/opentrack-api/trackers.cpp b/opentrack-api/trackers.cpp deleted file mode 100644 index 5027ec1d..00000000 --- a/opentrack-api/trackers.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "opentrack-guts.h" -#include "opentrack.h" - -extern "C" { - -opentrack_tracker OPENTRACK_EXPORT opentrack_make_tracker(opentrack ctx, const char* name) -{ - for (int i = 0; i < ctx->meta_list.size(); i++) - { - auto meta = ctx->meta_list.at(i); - if (ctx->meta_list.at(i).path == name) - { - ITracker* foo = static_cast<ITracker*>(meta.lib->Constructor()); - return foo; - } - } - return NULL; -} - -void OPENTRACK_EXPORT opentrack_finalize_tracker(opentrack_tracker tracker) -{ - delete tracker; -} - -void OPENTRACK_EXPORT opentrack_tracker_start(opentrack self, opentrack_tracker tracker) -{ - // hot damn, this is problematic! - // need to pass QFrame from somewhere - return tracker->StartTracker(&self->fake_frame); -} - -void OPENTRACK_EXPORT opentrack_tracker_tick(opentrack_tracker tracker, double* headpose) -{ - tracker->GetHeadPoseData(headpose); - QApplication::processEvents(0, 5); -} - -} diff --git a/opentrack-version.h b/opentrack-version.h deleted file mode 100644 index f31d5edf..00000000 --- a/opentrack-version.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef OPENTRACK_VERSION -# define OPENTRACK_VERSION @OPENTRACK_COMMIT_VERSION@ -#else -# ifndef OPENTRACK_VERSION -# define OPENTRACK_VERSION "Mourns-For-Trees" -# endif -#endif diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index 97a6db24..a4d03ed8 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -1,11 +1,3 @@ -/* Copyright (c) 2012, 2013 Stanisław Halik <sthalik@misaki.pl> - - * Permission to use, copy, modify, and/or distribute this - * software for any purpose with or without fee is hereby granted, - * provided that the above copyright notice and this permission - * notice appear in all copies. - */ - #include <QMutexLocker> #include <QCoreApplication> #include <QPointF> @@ -14,259 +6,193 @@ #include <QtAlgorithms> #include <QtAlgorithms> #include <QSettings> -#include <math.h> #include <QPixmap> +#include <algorithm> -// -// Constructor with List of Points in argument. -// -FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) : - _mutex(QMutex::Recursive) -{ - _title = title; - _points = QList<QPointF>(); - _data = 0; - _size = 0; - lastValueTracked = QPointF(0,0); - _tracking_active = false; - _max_Input = intMaxInput; // Added WVR 20120805 - _max_Output = intMaxOutput; - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - loadSettings(iniFile); - reload(); -} - -void FunctionConfig::setTrackingActive(bool blnActive) +void Map::setTrackingActive(bool blnActive) { - _tracking_active = blnActive; + activep = blnActive; } -FunctionConfig::FunctionConfig() : +Map::Map() : _mutex(QMutex::Recursive), - _data(0), - _size(0), - _tracking_active(false), - _max_Input(0), - _max_Output(0) + activep(false), + max_x(0), + max_y(0) { } -// -// Calculate the value of the function, given the input 'x'. -// Used to draw the curve and, most importantly, to translate input to output. -// The return-value is also stored internally, so the Widget can show the current value, when the Tracker is running. -// -float FunctionConfig::getValue(float x) { +float Map::getValue(float x) { QMutexLocker foo(&_mutex); - int x2 = (int) (std::min<float>(std::max<float>(x, -360), 360) * MEMOIZE_PRECISION); + int x2 = x * (double) MEMOIZE_PRECISION; float ret = getValueInternal(x2); - lastValueTracked.setX(x); - lastValueTracked.setY(ret); - return ret; + last_input_value.setX(x); + last_input_value.setY(ret); + return ret; } -// -// The return-value is also stored internally, so the Widget can show the current value, when the Tracker is running. -// -bool FunctionConfig::getLastPoint(QPointF& point ) { +bool Map::getLastPoint(QPointF& point ) { QMutexLocker foo(&_mutex); - point = lastValueTracked; - return _tracking_active; + point = last_input_value; + return activep; } -float FunctionConfig::getValueInternal(int x) { +float Map::getValueInternal(int x) { float sign = x < 0 ? -1 : 1; - x = x < 0 ? -x : x; + x = std::abs(x); float ret; - if (!_data) - ret = 0; - else if (_size == 0) - ret = 0; - else if (x < 0) - ret = 0; - else if (x < _size && x >= 0) - ret = _data[x]; - else - ret = _data[_size - 1]; - return ret * sign; + int sz = cur.data.size(); + if (sz == 0) + ret = 0; + else + ret = cur.data[std::max(std::min(x, sz-1), 0)]; + return ret * sign; } static __inline QPointF ensureInBounds(QList<QPointF> points, int i) { - int siz = points.size(); - if (siz == 0 || i < 0) - return QPointF(0, 0); - if (siz > i) - return points[i]; - return points[siz - 1]; + int siz = points.size(); + if (siz == 0 || i < 0) + return QPointF(0, 0); + if (siz > i) + return points[i]; + return points[siz - 1]; } static bool sortFn(const QPointF& one, const QPointF& two) { - return one.x() < two.x(); + return one.x() < two.x(); } -void FunctionConfig::reload() { - _size = 0; - - if (_points.size()) - qStableSort(_points.begin(), _points.end(), sortFn); - - if (_data) - delete[] _data; - _data = NULL; - if (_points.size()) { - _data = new float[_size = MEMOIZE_PRECISION * _points[_points.size() - 1].x()]; - - for (int i = 0; i < _size; i++) - _data[i] = -1e6; - - for (int k = 0; k < _points[0].x() * MEMOIZE_PRECISION; k++) { - if (k < _size) - _data[k] = _points[0].y() * k / (_points[0].x() * MEMOIZE_PRECISION); +void Map::reload() { + if (cur.input.size()) + { + auto& input = cur.input; + auto& data = cur.data; + + qStableSort(input.begin(), input.end(), sortFn); + data = std::vector<float>(MEMOIZE_PRECISION * input[input.size() - 1].x()); + + const int sz = data.size(); + + for (int i = 0; i < sz; i++) + data[i] = -1; + + for (int k = 0; k < input[0].x() * MEMOIZE_PRECISION; k++) { + if (k < sz) + data[k] = input[0].y() * k / (input[0].x() * MEMOIZE_PRECISION); } - - for (int i = 0; i < _points.size(); i++) { - QPointF p0 = ensureInBounds(_points, i - 1); - QPointF p1 = ensureInBounds(_points, i); - QPointF p2 = ensureInBounds(_points, i + 1); - QPointF p3 = ensureInBounds(_points, i + 2); - - int end = p2.x() * MEMOIZE_PRECISION; + + for (int i = 0; i < sz; i++) { + QPointF p0 = ensureInBounds(input, i - 1); + QPointF p1 = ensureInBounds(input, i); + QPointF p2 = ensureInBounds(input, i + 1); + QPointF p3 = ensureInBounds(input, i + 2); + + int end = std::min<int>(sz, p2.x() * MEMOIZE_PRECISION); int start = p1.x() * MEMOIZE_PRECISION; - - for (int j = start; j < end && j < _size; j++) { + + for (int j = start; j < end; j++) { double t = (j - start) / (double) (end - start); double t2 = t*t; double t3 = t*t*t; - + int x = .5 * ((2. * p1.x()) + (-p0.x() + p2.x()) * t + (2. * p0.x() - 5. * p1.x() + 4. * p2.x() - p3.x()) * t2 + (-p0.x() + 3. * p1.x() - 3. * p2.x() + p3.x()) * t3) * MEMOIZE_PRECISION; - + float y = .5 * ((2. * p1.y()) + - (-p0.y() + p2.y()) * t + - (2. * p0.y() - 5. * p1.y() + 4. * p2.y() - p3.y()) * t2 + - (-p0.y() + 3. * p1.y() - 3. * p2.y() + p3.y()) * t3); - - if (x >= 0 && x < _size) - _data[x] = y; + (-p0.y() + p2.y()) * t + + (2. * p0.y() - 5. * p1.y() + 4. * p2.y() - p3.y()) * t2 + + (-p0.y() + 3. * p1.y() - 3. * p2.y() + p3.y()) * t3); + + if (x >= 0 && x < sz) + data[x] = y; } - } - - float last = 0; - - for (int i = 0; i < _size; i++) - { - if (_data[i] == -1e6) - _data[i] = last; - last = _data[i]; - } - } -} - -FunctionConfig::~FunctionConfig() { - if (_data) - delete[] _data; + } + + float last = 0; + for (int i = 0; i < sz; i++) + { + if (data[i] <= 0) + data[i] = last; + last = data[i]; + } + } + else + cur.data.clear(); } -// -// Remove a Point from the Function. -// Used by the Widget. -// -void FunctionConfig::removePoint(int i) { +void Map::removePoint(int i) { QMutexLocker foo(&_mutex); - if (i >= 0 && i < _points.size()) + if (i >= 0 && i < cur.input.size()) { - _points.removeAt(i); + cur.input.removeAt(i); reload(); } } -// -// Add a Point to the Function. -// Used by the Widget and by loadSettings. -// -void FunctionConfig::addPoint(QPointF pt) { +void Map::addPoint(QPointF pt) { QMutexLocker foo(&_mutex); - _points.append(pt); - reload(); + cur.input.append(pt); + reload(); } -// -// Move a Function Point. -// Used by the Widget. -// -void FunctionConfig::movePoint(int idx, QPointF pt) { +void Map::movePoint(int idx, QPointF pt) { QMutexLocker foo(&_mutex); - if (idx >= 0 && idx < _points.size()) + if (idx >= 0 && idx < cur.input.size()) { - _points[idx] = pt; + cur.input[idx] = pt; reload(); } } -// -// Return the List of Points. -// Used by the Widget. -// -QList<QPointF> FunctionConfig::getPoints() { - QList<QPointF> ret; +const QList<QPointF> Map::getPoints() { QMutexLocker foo(&_mutex); - for (int i = 0; i < _points.size(); i++) { - ret.append(_points[i]); - } - return ret; + return cur.input; +} + +void Map::invalidate_unsaved_settings() +{ + cur = saved; + reload(); } -// -// Load the Points for the Function from the INI-file designated by settings. -// Settings for a specific Curve are loaded from their own Group in the INI-file. -// -void FunctionConfig::loadSettings(QSettings& settings) { +void Map::loadSettings(QSettings& settings, const QString& title) { QMutexLocker foo(&_mutex); QPointF newPoint; + QList<QPointF> points; + settings.beginGroup(QString("Curves-%1").arg(title)); - QList<QPointF> points; - settings.beginGroup(QString("Curves-%1").arg(_title)); - int max = settings.value("point-count", 0).toInt(); - for (int i = 0; i < max; i++) { - newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), 0).toFloat(), - settings.value(QString("point-%1-y").arg(i), 0).toFloat()); - // - // Make sure the new Point fits in the Function Range. - // Maybe this can be improved? - // - if (newPoint.x() > _max_Input) { - newPoint.setX(_max_Input); - } - if (newPoint.y() > _max_Output) { - newPoint.setY(_max_Output); - } - points.append(newPoint); - } + for (int i = 0; i < max; i++) { + newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), 0).toFloat(), + settings.value(QString("point-%1-y").arg(i), 0).toFloat()); + if (newPoint.x() > max_x) { + newPoint.setX(max_x); + } + if (newPoint.y() > max_y) { + newPoint.setY(max_y); + } + points.append(newPoint); + } + settings.endGroup(); - _points = points; - reload(); + cur.input = points; + reload(); + saved = cur; } -// -// Save the Points for the Function to the INI-file designated by settings. -// Settings for a specific Curve are saved in their own Group in the INI-file. -// The number of Points is also saved, to make loading more convenient. -// -void FunctionConfig::saveSettings(QSettings& settings) { +void Map::saveSettings(QSettings& settings, const QString& title) { QMutexLocker foo(&_mutex); - settings.beginGroup(QString("Curves-%1").arg(_title)); - int max = _points.size(); - settings.setValue("point-count", max); - for (int i = 0; i < max; i++) { - settings.setValue(QString("point-%1-x").arg(i), _points[i].x()); - settings.setValue(QString("point-%1-y").arg(i), _points[i].y()); + settings.beginGroup(QString("Curves-%1").arg(title)); + int max = cur.input.size(); + settings.setValue("point-count", max); + + for (int i = 0; i < max; i++) { + settings.setValue(QString("point-%1-x").arg(i), cur.input[i].x()); + settings.setValue(QString("point-%1-y").arg(i), cur.input[i].y()); } for (int i = max; true; i++) @@ -277,5 +203,8 @@ void FunctionConfig::saveSettings(QSettings& settings) { settings.remove(x); settings.remove(QString("point-%1-y").arg(i)); } - settings.endGroup(); + + saved = cur; + + settings.endGroup(); } diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index 4d771dfd..e24f54cf 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl> +/* Copyright (c) 2011-2014, Stanislaw Halik <sthalik@misaki.pl> * Permission to use, copy, modify, and/or distribute this * software for any purpose with or without fee is hereby granted, @@ -13,63 +13,61 @@ #include <QString> #include <QSettings> #include <QMutex> -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include <vector> +#include "../facetracknoir/plugin-api.hpp" +#include "../facetracknoir/qcopyable-mutex.hpp" -#define MEMOIZE_PRECISION 100 -class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { +class OPENTRACK_EXPORT Map { private: - QMutex _mutex; - QList<QPointF> _points; - void reload(); - float* _data; - int _size; - QString _title; + struct State { + QList<QPointF> input; + std::vector<float> data; + }; + + static constexpr long MEMOIZE_PRECISION = 25; + void reload(); float getValueInternal(int x); - QPointF lastValueTracked; // The last input value requested by the Tracker, with it's output-value. - volatile bool _tracking_active; - int _max_Input; - int _max_Output; - FunctionConfig(const FunctionConfig&) = delete; + + MyMutex _mutex; + QPointF last_input_value; + volatile bool activep; + int max_x; + int max_y; + + State cur, saved; public: - int maxInput() const { return _max_Input; } - int maxOutput() const { return _max_Output; } - // - // Contructor(s) and destructor - // - FunctionConfig(); - FunctionConfig(QString title, int intMaxInput, int intMaxOutput); - ~FunctionConfig(); + int maxInput() const { return max_x; } + int maxOutput() const { return max_y; } + Map(); + Map(int maxx, int maxy) + { + setMaxInput(maxx); + setMaxOutput(maxy); + } float getValue(float x); - bool getLastPoint(QPointF& point); // Get the last Point that was requested. - - // - // Functions to manipulate the Function - // - void removePoint(int i); + bool getLastPoint(QPointF& point); + void removePoint(int i); void removeAllPoints() { QMutexLocker foo(&_mutex); - _points.clear(); + cur.input.clear(); reload(); } - void addPoint(QPointF pt); - void movePoint(int idx, QPointF pt); - QList<QPointF> getPoints(); - void setMaxInput(int MaxInput) { - _max_Input = MaxInput; - } - void setMaxOutput(int MaxOutput) { - _max_Output = MaxOutput; - } + void addPoint(QPointF pt); + void movePoint(int idx, QPointF pt); + const QList<QPointF> getPoints(); + void setMaxInput(int MaxInput) { + max_x = MaxInput; + } + void setMaxOutput(int MaxOutput) { + max_y = MaxOutput; + } - // - // Functions to load/save the Function-Points to an INI-file - // - void saveSettings(QSettings& settings); - void loadSettings(QSettings& settings); + void saveSettings(QSettings& settings, const QString& title); + void loadSettings(QSettings& settings, const QString& title); + void invalidate_unsaved_settings(); - void setTrackingActive(bool blnActive); - QString getTitle() { return _title; } + void setTrackingActive(bool blnActive); }; diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 55d1e1bc..94a31be5 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -1,71 +1,47 @@ -/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl> - * Adapted to FaceTrackNoIR by Wim Vriend. - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - #include "qfunctionconfigurator/qfunctionconfigurator.h" #include <QPainter> #include <QPaintEvent> -#include <QPainterPathStroker> -#include <QPainterPath> -#include <QBrush> -#include <QFileDialog> #include <QPen> -#include <QMessageBox> -#include <QImage> #include <QPixmap> #include <QTimer> -#include <QtDebug> #include <cmath> -#include <QTabWidget> -#include <QTabBar> -#include <QFontMetrics> +#include <algorithm> static const int pointSize = 5; -QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) - : QWidget(parent) +QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) : + QWidget(parent), + _config(nullptr), + moving_control_point_idx(-1), + _draw_function(true) { - movingPoint = -1; // Index of that same point - _config = 0; - _draw_background = true; - _draw_function = true; update_range(); setMouseTracking(true); } -void QFunctionConfigurator::setConfig(FunctionConfig* config) { - QSettings settings("opentrack"); // Registry settings (in HK_USER) +void QFunctionConfigurator::setConfig(Map* config, const QString& name) { + QSettings settings("opentrack"); QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + QSettings iniFile( currentFile, QSettings::IniFormat ); - config->loadSettings(iniFile); + config->loadSettings(iniFile, name); _config = config; - _draw_function = _draw_background = true; + _draw_function = true; update_range(); update(); } -void QFunctionConfigurator::saveSettings(QString settingsFile) { - QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - - if (_config) { - _config->saveSettings(iniFile); - } -} - void QFunctionConfigurator::drawBackground() { if (!_config) return; _background = QPixmap(width(), height()); + QPainter painter(&_background); painter.fillRect(rect(), QColor::fromRgb(204, 204, 204)); - painter.setRenderHint(QPainter::Antialiasing); + QColor bg_color(112, 154, 209); - painter.fillRect(range, bg_color); + painter.fillRect(pixel_bounds, bg_color); QFont font; font.setPointSize(8); @@ -79,61 +55,59 @@ void QFunctionConfigurator::drawBackground() const int maxy = _config->maxOutput(); // horizontal grid - for (int i = 0; i < maxy; i += xstep) { - double y = range.height() - i * c.y() + range.y(); + double y = pixel_bounds.height() - i * c.y() + pixel_bounds.y(); drawLine(&painter, - QPointF(range.x(), y), - QPointF(range.x() + range.width(), y), + QPointF(pixel_bounds.x(), y), + QPointF(pixel_bounds.x() + pixel_bounds.width(), y), pen); painter.drawText(QRectF(10, y - metrics.height()/2, - range.left(), + pixel_bounds.left(), metrics.height()), QString::number(i)); } { const int i = maxy; - double y = range.height() - i * c.y() + range.y(); + double y = pixel_bounds.height() - i * c.y() + pixel_bounds.y(); drawLine(&painter, - QPointF(range.x(), y), - QPointF(range.x() + range.width(), y), + QPointF(pixel_bounds.x(), y), + QPointF(pixel_bounds.x() + pixel_bounds.width(), y), pen); painter.drawText(QRectF(10, y - metrics.height()/2, - range.x() - 10, + pixel_bounds.x() - 10, metrics.height()), QString::number(i)); } // vertical grid - for (int i = 0; i < maxx; i += ystep) { - double x = range.x() + i * c.x(); + double x = pixel_bounds.x() + i * c.x(); drawLine(&painter, - QPointF(x, range.y()), - QPointF(x, range.y() + range.height()), + QPointF(x, pixel_bounds.y()), + QPointF(x, pixel_bounds.y() + pixel_bounds.height()), pen); const QString text = QString::number(i); painter.drawText(QRectF(x - metrics.width(text)/2, - range.height() + 10 + metrics.height(), + pixel_bounds.height() + 10 + metrics.height(), metrics.width(text), metrics.height()), text); } { const int i = maxx; - double x = range.x() + i * c.x(); + double x = pixel_bounds.x() + i * c.x(); drawLine(&painter, - QPointF(x, range.y()), - QPointF(x, range.y() + range.height()), + QPointF(x, pixel_bounds.y()), + QPointF(x, pixel_bounds.y() + pixel_bounds.height()), pen); const QString text = QString::number(i); painter.drawText(QRectF(x - metrics.width(text)/2, - range.height() + 10 + metrics.height(), + pixel_bounds.height() + 10 + metrics.height(), metrics.width(text), metrics.height()), text); @@ -144,102 +118,82 @@ void QFunctionConfigurator::drawFunction() { if (!_config) return; - int i; - QPointF prevPoint; - QPointF currentPoint; _function = QPixmap(_background); QPainter painter(&_function); - - painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); QList<QPointF> points = _config->getPoints(); - for (i = 0; i < points.size(); i++) { - currentPoint = point_to_pixel( points[i] ); // Get the next point and convert it to Widget measures - drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120)); - lastPoint = currentPoint; // Remember which point is the rightmost in the graph + for (int i = 0; i < points.size(); i++) { + drawPoint(&painter, + point_to_pixel(points[i]), + QColor(200, 200, 210, 120)); } + QPen pen(spline_color, 1.2, Qt::SolidLine); - QPen pen(colBezier, 1.2, Qt::SolidLine); - - prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis - double max = _config->maxInput(); + static constexpr double step = 1.02; + const double max = _config->maxInput(); + QPointF prev = point_to_pixel(QPointF(0, 0)); - const double step = 1.01; for (double i = 0; i < max; i += step) { double val = _config->getValue(i); QPointF cur = point_to_pixel(QPointF(i, val)); drawLine(&painter, prev, cur, pen); prev = cur; } - painter.restore(); } void QFunctionConfigurator::paintEvent(QPaintEvent *e) { - QPointF prevPoint; - QPointF currentPoint; - QPointF actualPos; - int i; - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - if (_draw_background) { + if (_background.isNull()) drawBackground(); - _draw_background = false; - } - p.drawPixmap(e->rect(), _background); if (_draw_function) { - drawFunction(); // Draw the Function on a Pixmap _draw_function = false; + drawFunction(); } - p.drawPixmap(e->rect(), _function); // Always draw the background and the function + + p.drawPixmap(e->rect(), _function); if (_config) { QPen pen(Qt::white, 1, Qt::SolidLine); QList<QPointF> points = _config->getPoints(); - if (movingPoint >= 0 && movingPoint < points.size()) { - prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis - for (i = 0; i < points.size(); i++) { - currentPoint = point_to_pixel( points[i] ); // Get the next point and convert it to Widget measures - drawLine(&p, prevPoint, currentPoint, pen); - prevPoint = currentPoint; + if (points.size() && moving_control_point_idx >= 0 && moving_control_point_idx < points.size()) { + QPointF prev = points[0]; + for (int i = 1; i < points.size(); i++) { + auto tmp = point_to_pixel(points[i]); + drawLine(&p, prev, tmp, pen); + prev = tmp; } pen.setWidth(1); pen.setColor( Qt::white ); pen.setStyle( Qt::DashLine ); - actualPos = point_to_pixel(points[movingPoint]); - drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); - drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.height() + range.top()), pen); + QPointF pixel_pos = point_to_pixel(points[moving_control_point_idx]); + drawLine(&p, QPoint(pixel_bounds.left(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_pos.y()), pen); + drawLine(&p, QPoint(pixel_pos.x(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_bounds.height() + pixel_bounds.top()), pen); } - // // If the Tracker is active, the 'Last Point' it requested is recorded. // Show that point on the graph, with some lines to assist. // This new feature is very handy for tweaking the curves! - // - if (_config->getLastPoint( currentPoint )) { - actualPos = point_to_pixel( QPointF(fabs(currentPoint.x()), fabs(currentPoint.y())) ); - drawPoint(&p, actualPos, QColor(255, 0, 0, 120)); + QPointF last; + if (_config->getLastPoint(last)) { + QPointF pixel_pos = point_to_pixel( QPointF(fabs(last.x()), fabs(last.y())) ); + drawPoint(&p, pixel_pos, QColor(255, 0, 0, 120)); pen.setWidth(1); pen.setColor( Qt::black ); pen.setStyle( Qt::SolidLine ); - drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); - drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.width()), pen); + drawLine(&p, QPoint(pixel_bounds.left(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_pos.y()), pen); + drawLine(&p, QPoint(pixel_pos.x(), pixel_pos.y()), QPoint(pixel_pos.x(), pixel_bounds.width()), pen); } - } } -// -// Draw the handle, to move the Bezier-curve. -// void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG ) { painter->save(); @@ -251,7 +205,7 @@ void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QCo painter->restore(); } -void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen) +void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen &pen) { painter->save(); painter->setPen(pen); @@ -267,19 +221,17 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) QList<QPointF> points = _config->getPoints(); if (e->button() == Qt::LeftButton) { bool bTouchingPoint = false; - movingPoint = -1; + moving_control_point_idx = -1; if (_config) { for (int i = 0; i < points.size(); i++) { - if ( point_within_pixel(points[i], e->pos() ) ) { + if (point_within_pixel(points[i], e->pos())) { bTouchingPoint = true; - movingPoint = i; - timer.restart(); + moving_control_point_idx = i; break; } } if (!bTouchingPoint) { _config->addPoint(pixel_coord_to_point(e->pos())); - emit CurveChanged( true ); } } } @@ -288,7 +240,7 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) if (_config) { int found_pt = -1; for (int i = 0; i < points.size(); i++) { - if ( point_within_pixel(points[i], e->pos() ) ) { + if (point_within_pixel(points[i], e->pos())) { found_pt = i; break; } @@ -296,9 +248,8 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) if (found_pt != -1) { _config->removePoint(found_pt); - emit CurveChanged( true ); } - movingPoint = -1; + moving_control_point_idx = -1; } } _draw_function = true; @@ -309,29 +260,43 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) { if (!_config) return; + + static constexpr int min_refresh_delay = 12; + + if (timer.isValid() && timer.elapsed() < min_refresh_delay) + return; + + static constexpr int refresh_delay = 17; QList<QPointF> points = _config->getPoints(); - const int refresh_delay = 50; - if (movingPoint >= 0 && movingPoint < points.size()) { + if (moving_control_point_idx != -1 && moving_control_point_idx < points.size()) { setCursor(Qt::ClosedHandCursor); - - if (timer.isValid() && timer.elapsed() > refresh_delay) + + bool overlap = false; + + QPointF new_pt = pixel_coord_to_point(e->pos()); + + if (moving_control_point_idx + 1 < points.size()) + overlap |= new_pt.x() > points[moving_control_point_idx+1].x(); + if (moving_control_point_idx != 0) + overlap |= new_pt.x() < points[moving_control_point_idx-1].x(); + + if (overlap) + moving_control_point_idx = -1; + else if (timer.isValid() && timer.elapsed() > refresh_delay) { timer.restart(); - QPointF new_pt = pixel_coord_to_point(e->pos()); - points[movingPoint] = new_pt; - _config->movePoint(movingPoint, new_pt); + points[moving_control_point_idx] = new_pt; + _config->movePoint(moving_control_point_idx, new_pt); _draw_function = true; update(); } } else { bool bTouchingPoint = false; - if (_config) { - for (int i = 0; i < points.size(); i++) { - if ( point_within_pixel(points[i], e->pos() ) ) { - bTouchingPoint = true; - } + for (int i = 0; i < points.size(); i++) { + if ( point_within_pixel(points[i], e->pos() ) ) { + bTouchingPoint = true; } } @@ -348,38 +313,54 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) { if (!_config) return; - QList<QPointF> points = _config->getPoints(); if (e->button() == Qt::LeftButton) { - timer.invalidate(); - if (movingPoint >= 0 && movingPoint < points.size()) { - emit CurveChanged( true ); + QList<QPointF> points = _config->getPoints(); + if (moving_control_point_idx >= 0 && moving_control_point_idx < points.size()) { if (_config) { - _config->movePoint(movingPoint, pixel_coord_to_point(e->pos())); + _config->movePoint(moving_control_point_idx, pixel_coord_to_point(e->pos())); } } setCursor(Qt::ArrowCursor); - movingPoint = -1; + moving_control_point_idx = -1; + + _draw_function = true; + update(); } +} +void QFunctionConfigurator::update_range() +{ + if (!_config) + return; + + const double w = width(), h = height(); + const double mwl = 40, mhl = 20; + const double mwr = 15, mhr = 35; + + pixel_bounds = QRectF(mwl, mhl, (w - mwl - mwr), (h - mhl - mhr)); + c = QPointF(pixel_bounds.width() / _config->maxInput(), pixel_bounds.height() / _config->maxOutput()); _draw_function = true; - update(); + + _background = QPixmap(); + _function = QPixmap(); } -bool QFunctionConfigurator::point_within_pixel(QPointF pt, QPointF pixel) const +bool QFunctionConfigurator::point_within_pixel(const QPointF &pt, const QPointF &pixel) { - QPointF pixel2(range.x() + pt.x() * c.x(), (range.y() + range.height() - pt.y() * c.y())); + QPointF pixel2(pixel_bounds.x() + pt.x() * c.x(), + (pixel_bounds.y() + pixel_bounds.height() - pt.y() * c.y())); return pixel2.x() >= pixel.x() - pointSize && pixel2.x() < pixel.x() + pointSize && pixel2.y() >= pixel.y() - pointSize && pixel2.y() < pixel.y() + pointSize; } -QPointF QFunctionConfigurator::pixel_coord_to_point(QPointF point) const +QPointF QFunctionConfigurator::pixel_coord_to_point(const QPointF& point) { if (!_config) return QPointF(-1, -1); - double x = (point.x() - range.x()) / c.x(); - double y = (range.height() - point.y() + range.y()) / c.y(); + double x = (point.x() - pixel_bounds.x()) / c.x(); + double y = (pixel_bounds.height() - point.y() + pixel_bounds.y()) / c.y(); if (x < 0) x = 0; @@ -394,20 +375,14 @@ QPointF QFunctionConfigurator::pixel_coord_to_point(QPointF point) const return QPointF(x, y); } -QPointF QFunctionConfigurator::point_to_pixel(QPointF point) const -{ - return QPointF(range.x() + point.x() * c.x(), - range.y() + range.height() - point.y() * c.y()); -} - -void QFunctionConfigurator::setColorBezier(QColor color) +QPointF QFunctionConfigurator::point_to_pixel(const QPointF& point) { - colBezier = color; - update(); + return QPointF(pixel_bounds.x() + point.x() * c.x(), + pixel_bounds.y() + pixel_bounds.height() - point.y() * c.y()); } void QFunctionConfigurator::resizeEvent(QResizeEvent *) { update_range(); - repaint(); + update(); } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 1f6b4f78..229d9977 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -1,92 +1,71 @@ -/* Copyright (c) 2011-2012 Stanislaw Halik <sthalik@misaki.pl> - * Adapted to FaceTrackNoIR by Wim Vriend. +/* Copyright (c) 2011-2014 Stanislaw Halik <sthalik@misaki.pl> + * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ -#ifndef QFUNCTIONCONFIGURATOR_H -#define QFUNCTIONCONFIGURATOR_H + +// Adapted to FaceTrackNoIR by Wim Vriend. + +#pragma once #include <QWidget> #include <QtGui> #include <QPointF> #include <QElapsedTimer> #include "qfunctionconfigurator/functionconfig.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" - -// -// The FunctionConfigurator Widget is used to display and configure a function (curve). -// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function. -// -// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the -// Widget and the Widget used to change the Function. -// +#include "facetracknoir/plugin-api.hpp" -class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget +class OPENTRACK_EXPORT QFunctionConfigurator : public QWidget { Q_OBJECT Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier) +public: + QFunctionConfigurator(QWidget *parent = 0); + + Map* config(); + void setConfig(Map* config, const QString &name); + QColor colorBezier() const { - return colBezier; + return spline_color; + } + void setColorBezier(QColor color) + { + spline_color = color; + update(); } -public: - QFunctionConfigurator(QWidget *parent = 0); - FunctionConfig* config(); - - void setConfig(FunctionConfig* config); - void saveSettings(QString settingsFile); - -signals: - void CurveChanged(bool); - -public slots: - void setColorBezier(QColor); protected slots: void paintEvent(QPaintEvent *e); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); - -protected: +private: void drawBackground(); void drawFunction(); void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); - void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); - bool point_within_pixel(QPointF pt, QPointF pixel) const; - + void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen& pen); + bool point_within_pixel(const QPointF& pt, const QPointF& pixel); protected: - virtual void resizeEvent(QResizeEvent *); - + void resizeEvent(QResizeEvent *) override; private: - void update_range() { - if (!_config) - return; - double w = width(), h = height(); - const double mwl = 40, mhl = 20; - const double mwr = 15, mhr = 35; - range = QRectF(mwl, mhl, (w - mwl - mwr), (h - mhl - mhr)); - c = QPointF(range.width() / _config->maxInput(), range.height() / _config->maxOutput()); - _draw_function = _draw_background = true; - } + void update_range(); - QRectF range; // The actual rectangle for the Bezier-curve - QPointF lastPoint; // The right-most point of the Function - QPointF pixel_coord_to_point (QPointF point) const; // Convert the graphical Point to a real-life Point - QPointF point_to_pixel (QPointF point) const; // Convert the Point to a graphical Point + QPointF pixel_coord_to_point (const QPointF& point); + QPointF point_to_pixel (const QPointF& point); - int movingPoint; + Map* _config; + + // bounds of the rectangle user can interact with + QRectF pixel_bounds; + + int moving_control_point_idx; QElapsedTimer timer; QPointF c; - QColor colBezier; // Color of Bezier curve - - bool _draw_background; // Flag to determine if the background should be (re-)drawn on the QPixmap - QPixmap _background; // Image of the static parts (axis, lines, etc.) - bool _draw_function; // Flag to determine if the function should be (re-)drawn on the QPixmap - QPixmap _function; // Image of the function (static unless edited by the user) - - FunctionConfig* _config; + QColor spline_color; + + QPixmap _background; + QPixmap _function; + bool _draw_function; }; - -#endif // QFUNCTIONCONFIGURATOR_H diff --git a/qxt-mini/plat/qxtglobalshortcut_mac.cpp b/qxt-mini/plat/qxtglobalshortcut_mac.cpp index f43c773a..fbf86a94 100644 --- a/qxt-mini/plat/qxtglobalshortcut_mac.cpp +++ b/qxt-mini/plat/qxtglobalshortcut_mac.cpp @@ -1,4 +1,4 @@ -#include <Carbon/Carbon.h>
+#include <Carbon/Carbon.h> /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. @@ -29,235 +29,235 @@ ** <http://libqxt.org> <foundation@libqxt.org> *****************************************************************************/ -#include "qxtglobalshortcut_p.h"
-#include <QMap>
-#include <QHash>
-#include <QtDebug>
-#include <QApplication>
-
-typedef QPair<uint, uint> Identifier;
-static QMap<quint32, EventHotKeyRef> keyRefs;
-static QHash<Identifier, quint32> keyIDs;
-static quint32 hotKeySerial = 0;
-static bool qxt_mac_handler_installed = false;
-
-OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
-{
- Q_UNUSED(nextHandler);
- Q_UNUSED(data);
- if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
- {
- EventHotKeyID keyID;
- GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
- Identifier id = keyIDs.key(keyID.id);
+#include "qxtglobalshortcut_p.h" +#include <QMap> +#include <QHash> +#include <QtDebug> +#include <QApplication> + +typedef QPair<uint, uint> Identifier; +static QMap<quint32, EventHotKeyRef> keyRefs; +static QHash<Identifier, quint32> keyIDs; +static quint32 hotKeySerial = 0; +static bool qxt_mac_handler_installed = false; + +OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) + { + EventHotKeyID keyID; + GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); + Identifier id = keyIDs.key(keyID.id); if(id != Identifier()) - QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
- }
- return noErr;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= shiftKey;
- if (modifiers & Qt::ControlModifier)
- native |= cmdKey;
- if (modifiers & Qt::AltModifier)
- native |= optionKey;
- if (modifiers & Qt::MetaModifier)
- native |= controlKey;
- if (modifiers & Qt::KeypadModifier)
- native |= kEventKeyModifierNumLockMask;
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- UTF16Char ch;
- // Constants found in NSEvent.h from AppKit.framework
- switch (key)
- {
- case Qt::Key_Return:
- return kVK_Return;
- case Qt::Key_Enter:
- return kVK_ANSI_KeypadEnter;
- case Qt::Key_Tab:
- return kVK_Tab;
- case Qt::Key_Space:
- return kVK_Space;
- case Qt::Key_Backspace:
- return kVK_Delete;
- case Qt::Key_Control:
- return kVK_Command;
- case Qt::Key_Shift:
- return kVK_Shift;
- case Qt::Key_CapsLock:
- return kVK_CapsLock;
- case Qt::Key_Option:
- return kVK_Option;
- case Qt::Key_Meta:
- return kVK_Control;
- case Qt::Key_F17:
- return kVK_F17;
- case Qt::Key_VolumeUp:
- return kVK_VolumeUp;
- case Qt::Key_VolumeDown:
- return kVK_VolumeDown;
- case Qt::Key_F18:
- return kVK_F18;
- case Qt::Key_F19:
- return kVK_F19;
- case Qt::Key_F20:
- return kVK_F20;
- case Qt::Key_F5:
- return kVK_F5;
- case Qt::Key_F6:
- return kVK_F6;
- case Qt::Key_F7:
- return kVK_F7;
- case Qt::Key_F3:
- return kVK_F3;
- case Qt::Key_F8:
- return kVK_F8;
- case Qt::Key_F9:
- return kVK_F9;
- case Qt::Key_F11:
- return kVK_F11;
- case Qt::Key_F13:
- return kVK_F13;
- case Qt::Key_F16:
- return kVK_F16;
- case Qt::Key_F14:
- return kVK_F14;
- case Qt::Key_F10:
- return kVK_F10;
- case Qt::Key_F12:
- return kVK_F12;
- case Qt::Key_F15:
- return kVK_F15;
- case Qt::Key_Help:
- return kVK_Help;
- case Qt::Key_Home:
- return kVK_Home;
- case Qt::Key_PageUp:
- return kVK_PageUp;
- case Qt::Key_Delete:
- return kVK_ForwardDelete;
- case Qt::Key_F4:
- return kVK_F4;
- case Qt::Key_End:
- return kVK_End;
- case Qt::Key_F2:
- return kVK_F2;
- case Qt::Key_PageDown:
- return kVK_PageDown;
- case Qt::Key_F1:
- return kVK_F1;
- case Qt::Key_Left:
- return kVK_LeftArrow;
- case Qt::Key_Right:
- return kVK_RightArrow;
- case Qt::Key_Down:
- return kVK_DownArrow;
- case Qt::Key_Up:
- return kVK_UpArrow;
- default:
- ;
- }
-
- if (key == Qt::Key_Escape) ch = 27;
- else if (key == Qt::Key_Return) ch = 13;
- else if (key == Qt::Key_Enter) ch = 3;
- else if (key == Qt::Key_Tab) ch = 9;
- else ch = key;
-
- CFDataRef currentLayoutData;
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
-
- if (currentKeyboard == NULL)
- return 0;
-
- currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
- CFRelease(currentKeyboard);
- if (currentLayoutData == NULL)
- return 0;
-
- UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
- UCKeyboardTypeHeader* table = header->keyboardTypeList;
-
- uint8_t *data = (uint8_t*)header;
- // God, would a little documentation for this shit kill you...
- for (quint32 i=0; i < header->keyboardTypeCount; i++)
- {
- UCKeyStateRecordsIndex* stateRec = 0;
- if (table[i].keyStateRecordsIndexOffset != 0)
- {
- stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
- if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
- }
-
- UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
- if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
-
- for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
- {
- UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
- for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
- {
- if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
- {
- long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
- if (stateRec && idx < stateRec->keyStateRecordCount)
- {
- UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
- if (rec->stateZeroCharData == ch) return k;
- }
- }
- else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
- {
- if (keyToChar[k] == ch) return k;
- }
- } // for k
- } // for j
- } // for i
- return 0;
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- if (!qxt_mac_handler_installed)
- {
+ QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first); + } + return noErr; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= shiftKey; + if (modifiers & Qt::ControlModifier) + native |= cmdKey; + if (modifiers & Qt::AltModifier) + native |= optionKey; + if (modifiers & Qt::MetaModifier) + native |= controlKey; + if (modifiers & Qt::KeypadModifier) + native |= kEventKeyModifierNumLockMask; + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + UTF16Char ch; + // Constants found in NSEvent.h from AppKit.framework + switch (key) + { + case Qt::Key_Return: + return kVK_Return; + case Qt::Key_Enter: + return kVK_ANSI_KeypadEnter; + case Qt::Key_Tab: + return kVK_Tab; + case Qt::Key_Space: + return kVK_Space; + case Qt::Key_Backspace: + return kVK_Delete; + case Qt::Key_Control: + return kVK_Command; + case Qt::Key_Shift: + return kVK_Shift; + case Qt::Key_CapsLock: + return kVK_CapsLock; + case Qt::Key_Option: + return kVK_Option; + case Qt::Key_Meta: + return kVK_Control; + case Qt::Key_F17: + return kVK_F17; + case Qt::Key_VolumeUp: + return kVK_VolumeUp; + case Qt::Key_VolumeDown: + return kVK_VolumeDown; + case Qt::Key_F18: + return kVK_F18; + case Qt::Key_F19: + return kVK_F19; + case Qt::Key_F20: + return kVK_F20; + case Qt::Key_F5: + return kVK_F5; + case Qt::Key_F6: + return kVK_F6; + case Qt::Key_F7: + return kVK_F7; + case Qt::Key_F3: + return kVK_F3; + case Qt::Key_F8: + return kVK_F8; + case Qt::Key_F9: + return kVK_F9; + case Qt::Key_F11: + return kVK_F11; + case Qt::Key_F13: + return kVK_F13; + case Qt::Key_F16: + return kVK_F16; + case Qt::Key_F14: + return kVK_F14; + case Qt::Key_F10: + return kVK_F10; + case Qt::Key_F12: + return kVK_F12; + case Qt::Key_F15: + return kVK_F15; + case Qt::Key_Help: + return kVK_Help; + case Qt::Key_Home: + return kVK_Home; + case Qt::Key_PageUp: + return kVK_PageUp; + case Qt::Key_Delete: + return kVK_ForwardDelete; + case Qt::Key_F4: + return kVK_F4; + case Qt::Key_End: + return kVK_End; + case Qt::Key_F2: + return kVK_F2; + case Qt::Key_PageDown: + return kVK_PageDown; + case Qt::Key_F1: + return kVK_F1; + case Qt::Key_Left: + return kVK_LeftArrow; + case Qt::Key_Right: + return kVK_RightArrow; + case Qt::Key_Down: + return kVK_DownArrow; + case Qt::Key_Up: + return kVK_UpArrow; + default: + ; + } + + if (key == Qt::Key_Escape) ch = 27; + else if (key == Qt::Key_Return) ch = 13; + else if (key == Qt::Key_Enter) ch = 3; + else if (key == Qt::Key_Tab) ch = 9; + else ch = key; + + CFDataRef currentLayoutData; + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + + if (currentKeyboard == NULL) + return 0; + + currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(currentKeyboard); + if (currentLayoutData == NULL) + return 0; + + UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData); + UCKeyboardTypeHeader* table = header->keyboardTypeList; + + uint8_t *data = (uint8_t*)header; + // God, would a little documentation for this shit kill you... + for (quint32 i=0; i < header->keyboardTypeCount; i++) + { + UCKeyStateRecordsIndex* stateRec = 0; + if (table[i].keyStateRecordsIndexOffset != 0) + { + stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset); + if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; + } + + UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset); + if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; + + for (quint32 j=0; j < charTable->keyToCharTableCount; j++) + { + UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]); + for (quint32 k=0; k < charTable->keyToCharTableSize; k++) + { + if (keyToChar[k] & kUCKeyOutputTestForIndexMask) + { + long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; + if (stateRec && idx < stateRec->keyStateRecordCount) + { + UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]); + if (rec->stateZeroCharData == ch) return k; + } + } + else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) + { + if (keyToChar[k] == ch) return k; + } + } // for k + } // for j + } // for i + return 0; +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + if (!qxt_mac_handler_installed) + { qxt_mac_handler_installed = true; - EventTypeSpec t;
- t.eventClass = kEventClassKeyboard;
- t.eventKind = kEventHotKeyPressed;
- InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
- }
-
- EventHotKeyID keyID;
- keyID.signature = 'cute';
- keyID.id = ++hotKeySerial;
-
- EventHotKeyRef ref = 0;
- bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
- if (rv)
- {
- keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
- keyRefs.insert(keyID.id, ref);
- }
- return rv;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- Identifier id(nativeMods, nativeKey);
- if (!keyIDs.contains(id)) return false;
-
- EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
- keyIDs.remove(id);
- return !UnregisterEventHotKey(ref);
-}
+ EventTypeSpec t; + t.eventClass = kEventClassKeyboard; + t.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); + } + + EventHotKeyID keyID; + keyID.signature = 'cute'; + keyID.id = ++hotKeySerial; + + EventHotKeyRef ref = 0; + bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); + if (rv) + { + keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); + keyRefs.insert(keyID.id, ref); + } + return rv; +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Identifier id(nativeMods, nativeKey); + if (!keyIDs.contains(id)) return false; + + EventHotKeyRef ref = keyRefs.take(keyIDs[id]); + keyIDs.remove(id); + return !UnregisterEventHotKey(ref); +} bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, void *message, long *result) { diff --git a/qxt-mini/plat/qxtglobalshortcut_x11.cpp b/qxt-mini/plat/qxtglobalshortcut_x11.cpp index 0c203dd8..f18f86db 100644 --- a/qxt-mini/plat/qxtglobalshortcut_x11.cpp +++ b/qxt-mini/plat/qxtglobalshortcut_x11.cpp @@ -1,235 +1,235 @@ -#include "../qxtglobalshortcut_p.h"
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#include <QVector>
-#include <QApplication>
-// include private header for great justice -sh 20131015
-#include <X11/Xlib.h>
-#include <xcb/xcb.h>
-#include "qplatformnativeinterface.h"
-
-namespace {
-
-const QVector<quint32> maskModifiers = QVector<quint32>()
- << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
-
-typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);
-
-class QxtX11ErrorHandler {
-public:
- static bool error;
-
- static int qxtX11ErrorHandler(Display *display, XErrorEvent *event)
- {
- Q_UNUSED(display);
- switch (event->error_code)
- {
- case BadAccess:
- case BadValue:
- case BadWindow:
- if (event->request_code == 33 /* X_GrabKey */ ||
- event->request_code == 34 /* X_UngrabKey */)
- {
- error = true;
- //TODO:
- //char errstr[256];
- //XGetErrorText(dpy, err->error_code, errstr, 256);
- }
- }
- return 0;
- }
-
- QxtX11ErrorHandler()
- {
- error = false;
- m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
- }
-
- ~QxtX11ErrorHandler()
- {
- XSetErrorHandler(m_previousErrorHandler);
- }
-
-private:
- X11ErrorHandler m_previousErrorHandler;
-};
-
-bool QxtX11ErrorHandler::error = false;
-
-class QxtX11Data {
-public:
- QxtX11Data()
- {
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- m_display = QX11Info::display();
-#else
- QPlatformNativeInterface *native = qApp->platformNativeInterface();
- void *display = native->nativeResourceForScreen(QByteArray("display"),
- QGuiApplication::primaryScreen());
- m_display = reinterpret_cast<Display *>(display);
-#endif
- }
-
- bool isValid()
- {
- return m_display != 0;
- }
-
- Display *display()
- {
- Q_ASSERT(isValid());
- return m_display;
- }
-
- Window rootWindow()
- {
- return DefaultRootWindow(display());
- }
-
- bool grabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) {
- XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True,
- GrabModeAsync, GrabModeAsync);
- }
-
- if (errorHandler.error) {
- ungrabKey(keycode, modifiers, window);
- return false;
- }
-
- return true;
- }
-
- bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- foreach (quint32 maskMods, maskModifiers) {
- XUngrabKey(display(), keycode, modifiers | maskMods, window);
- }
-
- return !errorHandler.error;
- }
-
-private:
- Display *m_display;
-};
-
-} // namespace
-
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
-bool QxtGlobalShortcutPrivate::eventFilter(void *message)
-{
- XEvent *event = static_cast<XEvent *>(message);
- if (event->type == KeyPress)
- {
- XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event);
- unsigned int keycode = key->keycode;
- unsigned int keystate = key->state;
-#else
-bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
- void *message, long *result)
-{
- Q_UNUSED(result);
-
- xcb_key_press_event_t *kev = 0;
- if (eventType == "xcb_generic_event_t") {
- xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
- if ((ev->response_type & 127) == XCB_KEY_PRESS)
- kev = static_cast<xcb_key_press_event_t *>(message);
- }
-
- if (kev != 0) {
- unsigned int keycode = kev->detail;
- unsigned int keystate = 0;
- if(kev->state & XCB_MOD_MASK_1)
- keystate |= Mod1Mask;
- if(kev->state & XCB_MOD_MASK_CONTROL)
- keystate |= ControlMask;
- if(kev->state & XCB_MOD_MASK_4)
- keystate |= Mod4Mask;
- if(kev->state & XCB_MOD_MASK_SHIFT)
- keystate |= ShiftMask;
-#endif
- activateShortcut(keycode,
- // Mod1Mask == Alt, Mod4Mask == Meta
- keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
- }
- return false;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= ShiftMask;
- if (modifiers & Qt::ControlModifier)
- native |= ControlMask;
- if (modifiers & Qt::AltModifier)
- native |= Mod1Mask;
- if (modifiers & Qt::MetaModifier)
- native |= Mod4Mask;
-
- // TODO: resolve these?
- //if (modifiers & Qt::MetaModifier)
- //if (modifiers & Qt::KeypadModifier)
- //if (modifiers & Qt::GroupSwitchModifier)
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- QxtX11Data x11;
- if (!x11.isValid())
- return 0;
-
- KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
- if (keysym == NoSymbol)
- keysym = static_cast<ushort>(key);
-
- return XKeysymToKeycode(x11.display(), keysym);
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow());
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow());
-}
+#include "../qxtglobalshortcut_p.h" +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** <http://libqxt.org> <foundation@libqxt.org> +*****************************************************************************/ + +#include <QVector> +#include <QApplication> +// include private header for great justice -sh 20131015 +#include <X11/Xlib.h> +#include <xcb/xcb.h> +#include "qplatformnativeinterface.h" + +namespace { + +const QVector<quint32> maskModifiers = QVector<quint32>() + << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask); + +typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event); + +class QxtX11ErrorHandler { +public: + static bool error; + + static int qxtX11ErrorHandler(Display *display, XErrorEvent *event) + { + Q_UNUSED(display); + switch (event->error_code) + { + case BadAccess: + case BadValue: + case BadWindow: + if (event->request_code == 33 /* X_GrabKey */ || + event->request_code == 34 /* X_UngrabKey */) + { + error = true; + //TODO: + //char errstr[256]; + //XGetErrorText(dpy, err->error_code, errstr, 256); + } + } + return 0; + } + + QxtX11ErrorHandler() + { + error = false; + m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler); + } + + ~QxtX11ErrorHandler() + { + XSetErrorHandler(m_previousErrorHandler); + } + +private: + X11ErrorHandler m_previousErrorHandler; +}; + +bool QxtX11ErrorHandler::error = false; + +class QxtX11Data { +public: + QxtX11Data() + { +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + m_display = QX11Info::display(); +#else + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + void *display = native->nativeResourceForScreen(QByteArray("display"), + QGuiApplication::primaryScreen()); + m_display = reinterpret_cast<Display *>(display); +#endif + } + + bool isValid() + { + return m_display != 0; + } + + Display *display() + { + Q_ASSERT(isValid()); + return m_display; + } + + Window rootWindow() + { + return DefaultRootWindow(display()); + } + + bool grabKey(quint32 keycode, quint32 modifiers, Window window) + { + QxtX11ErrorHandler errorHandler; + + for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) { + XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True, + GrabModeAsync, GrabModeAsync); + } + + if (errorHandler.error) { + ungrabKey(keycode, modifiers, window); + return false; + } + + return true; + } + + bool ungrabKey(quint32 keycode, quint32 modifiers, Window window) + { + QxtX11ErrorHandler errorHandler; + + foreach (quint32 maskMods, maskModifiers) { + XUngrabKey(display(), keycode, modifiers | maskMods, window); + } + + return !errorHandler.error; + } + +private: + Display *m_display; +}; + +} // namespace + +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) +bool QxtGlobalShortcutPrivate::eventFilter(void *message) +{ + XEvent *event = static_cast<XEvent *>(message); + if (event->type == KeyPress) + { + XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event); + unsigned int keycode = key->keycode; + unsigned int keystate = key->state; +#else +bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, + void *message, long *result) +{ + Q_UNUSED(result); + + xcb_key_press_event_t *kev = 0; + if (eventType == "xcb_generic_event_t") { + xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); + if ((ev->response_type & 127) == XCB_KEY_PRESS) + kev = static_cast<xcb_key_press_event_t *>(message); + } + + if (kev != 0) { + unsigned int keycode = kev->detail; + unsigned int keystate = 0; + if(kev->state & XCB_MOD_MASK_1) + keystate |= Mod1Mask; + if(kev->state & XCB_MOD_MASK_CONTROL) + keystate |= ControlMask; + if(kev->state & XCB_MOD_MASK_4) + keystate |= Mod4Mask; + if(kev->state & XCB_MOD_MASK_SHIFT) + keystate |= ShiftMask; +#endif + activateShortcut(keycode, + // Mod1Mask == Alt, Mod4Mask == Meta + keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); + } + return false; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= ShiftMask; + if (modifiers & Qt::ControlModifier) + native |= ControlMask; + if (modifiers & Qt::AltModifier) + native |= Mod1Mask; + if (modifiers & Qt::MetaModifier) + native |= Mod4Mask; + + // TODO: resolve these? + //if (modifiers & Qt::MetaModifier) + //if (modifiers & Qt::KeypadModifier) + //if (modifiers & Qt::GroupSwitchModifier) + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + QxtX11Data x11; + if (!x11.isValid()) + return 0; + + KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); + if (keysym == NoSymbol) + keysym = static_cast<ushort>(key); + + return XKeysymToKeycode(x11.display(), keysym); +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtX11Data x11; + return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow()); +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtX11Data x11; + return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow()); +} diff --git a/qxt-mini/qxtglobalshortcut.cpp b/qxt-mini/qxtglobalshortcut.cpp index 8515a6b2..45576d37 100644 --- a/qxt-mini/qxtglobalshortcut.cpp +++ b/qxt-mini/qxtglobalshortcut.cpp @@ -1,224 +1,224 @@ -#include "qxtglobalshortcut.h"
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#include "qxtglobalshortcut_p.h"
-#include <QAbstractEventDispatcher>
-#include <QtDebug>
-
-#ifndef Q_OS_MAC
-int QxtGlobalShortcutPrivate::ref = 0;
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
-QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
-# endif
-#endif // Q_OS_MAC
-QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
-
-QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
-{
-#ifndef Q_OS_MAC
- if (ref == 0) {
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
-# else
- QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
-#endif
- }
- ++ref;
-#endif // Q_OS_MAC
-}
-
-QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
-{
-#ifndef Q_OS_MAC
- --ref;
- if (ref == 0) {
- QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
- if (ed != 0) {
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- ed->setEventFilter(prevEventFilter);
-# else
- ed->removeNativeEventFilter(this);
-# endif
- }
- }
-#endif // Q_OS_MAC
-}
-
-bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
-{
- if (shortcut.toString() == "") return false;
- Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
- key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
- mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- const bool res = registerShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
- else
- qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
- return res;
-}
-
-bool QxtGlobalShortcutPrivate::unsetShortcut()
-{
- bool res = false;
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p())
- res = unregisterShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.remove(qMakePair(nativeKey, nativeMods));
- else
- qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
- key = Qt::Key(0);
- mods = Qt::KeyboardModifiers(0);
- return res;
-}
-
-void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
- if (shortcut && shortcut->isEnabled())
- emit shortcut->activated();
-}
-
-/*!
- \class QxtGlobalShortcut
- \inmodule QxtWidgets
- \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
-
- A global shortcut triggers even if the application is not active. This
- makes it easy to implement applications that react to certain shortcuts
- still if some other application is active or if the application is for
- example minimized to the system tray.
-
- Example usage:
- \code
- QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
- connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
- shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
- \endcode
-
- \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
- */
-
-/*!
- \fn QxtGlobalShortcut::activated()
-
- This signal is emitted when the user types the shortcut's key sequence.
-
- \sa shortcut
- */
-
-/*!
- Constructs a new QxtGlobalShortcut with \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
-}
-
-/*!
- Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
- */
-QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
- : QObject(parent)
-{
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
- setShortcut(shortcut);
-}
-
-/*!
- Destructs the QxtGlobalShortcut.
- */
-QxtGlobalShortcut::~QxtGlobalShortcut()
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
-}
-
-/*!
- \property QxtGlobalShortcut::shortcut
- \brief the shortcut key sequence
-
- \bold {Note:} Notice that corresponding key press and release events are not
- delivered for registered global shortcuts even if they are disabled.
- Also, comma separated key sequences are not supported.
- Only the first part is used:
-
- \code
- qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
- Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
- \endcode
- */
-QKeySequence QxtGlobalShortcut::shortcut() const
-{
- return QKeySequence(qxt_d().key | qxt_d().mods);
-}
-
-bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
-{
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
- return qxt_d().setShortcut(shortcut);
-}
-
-/*!
- \property QxtGlobalShortcut::enabled
- \brief whether the shortcut is enabled
-
- A disabled shortcut does not get activated.
-
- The default value is \c true.
-
- \sa setDisabled()
- */
-bool QxtGlobalShortcut::isEnabled() const
-{
- return qxt_d().enabled;
-}
-
-void QxtGlobalShortcut::setEnabled(bool enabled)
-{
- qxt_d().enabled = enabled;
-}
-
-/*!
- Sets the shortcut \a disabled.
-
- \sa enabled
- */
-void QxtGlobalShortcut::setDisabled(bool disabled)
-{
- qxt_d().enabled = !disabled;
-}
+#include "qxtglobalshortcut.h" +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** <http://libqxt.org> <foundation@libqxt.org> +*****************************************************************************/ + +#include "qxtglobalshortcut_p.h" +#include <QAbstractEventDispatcher> +#include <QtDebug> + +#ifndef Q_OS_MAC +int QxtGlobalShortcutPrivate::ref = 0; +# if QT_VERSION < QT_VERSION_CHECK(5,0,0) +QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0; +# endif +#endif // Q_OS_MAC +QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; + +QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) +{ +#ifndef Q_OS_MAC + if (ref == 0) { +# if QT_VERSION < QT_VERSION_CHECK(5,0,0) + prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); +# else + QAbstractEventDispatcher::instance()->installNativeEventFilter(this); +#endif + } + ++ref; +#endif // Q_OS_MAC +} + +QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate() +{ +#ifndef Q_OS_MAC + --ref; + if (ref == 0) { + QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance(); + if (ed != 0) { +# if QT_VERSION < QT_VERSION_CHECK(5,0,0) + ed->setEventFilter(prevEventFilter); +# else + ed->removeNativeEventFilter(this); +# endif + } + } +#endif // Q_OS_MAC +} + +bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut) +{ + if (shortcut.toString() == "") return false; + Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; + key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]); + mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods); + const quint32 nativeKey = nativeKeycode(key); + const quint32 nativeMods = nativeModifiers(mods); + const bool res = registerShortcut(nativeKey, nativeMods); + if (res) + shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p()); + else + qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString(); + return res; +} + +bool QxtGlobalShortcutPrivate::unsetShortcut() +{ + bool res = false; + const quint32 nativeKey = nativeKeycode(key); + const quint32 nativeMods = nativeModifiers(mods); + if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p()) + res = unregisterShortcut(nativeKey, nativeMods); + if (res) + shortcuts.remove(qMakePair(nativeKey, nativeMods)); + else + qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString(); + key = Qt::Key(0); + mods = Qt::KeyboardModifiers(0); + return res; +} + +void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); + if (shortcut && shortcut->isEnabled()) + emit shortcut->activated(); +} + +/*! + \class QxtGlobalShortcut + \inmodule QxtWidgets + \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey". + + A global shortcut triggers even if the application is not active. This + makes it easy to implement applications that react to certain shortcuts + still if some other application is active or if the application is for + example minimized to the system tray. + + Example usage: + \code + QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window); + connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility())); + shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12")); + \endcode + + \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication. + */ + +/*! + \fn QxtGlobalShortcut::activated() + + This signal is emitted when the user types the shortcut's key sequence. + + \sa shortcut + */ + +/*! + Constructs a new QxtGlobalShortcut with \a parent. + */ +QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent) + : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtGlobalShortcut); +} + +/*! + Constructs a new QxtGlobalShortcut with \a shortcut and \a parent. + */ +QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent) + : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtGlobalShortcut); + setShortcut(shortcut); +} + +/*! + Destructs the QxtGlobalShortcut. + */ +QxtGlobalShortcut::~QxtGlobalShortcut() +{ + if (qxt_d().key != 0) + qxt_d().unsetShortcut(); +} + +/*! + \property QxtGlobalShortcut::shortcut + \brief the shortcut key sequence + + \bold {Note:} Notice that corresponding key press and release events are not + delivered for registered global shortcuts even if they are disabled. + Also, comma separated key sequences are not supported. + Only the first part is used: + + \code + qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B")); + Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A")); + \endcode + */ +QKeySequence QxtGlobalShortcut::shortcut() const +{ + return QKeySequence(qxt_d().key | qxt_d().mods); +} + +bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut) +{ + if (qxt_d().key != 0) + qxt_d().unsetShortcut(); + return qxt_d().setShortcut(shortcut); +} + +/*! + \property QxtGlobalShortcut::enabled + \brief whether the shortcut is enabled + + A disabled shortcut does not get activated. + + The default value is \c true. + + \sa setDisabled() + */ +bool QxtGlobalShortcut::isEnabled() const +{ + return qxt_d().enabled; +} + +void QxtGlobalShortcut::setEnabled(bool enabled) +{ + qxt_d().enabled = enabled; +} + +/*! + Sets the shortcut \a disabled. + + \sa enabled + */ +void QxtGlobalShortcut::setDisabled(bool disabled) +{ + qxt_d().enabled = !disabled; +} diff --git a/qxt-mini/qxtglobalshortcut.h b/qxt-mini/qxtglobalshortcut.h index a81942d2..641c07c9 100644 --- a/qxt-mini/qxtglobalshortcut.h +++ b/qxt-mini/qxtglobalshortcut.h @@ -1,64 +1,64 @@ -#ifndef QXTGLOBALSHORTCUT_H
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#define QXTGLOBALSHORTCUT_H
-
-#include "qxtglobal.h"
-#include <QObject>
-#include <QKeySequence>
-class QxtGlobalShortcutPrivate;
-
-class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject
-{
- Q_OBJECT
- QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
-
-public:
- explicit QxtGlobalShortcut(QObject* parent = 0);
- explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
- virtual ~QxtGlobalShortcut();
-
- QKeySequence shortcut() const;
- bool setShortcut(const QKeySequence& shortcut);
-
- bool isEnabled() const;
-
-public Q_SLOTS:
- void setEnabled(bool enabled = true);
- void setDisabled(bool disabled = true);
-
-Q_SIGNALS:
- void activated();
-};
-
-#endif // QXTGLOBALSHORTCUT_H
+#ifndef QXTGLOBALSHORTCUT_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** <http://libqxt.org> <foundation@libqxt.org> +*****************************************************************************/ + +#define QXTGLOBALSHORTCUT_H + +#include "qxtglobal.h" +#include <QObject> +#include <QKeySequence> +class QxtGlobalShortcutPrivate; + +class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject +{ + Q_OBJECT + QXT_DECLARE_PRIVATE(QxtGlobalShortcut) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) + +public: + explicit QxtGlobalShortcut(QObject* parent = 0); + explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); + virtual ~QxtGlobalShortcut(); + + QKeySequence shortcut() const; + bool setShortcut(const QKeySequence& shortcut); + + bool isEnabled() const; + +public Q_SLOTS: + void setEnabled(bool enabled = true); + void setDisabled(bool disabled = true); + +Q_SIGNALS: + void activated(); +}; + +#endif // QXTGLOBALSHORTCUT_H diff --git a/x-plane-plugin/plugin.c b/x-plane-plugin/plugin.c index 62c9d6f0..3958c895 100644 --- a/x-plane-plugin/plugin.c +++ b/x-plane-plugin/plugin.c @@ -13,8 +13,6 @@ #include <XPLMCamera.h> #include <XPLMProcessing.h> -#include "ftnoir_tracker_base/ftnoir_tracker_types.h" - #ifndef PLUGIN_API #define PLUGIN_API #endif @@ -23,6 +21,10 @@ #define WINE_SHM_NAME "facetracknoir-wine-shm" #define WINE_MTX_NAME "facetracknoir-wine-mtx" +enum Axis { + TX = 0, TY, TZ, Yaw, Pitch, Roll +}; + typedef struct PortableLockedShm { void* mem; int fd, size; |