summaryrefslogtreecommitdiffhomepage
path: root/facetracknoir/tracker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'facetracknoir/tracker.cpp')
-rw-r--r--facetracknoir/tracker.cpp1186
1 files changed, 257 insertions, 929 deletions
diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp
index 5396c95b..fbc0bd29 100644
--- a/facetracknoir/tracker.cpp
+++ b/facetracknoir/tracker.cpp
@@ -23,7 +23,6 @@
*********************************************************************************/
/*
Modifications (last one on top):
- 20130201 - WVR: Remove the Protocol, when stopping the Thread.
20121215 - WVR: Fixed crash after message: protocol not installed correctly... by terminating the thread.
20120921 - WVR: Fixed centering when no filter is selected.
20120917 - WVR: Added Mouse-buttons to ShortKeys.
@@ -31,7 +30,7 @@
20120805 - WVR: The FunctionConfig-widget is used to configure the Curves. It was tweaked some more, because the Accela filter now also
uses the Curve(s). ToDo: make the ranges configurable by the user. Development on the Toradex IMU makes us realize, that
a fixed input-range may not be so handy after all..
- 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled ´statically´. Now, a Dir() of the
+ 20120427 - WVR: The Protocol-code was already in separate DLLs, but the ListBox was still filled �statically�. Now, a Dir() of the
EXE-folder is done, to locate Protocol-DLLs. The Icons were also moved to the DLLs
20120317 - WVR: The Filter and Tracker-code was moved to separate DLLs. The calling-method
was changed accordingly.
@@ -67,779 +66,249 @@
1 or (-1).
*/
#include "tracker.h"
-#include "FaceTrackNoIR.h"
-
-// Flags
-bool Tracker::confid = false;
-bool Tracker::do_tracking = true;
-bool Tracker::do_center = false;
-bool Tracker::do_inhibit = false;
-bool Tracker::do_game_zero = false;
-bool Tracker::do_axis_reverse = false;
-
-bool Tracker::setZero = true;
-bool Tracker::setEngineStop = true;
-HANDLE Tracker::hTrackMutex = 0;
-
-bool Tracker::useAxisReverse = false; // Use Axis Reverse
-float Tracker::YawAngle4ReverseAxis = 40.0f; // Axis Reverse settings
-float Tracker::Z_Pos4ReverseAxis = -20.0f;
-float Tracker::Z_PosWhenReverseAxis = 50.0f;
-
-
-T6DOF Tracker::current_camera(0,0,0,0,0,0); // Used for filtering
-T6DOF Tracker::target_camera(0,0,0,0,0,0);
-T6DOF Tracker::new_camera(0,0,0,0,0,0);
-T6DOF Tracker::output_camera(0,0,0,0,0,0); // Position sent to game protocol
-
-THeadPoseDOF Tracker::Pitch("PitchUp", "PitchDown", 50, 180, 50, 90); // One structure for each of 6DOF's
-THeadPoseDOF Tracker::Yaw("Yaw", "", 50, 180);
-THeadPoseDOF Tracker::Roll("Roll", "", 50, 180);
-THeadPoseDOF Tracker::X("X","", 50, 180);
-THeadPoseDOF Tracker::Y("Y","", 50, 180);
-THeadPoseDOF Tracker::Z("Z","", 50, 180);
-
-TShortKey Tracker::CenterKey; // ShortKey to Center headposition
-TShortKey Tracker::StartStopKey; // ShortKey to Start/stop tracking
-TShortKey Tracker::InhibitKey; // ShortKey to inhibit axis while tracking
-TShortKey Tracker::GameZeroKey; // ShortKey to Set Game Zero
-bool Tracker::DisableBeep = false; // Disable beep when center
-//TShortKey Tracker::AxisReverseKey; // ShortKey to start/stop axis reverse while tracking
-
-int Tracker::CenterMouseKey; // ShortKey to Center headposition
-int Tracker::StartStopMouseKey; // ShortKey to Start/stop tracking
-int Tracker::InhibitMouseKey; // ShortKey to inhibit axis while tracking
-int Tracker::GameZeroMouseKey; // ShortKey to Set Game Zero
-
-//ITrackerPtr Tracker::pTracker; // Pointer to Tracker instance (in DLL)
-IProtocolPtr Tracker::pProtocol; // Pointer to Protocol instance (in DLL)
-IFilterPtr Tracker::pFilter; // Pointer to Filter instance (in DLL)
+#include "facetracknoir.h"
+HeadPoseData* GlobalPose = NULL;
/** constructor **/
-Tracker::Tracker( FaceTrackNoIR *parent ) {
-QString libName;
-importGetTracker getIT;
-QLibrary *trackerLib;
-importGetFilter getFilter;
-QLibrary *filterLib;
-importGetProtocol getProtocol;
-QLibrary *protocolLib;
-QFrame *video_frame;
-
- // Retieve the pointer to the parent
+Tracker::Tracker( FaceTrackNoIR *parent ) :
+ confid(false),
+ useAxisReverse(false),
+ YawAngle4ReverseAxis(40),
+ Z_Pos4ReverseAxis(-20.0f),
+ Z_PosWhenReverseAxis(50.0),
+ should_quit(false),
+ do_tracking(true),
+ do_center(false),
+ do_inhibit(false),
+ do_game_zero(false),
+ do_axis_reverse(false),
+ inhibit_rx(false),
+ inhibit_ry(false),
+ inhibit_rz(false),
+ inhibit_tx(false),
+ inhibit_ty(false),
+ inhibit_tz(false)
+{
+ // Retieve the pointer to the parent
mainApp = parent;
-
- // Create events
- m_StopThread = CreateEvent(0, TRUE, FALSE, 0);
- m_WaitThread = CreateEvent(0, TRUE, FALSE, 0);
-
- Tracker::hTrackMutex = CreateMutexA(NULL, false, "HeadPose_mutex");
-
- //
- // Initialize the headpose-data
- //
- Tracker::Yaw.initHeadPoseData();
- Tracker::Pitch.initHeadPoseData();
- Tracker::Roll.initHeadPoseData();
- Tracker::X.initHeadPoseData();
- Tracker::Y.initHeadPoseData();
- Tracker::Z.initHeadPoseData();
-
- //
- // Locate the video-frame, for the DLL
- //
- video_frame = 0;
- video_frame = mainApp->getVideoWidget();
- qDebug() << "Tracker::Tracker VideoFrame = " << video_frame;
-
- //
- // Load the Tracker-engine DLL, get the tracker-class from it and do stuff...
- //
- pTracker = NULL;
- libName = mainApp->getCurrentTrackerName();
- if (!libName.isEmpty()) {
- trackerLib = new QLibrary(libName);
- getIT = (importGetTracker) trackerLib->resolve("GetTracker");
- qDebug() << "Tracker::Tracker libName = " << libName;
-
- if (getIT) {
- ITracker *ptrXyz(getIT()); // Get the Class
- if (ptrXyz)
- {
- pTracker = ptrXyz;
- pTracker->Initialize( video_frame );
- qDebug() << "Tracker::setup Function Resolved!";
- }
- }
- else {
- QMessageBox::warning(0,"FaceTrackNoIR Error", libName + " DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton);
- }
- }
- //
- // Load the Tracker-engine DLL, get the tracker-class from it and do stuff...
- //
- pSecondTracker = NULL;
- libName = mainApp->getSecondTrackerName();
- if ((!libName.isEmpty()) && (libName != "None")) {
- trackerLib = new QLibrary(libName);
- getIT = (importGetTracker) trackerLib->resolve("GetTracker");
-
- if (getIT) {
- ITracker *ptrXyz(getIT()); // Get the Class
- if (ptrXyz)
- {
- pSecondTracker = ptrXyz;
- pSecondTracker->Initialize( NULL );
- qDebug() << "Tracker::setup Function Resolved!";
- }
- }
- else {
- QMessageBox::warning(0,"FaceTrackNoIR Error", libName + " DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton);
- }
- }
-
- //
- // Load the DLL with the protocol-logic and retrieve a pointer to the Protocol-class.
- //
- libName = mainApp->getCurrentProtocolName();
- if (!libName.isEmpty()) {
- protocolLib = new QLibrary(libName);
- getProtocol = (importGetProtocol) protocolLib->resolve("GetProtocol");
- if (getProtocol) {
- IProtocolPtr ptrXyz(getProtocol());
- if (ptrXyz)
- {
- pProtocol = ptrXyz;
- pProtocol->Initialize();
- qDebug() << "Protocol::setup Function Resolved!";
- }
- }
- else {
- QMessageBox::warning(0,"FaceTrackNoIR Error", "Protocol-DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton);
- return;
- }
- }
-
- //
- // Load the DLL with the filter-logic and retrieve a pointer to the Filter-class.
- //
- pFilter = NULL;
- libName = mainApp->getCurrentFilterName();
-
- if ((!libName.isEmpty()) && (libName != "None")) {
- filterLib = new QLibrary(libName);
-
- getFilter = (importGetFilter) filterLib->resolve("GetFilter");
- if (getFilter) {
- IFilterPtr ptrXyz(getFilter());
- if (ptrXyz)
- {
- pFilter = ptrXyz;
- qDebug() << "Filter::setup Function Resolved!";
- }
- }
- else {
- QMessageBox::warning(0,"FaceTrackNoIR Error", "Filter-DLL not loaded",QMessageBox::Ok,QMessageBox::NoButton);
- return;
- }
- }
-
// Load the settings from the INI-file
loadSettings();
+ GlobalPose->Yaw.headPos = 0;
+ GlobalPose->Pitch.headPos = 0;
+ GlobalPose->Roll.headPos = 0;
+ GlobalPose->X.headPos = 0;
+ GlobalPose->Y.headPos = 0;
+ GlobalPose->Z.headPos = 0;
}
-/** destructor empty **/
-Tracker::~Tracker() {
-
- // Stop the Tracker(s)
- if (pTracker) {
- pTracker->StopTracker( true );
- }
- if (pSecondTracker) {
- pSecondTracker->StopTracker( true );
- }
-
- // Trigger thread to stop
- ::SetEvent(m_StopThread);
-
- // Wait until thread finished
- if (isRunning()) {
- ::WaitForSingleObject(m_WaitThread, INFINITE);
- }
-
- //
- // Remove the Tracker
- // 20120615, WVR: As suggested by Stanislaw
- if (pTracker) {
- delete pTracker;
- pTracker = NULL;
- }
- if (pSecondTracker) {
- delete pSecondTracker;
- pSecondTracker = NULL;
- }
-
- //
- // Remove the Protocol
- //
- if (pProtocol) {
- delete pProtocol;
- pProtocol = NULL;
- }
-
- // Close handles
- ::CloseHandle(m_StopThread);
- ::CloseHandle(m_WaitThread);
-
- if (Tracker::hTrackMutex != 0) {
- ::CloseHandle( Tracker::hTrackMutex );
- }
-
-# ifdef USE_DEBUG_CLIENT
- debug_Client->deleteLater(); // Delete Excel protocol-server
-# endif
-
- qDebug() << "Tracker::~Tracker Finished...";
-
+Tracker::~Tracker()
+{
}
-/** setting up the tracker engine **/
-void Tracker::setup() {
- bool DLL_Ok;
-
- // retrieve pointers to the User Interface and the main Application
- if (pTracker) {
- pTracker->StartTracker( mainApp->winId() );
- }
- if (pSecondTracker) {
- pSecondTracker->StartTracker( mainApp->winId() );
- }
-
- //
- // 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) {
-
- DLL_Ok = pProtocol->checkServerInstallationOK( mainApp->winId() );
- if (!DLL_Ok) {
- // Trigger thread to stop
- ::SetEvent(m_StopThread);
- QMessageBox::information(mainApp, "FaceTrackNoIR error", "Protocol is not (correctly) installed!");
- }
- }
-
-# ifdef USE_DEBUG_CLIENT
- DLL_Ok = debug_Client->checkServerInstallationOK( mainApp->winId() ); // Check installation
- if (!DLL_Ok) {
- QMessageBox::information(mainApp, "FaceTrackNoIR error", "Excel Protocol is not (correctly) installed!");
- }
-# endif
-
+static void get_curve(bool inhibitp, bool inhibit_zerop, double pos, double& out, THeadPoseDOF& axis) {
+ if (inhibitp) {
+ if (inhibit_zerop)
+ out = 0;
+ axis.curvePtr->setTrackingActive( true );
+ axis.curvePtrAlt->setTrackingActive( false );
+ }
+ else {
+ bool altp = (pos < 0) && axis.altp;
+ if (altp) {
+ out = axis.invert * axis.curvePtrAlt->getValue(pos);
+ axis.curvePtr->setTrackingActive( false );
+ axis.curvePtrAlt->setTrackingActive( true );
+ }
+ else {
+ out = axis.invert * axis.curvePtr->getValue(pos);
+ axis.curvePtr->setTrackingActive( true );
+ axis.curvePtrAlt->setTrackingActive( false );
+ }
+ }
}
/** QThread run method @override **/
void Tracker::run() {
-/** Direct Input variables **/
-//
-// The DirectX stuff was found here: http://www.directxtutorial.com/tutorial9/e-directinput/dx9e2.aspx
-//
-LPDIRECTINPUT8 din; // the pointer to our DirectInput interface
-LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device
-LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device
-BYTE keystate[256]; // the storage for the key-information
-DIMOUSESTATE mousestate; // the storage for the mouse-information
-HRESULT retAcquire;
-bool lastCenterKey = false; // Remember state, to detect rising edge
-bool lastStartStopKey = false;
-bool lastInhibitKey = false;
-bool lastGameZeroKey = false;
-
-bool lastCenterMouseKey = false; // Remember state, to detect rising edge
-bool lastStartStopMouseKey = false;
-bool lastInhibitMouseKey = false;
-bool lastGameZeroMouseKey = false;
-
-bool waitAxisReverse = false;
-bool waitThroughZero = false;
-double actualYaw = 0.0f;
-double actualZ = 0.0f;
-T6DOF offset_camera(0,0,0,0,0,0);
-T6DOF gamezero_camera(0,0,0,0,0,0);
-T6DOF gameoutput_camera(0,0,0,0,0,0);
-
-bool bInitialCenter1 = true;
-bool bInitialCenter2 = true;
-bool bTracker1Confid = false;
-bool bTracker2Confid = false;
-
- Tracker::do_tracking = true; // Start initially
- Tracker::do_center = false; // Center initially
-
- //
- // Test some Filter-stuff
- //
- if (pFilter) {
- QString filterName;
- //pFilter->getFullName(&filterName);
- //qDebug() << "Tracker::run() FilterName = " << filterName;
- }
-
- //
- // Setup the DirectInput for keyboard strokes
- //
- // create the DirectInput interface
- if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8,
- (void**)&din, NULL) != DI_OK) { // COM stuff, so we'll set it to NULL
- qDebug() << "Tracker::setup DirectInput8 Creation failed!" << GetLastError();
- }
-
- // create the keyboard device
- if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) {
- qDebug() << "Tracker::setup CreateDevice function failed!" << GetLastError();
- }
- // create the mouse device
- din->CreateDevice(GUID_SysMouse, &dinmouse, NULL);
-
- // set the data format to keyboard format
- if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) {
- qDebug() << "Tracker::setup SetDataFormat function failed!" << GetLastError();
- }
- // set the data format to mouse format
- dinmouse->SetDataFormat(&c_dfDIMouse);
-
- // set the control you will have over the keyboard
- if (dinkeyboard->SetCooperativeLevel(mainApp->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) {
- qDebug() << "Tracker::setup SetCooperativeLevel function failed!" << GetLastError();
- }
- // set the control you will have over the mouse
- dinmouse->SetCooperativeLevel(mainApp->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
-
- forever
- {
-
- // Check event for stop thread
- if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0)
- {
- dinkeyboard->Unacquire(); // Unacquire keyboard
- dinkeyboard->Release();
- dinmouse->Unacquire(); // Unacquire mouse
- dinmouse->Release();
- din->Release(); // Release DirectInput
-
- // Set event
- ::SetEvent(m_WaitThread);
- qDebug() << "Tracker::run terminated run()";
- X.curvePtr->setTrackingActive( false );
- Y.curvePtr->setTrackingActive( false );
- Z.curvePtr->setTrackingActive( false );
- Yaw.curvePtr->setTrackingActive( false );
- Pitch.curvePtr->setTrackingActive( false );
- Pitch.curvePtrAlt->setTrackingActive( false );
- Roll.curvePtr->setTrackingActive( false );
-
- return;
- }
+ T6DOF current_camera; // Used for filtering
+ T6DOF target_camera;
+ T6DOF new_camera;
- //
- // Check the mouse
- //
- // get access if we don't have it already
- retAcquire = dinmouse->Acquire();
- if ( (retAcquire != DI_OK) && (retAcquire != S_FALSE) ) {
- qDebug() << "Tracker::run Acquire function failed!" << GetLastError();
- }
- else {
- if (dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate) != DI_OK) {
- qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError();
- }
- else {
- //
- // Check the state of the StartStop MouseKey
- //
- if ( isMouseKeyPressed( &StartStopMouseKey, &mousestate ) && (!lastStartStopMouseKey) ) {
- Tracker::do_tracking = !Tracker::do_tracking;
-
- //
- // To start tracking again and to be at '0', execute Center command too
- //
- if (Tracker::do_tracking) {
- Tracker::confid = false;
- if (pTracker) {
- pTracker->StartTracker( mainApp->winId() );
- }
- if (pSecondTracker) {
- pSecondTracker->StartTracker( mainApp->winId() );
- }
- }
- else {
- if (setEngineStop) { // Only stop engine when option is checked
- if (pTracker) {
- pTracker->StopTracker( false );
- }
- if (pSecondTracker) {
- pSecondTracker->StopTracker( false );
- }
- }
- }
- qDebug() << "Tracker::run() says StartStop pressed, do_tracking =" << Tracker::do_tracking;
- }
- lastStartStopMouseKey = isMouseKeyPressed( &StartStopMouseKey, &mousestate ); // Remember
-
- //
- // Check the state of the Center MouseKey
- //
- if ( isMouseKeyPressed( &CenterMouseKey, &mousestate ) && (!lastCenterMouseKey) ) {
- Tracker::do_center = true;
- qDebug() << "Tracker::run() says Center MouseKey pressed";
- }
- lastCenterMouseKey = isMouseKeyPressed( &CenterMouseKey, &mousestate ); // Remember
-
- //
- // Check the state of the GameZero MouseKey
- //
- if ( isMouseKeyPressed( &GameZeroMouseKey, &mousestate ) && (!lastGameZeroMouseKey) ) {
- Tracker::do_game_zero = true;
- qDebug() << "Tracker::run() says GameZero MouseKey pressed";
- }
- lastGameZeroMouseKey = isMouseKeyPressed( &GameZeroMouseKey, &mousestate ); // Remember
-
- //
- // Check the state of the Inhibit MouseKey
- //
- if ( isMouseKeyPressed( &InhibitMouseKey, &mousestate ) && (!lastInhibitMouseKey) ) {
- Tracker::do_inhibit = !Tracker::do_inhibit;
- qDebug() << "Tracker::run() says Inhibit MouseKey pressed";
- //
- // Execute Center command too, when inhibition ends.
- //
- if (!Tracker::do_inhibit) {
- Tracker::do_center = true;
- }
- }
- lastInhibitMouseKey = isMouseKeyPressed( &InhibitMouseKey, &mousestate ); // Remember
- }
- }
-
- //
- // Check the keyboard
- //
- // get access if we don't have it already
- retAcquire = dinkeyboard->Acquire();
- if ( (retAcquire != DI_OK) && (retAcquire != S_FALSE) ) {
- qDebug() << "Tracker::run Acquire function failed!" << GetLastError();
- }
- else {
- // get the input data
- if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) {
- qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError();
- }
- else {
- //
- // Check the state of the Start/Stop key
- //
- if ( isShortKeyPressed( &StartStopKey, &keystate[0] ) && (!lastStartStopKey) ) {
- Tracker::do_tracking = !Tracker::do_tracking;
-
- //
- // To start tracking again and to be at '0', execute Center command too
- //
- if (Tracker::do_tracking) {
- Tracker::confid = false;
- if (pTracker) {
- pTracker->StartTracker( mainApp->winId() );
- }
- if (pSecondTracker) {
- pSecondTracker->StartTracker( mainApp->winId() );
- }
- }
- else {
- if (setEngineStop) { // Only stop engine when option is checked
- if (pTracker) {
- pTracker->StopTracker( false );
- }
- if (pSecondTracker) {
- pSecondTracker->StopTracker( false );
- }
- }
- }
- qDebug() << "Tracker::run() says StartStop pressed, do_tracking =" << Tracker::do_tracking;
- }
- lastStartStopKey = isShortKeyPressed( &StartStopKey, &keystate[0] ); // Remember
-
- //
- // Check the state of the Center key
- //
- if ( isShortKeyPressed( &CenterKey, &keystate[0] ) && (!lastCenterKey) ) {
- Tracker::do_center = true;
- qDebug() << "Tracker::run() says Center pressed";
- }
- lastCenterKey = isShortKeyPressed( &CenterKey, &keystate[0] ); // Remember
-
- //
- // Check the state of the GameZero key
- //
- if ( isShortKeyPressed( &GameZeroKey, &keystate[0] ) && (!lastGameZeroKey) ) {
- Tracker::do_game_zero = true;
- qDebug() << "Tracker::run() says GameZero pressed";
- }
- lastGameZeroKey = isShortKeyPressed( &GameZeroKey, &keystate[0] ); // Remember
-
- //
- // Check the state of the Inhibit key
- //
- if ( isShortKeyPressed( &InhibitKey, &keystate[0] ) && (!lastInhibitKey) ) {
- Tracker::do_inhibit = !Tracker::do_inhibit;
- qDebug() << "Tracker::run() says Inhibit pressed";
- //
- // Execute Center command too, when inhibition ends.
- //
- if (!Tracker::do_inhibit) {
- Tracker::do_center = true;
- }
- }
- lastInhibitKey = isShortKeyPressed( &InhibitKey, &keystate[0] ); // Remember
- }
- }
-
- //
- // Reset the 'wait' flag. Moving above 90 with the key pressed, will (de-)activate Axis Reverse.
- //
-// qDebug() << "Tracker::run() says actualZ = " << actualZ << ", terwijl Z_Pos4 = " << Z_Pos4ReverseAxis;
- if (useAxisReverse) {
- Tracker::do_axis_reverse = ((fabs(actualYaw) > YawAngle4ReverseAxis) && (actualZ < Z_Pos4ReverseAxis));
- }
- else {
- Tracker::do_axis_reverse = false;
- }
-
-
- if (WaitForSingleObject(Tracker::hTrackMutex, 100) == WAIT_OBJECT_0) {
-
- THeadPoseData newpose;
- newpose.pitch = 0.0f;
- newpose.roll = 0.0f;
- newpose.yaw = 0.0f;
- newpose.x = 0.0f;
- newpose.y = 0.0f;
- newpose.z = 0.0f;
-
- //
- // The second tracker serves as 'secondary'. So if an axis is written by the second tracker it CAN be overwritten by the Primary tracker.
- // This is enforced by the sequence below.
- //
- if (pSecondTracker) {
- bTracker2Confid = pSecondTracker->GiveHeadPoseData(&newpose);
- }
- else {
- bTracker2Confid = false;
- bInitialCenter2 = false;
- }
- if (pTracker) {
- bTracker1Confid = pTracker->GiveHeadPoseData(&newpose);
-// qDebug() << "Tracker::run() says Roll = " << newpose.roll;
- }
- else {
- bTracker1Confid = false;
- bInitialCenter1 = false;
- }
-
- Tracker::confid = (bTracker1Confid || bTracker2Confid);
- if ( Tracker::confid ) {
- addHeadPose(newpose);
- }
-
- //
- // If Center is pressed, copy the current values to the offsets.
- //
- if ((Tracker::do_center) || ((bInitialCenter1 && bTracker1Confid ) || (bInitialCenter2 && bTracker2Confid))) {
-
- if (!DisableBeep) {
- MessageBeep (MB_ICONASTERISK); // Acknowledge the key-press with a beep.
- }
- if (pTracker && bTracker1Confid) {
- pTracker->notifyCenter(); // Send 'center' to the tracker
- bInitialCenter1 = false;
- }
- if (pSecondTracker && bTracker2Confid) {
- pSecondTracker->notifyCenter(); // Send 'center' to the second tracker
- bInitialCenter2 = false;
- }
-
- //
- // Only copy valid values
- //
- if (Tracker::confid) {
-
- offset_camera.x = getSmoothFromList( &X.rawList );
- offset_camera.y = getSmoothFromList( &Y.rawList );
- offset_camera.z = getSmoothFromList( &Z.rawList );
- offset_camera.pitch = getSmoothFromList( &Pitch.rawList );
- offset_camera.yaw = getSmoothFromList( &Yaw.rawList );
- offset_camera.roll = getSmoothFromList( &Roll.rawList );
- }
-
- Tracker::do_center = false;
- }
-
- //
- // If Set Game Zero is pressed, copy the current values to the offsets.
- // Change requested by Stanislaw
- //
- if (Tracker::confid && Tracker::do_game_zero) {
- if (pTracker) {
- if (!pTracker->notifyZeroed())
- gamezero_camera = gameoutput_camera;
- }
-// gamezero_camera = gameoutput_camera;
-
- Tracker::do_game_zero = false;
- }
-
- if (Tracker::do_tracking && Tracker::confid) {
-
- // get values
- target_camera.x = getSmoothFromList( &X.rawList );
- target_camera.y = getSmoothFromList( &Y.rawList );
- target_camera.z = getSmoothFromList( &Z.rawList );
- target_camera.pitch = getSmoothFromList( &Pitch.rawList );
- target_camera.yaw = getSmoothFromList( &Yaw.rawList );
- target_camera.roll = getSmoothFromList( &Roll.rawList );
-// qDebug() << "Tracker::run() says Roll from Smoothing = " << target_camera.roll;
-
- // do the centering
- target_camera = target_camera - offset_camera;
-
- //
- // Use advanced filtering, when a filter was selected.
- //
- if (pFilter) {
- pFilter->FilterHeadPoseData(&current_camera, &target_camera, &new_camera, Tracker::Pitch.newSample);
-// qDebug() << "Tracker::run() says Roll in Filter = " << current_camera.roll << ", Roll to output = " << new_camera.roll;
- }
- else {
- new_camera = target_camera;
-// qDebug() << "Tracker::run() says Roll to output = " << new_camera.roll;
- }
- output_camera.x = X.invert * X.curvePtr->getValue(new_camera.x);
- output_camera.y = Y.invert * Y.curvePtr->getValue(new_camera.y);
- output_camera.z = Z.invert * Z.curvePtr->getValue(new_camera.z);
-
- //
- // Determine, which curve (Up or Down) must be used for Pitch
- //
- bool altp = (new_camera.pitch < 0);
- if (altp) {
- output_camera.pitch = Pitch.invert * Pitch.curvePtrAlt->getValue(new_camera.pitch);
- Pitch.curvePtr->setTrackingActive( false );
- Pitch.curvePtrAlt->setTrackingActive( true );
- }
- else {
- output_camera.pitch = Pitch.invert * Pitch.curvePtr->getValue(new_camera.pitch);
- Pitch.curvePtr->setTrackingActive( true );
- Pitch.curvePtrAlt->setTrackingActive( false );
- }
- output_camera.yaw = Yaw.invert * Yaw.curvePtr->getValue(new_camera.yaw);
- output_camera.roll = Roll.invert * Roll.curvePtr->getValue(new_camera.roll);
-
- X.curvePtr->setTrackingActive( true );
- Y.curvePtr->setTrackingActive( true );
- Z.curvePtr->setTrackingActive( true );
- Yaw.curvePtr->setTrackingActive( true );
- Roll.curvePtr->setTrackingActive( true );
-
- //
- // Reverse Axis.
- //
- actualYaw = output_camera.yaw; // Save the actual Yaw, otherwise we can't check for +90
- actualZ = output_camera.z; // Also the Z
- if (Tracker::do_axis_reverse) {
- output_camera.z = Z_PosWhenReverseAxis; // Set the desired Z-position
- }
-
- //
- // Reset value for the selected axis, if inhibition is active
- //
- if (Tracker::do_inhibit) {
- if (InhibitKey.doPitch) output_camera.pitch = 0.0f;
- if (InhibitKey.doYaw) output_camera.yaw = 0.0f;
- if (InhibitKey.doRoll) output_camera.roll = 0.0f;
- if (InhibitKey.doX) output_camera.x = 0.0f;
- if (InhibitKey.doY) output_camera.y = 0.0f;
- if (InhibitKey.doZ) output_camera.z = 0.0f;
- }
-
- //
- // Send the headpose to the game
- //
- if (pProtocol) {
- gameoutput_camera = output_camera + gamezero_camera;
- pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters
- }
- }
- else {
- //
- // Go to initial position
- //
- if (pProtocol && setZero) {
- output_camera.pitch = 0.0f;
- output_camera.yaw = 0.0f;
- output_camera.roll = 0.0f;
- output_camera.x = 0.0f;
- output_camera.y = 0.0f;
- output_camera.z = 0.0f;
- gameoutput_camera = output_camera + gamezero_camera;
- pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters
- }
- X.curvePtr->setTrackingActive( false );
- Y.curvePtr->setTrackingActive( false );
- Z.curvePtr->setTrackingActive( false );
- Yaw.curvePtr->setTrackingActive( false );
- Pitch.curvePtr->setTrackingActive( false );
- Pitch.curvePtrAlt->setTrackingActive( false );
- Roll.curvePtr->setTrackingActive( false );
- }
- }
-
- Tracker::Pitch.newSample = false;
- ReleaseMutex(Tracker::hTrackMutex);
-
- //for lower cpu load
- usleep(10000);
- yieldCurrentThread();
- }
-}
-
-/** Add the headpose-data to the Lists **/
-void Tracker::addHeadPose( THeadPoseData head_pose )
-{
- // Pitch
- Tracker::Pitch.headPos = head_pose.pitch; // degrees
- addRaw2List ( &Pitch.rawList, Pitch.maxItems, Tracker::Pitch.headPos );
-// Tracker::Pitch.confidence = head_pose.confidence; // Just this one ...
- Tracker::Pitch.newSample = true;
-
- // Yaw
- Tracker::Yaw.headPos = head_pose.yaw; // degrees
- addRaw2List ( &Yaw.rawList, Yaw.maxItems, Tracker::Yaw.headPos );
-
- // Roll
- Tracker::Roll.headPos = head_pose.roll; // degrees
- addRaw2List ( &Roll.rawList, Roll.maxItems, Tracker::Roll.headPos );
-
- // X-position
- Tracker::X.headPos = head_pose.x; // centimeters
- addRaw2List ( &X.rawList, X.maxItems, Tracker::X.headPos );
-
- // Y-position
- Tracker::Y.headPos = head_pose.y; // centimeters
- addRaw2List ( &Y.rawList, Y.maxItems, Tracker::Y.headPos );
-
- // Z-position (distance to camera, absolute!)
- Tracker::Z.headPos = head_pose.z; // centimeters
- addRaw2List ( &Z.rawList, Z.maxItems, Tracker::Z.headPos );
+ /** Direct Input variables **/
+ T6DOF offset_camera;
+ T6DOF gamezero_camera;
+ T6DOF gameoutput_camera;
+
+ bool bTracker1Confid = false;
+ bool bTracker2Confid = false;
+
+ THeadPoseData last;
+
+ forever
+ {
+ if (should_quit)
+ break;
+
+ // Check event for stop thread
+
+ THeadPoseData newpose;
+ newpose.pitch = 0.0f;
+ newpose.roll = 0.0f;
+ newpose.yaw = 0.0f;
+ newpose.x = 0.0f;
+ newpose.y = 0.0f;
+ newpose.z = 0.0f;
+
+ //
+ // The second tracker serves as 'secondary'. So if an axis is written by the second tracker it CAN be overwritten by the Primary tracker.
+ // This is enforced by the sequence below.
+ //
+ if (Libraries->pSecondTracker) {
+ bTracker2Confid = Libraries->pSecondTracker->GiveHeadPoseData(&newpose);
+ }
+
+ if (Libraries->pTracker) {
+ bTracker1Confid = Libraries->pTracker->GiveHeadPoseData(&newpose);
+ }
+
+ confid = (bTracker1Confid || bTracker2Confid);
+
+ bool newp = last.yaw != newpose.yaw ||
+ last.pitch != newpose.pitch ||
+ last.roll != newpose.roll ||
+ last.x != newpose.x ||
+ last.y != newpose.y ||
+ last.z != newpose.z;
+
+ if (newp)
+ last = newpose;
+
+ if ( confid ) {
+ GlobalPose->Yaw.headPos = newpose.yaw;
+ GlobalPose->Pitch.headPos = newpose.pitch;
+ GlobalPose->Roll.headPos = newpose.roll;
+ GlobalPose->X.headPos = newpose.x;
+ GlobalPose->Y.headPos = newpose.y;
+ GlobalPose->Z.headPos = newpose.z;
+ }
+
+ //
+ // If Center is pressed, copy the current values to the offsets.
+ //
+ if (do_center) {
+ //
+ // Only copy valid values
+ //
+ if (Tracker::confid) {
+ offset_camera.x = GlobalPose->X.headPos;
+ offset_camera.y = GlobalPose->Y.headPos;
+ offset_camera.z = GlobalPose->Z.headPos;
+ offset_camera.pitch = GlobalPose->Pitch.headPos;
+ offset_camera.yaw = GlobalPose->Yaw.headPos;
+ offset_camera.roll = GlobalPose->Roll.headPos;
+ }
+
+ Tracker::do_center = false;
+
+ // for kalman
+ if (Libraries->pFilter)
+ Libraries->pFilter->Initialize();
+
+ last = newpose;
+ }
+
+ if (do_game_zero) {
+ gamezero_camera = gameoutput_camera;
+ do_game_zero = false;
+ }
+
+ if (Tracker::do_tracking && Tracker::confid) {
+ // get values
+ target_camera.x = GlobalPose->X.headPos;
+ target_camera.y = GlobalPose->Y.headPos;
+ target_camera.z = GlobalPose->Z.headPos;
+ target_camera.pitch = GlobalPose->Pitch.headPos;
+ target_camera.yaw = GlobalPose->Yaw.headPos;
+ target_camera.roll = GlobalPose->Roll.headPos;
+
+ // do the centering
+ target_camera = target_camera - offset_camera;
+
+ //
+ // Use advanced filtering, when a filter was selected.
+ //
+ if (Libraries->pFilter) {
+ THeadPoseData last_post_filter = gameoutput_camera;
+ Libraries->pFilter->FilterHeadPoseData(&current_camera, &target_camera, &new_camera, &last_post_filter, newp);
+ }
+ else {
+ new_camera = target_camera;
+ }
+
+ get_curve(do_inhibit && inhibit_rx, inhibit_zero, new_camera.yaw, output_camera.yaw, GlobalPose->Yaw);
+ get_curve(do_inhibit && inhibit_ry, inhibit_zero, new_camera.pitch, output_camera.pitch, GlobalPose->Pitch);
+ get_curve(do_inhibit && inhibit_rz, inhibit_zero, new_camera.roll, output_camera.roll, GlobalPose->Roll);
+ get_curve(do_inhibit && inhibit_tx, inhibit_zero, new_camera.x, output_camera.x, GlobalPose->X);
+ get_curve(do_inhibit && inhibit_ty, inhibit_zero, new_camera.y, output_camera.y, GlobalPose->Y);
+ get_curve(do_inhibit && inhibit_tz, inhibit_zero, new_camera.z, output_camera.z, GlobalPose->Z);
+
+ if (useAxisReverse) {
+ do_axis_reverse = ((fabs(output_camera.yaw) > YawAngle4ReverseAxis) && (output_camera.z < Z_Pos4ReverseAxis));
+ } else {
+ do_axis_reverse = false;
+ }
+
+ //
+ // Reverse Axis.
+ //
+ if (Tracker::do_axis_reverse) {
+ output_camera.z = Z_PosWhenReverseAxis; // Set the desired Z-position
+ }
+
+ //
+ // Send the headpose to the game
+ //
+ if (Libraries->pProtocol) {
+ gameoutput_camera = output_camera + gamezero_camera;
+ Libraries->pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters
+ }
+ }
+ else {
+ //
+ // Go to initial position
+ //
+ if (Libraries->pProtocol && inhibit_zero) {
+ output_camera.pitch = 0.0f;
+ output_camera.yaw = 0.0f;
+ output_camera.roll = 0.0f;
+ output_camera.x = 0.0f;
+ output_camera.y = 0.0f;
+ output_camera.z = 0.0f;
+ gameoutput_camera = output_camera + gamezero_camera;
+ Libraries->pProtocol->sendHeadposeToGame( &gameoutput_camera, &newpose ); // degrees & centimeters
+ }
+ GlobalPose->X.curvePtr->setTrackingActive( false );
+ GlobalPose->Y.curvePtr->setTrackingActive( false );
+ GlobalPose->Z.curvePtr->setTrackingActive( false );
+ GlobalPose->Yaw.curvePtr->setTrackingActive( false );
+ GlobalPose->Pitch.curvePtr->setTrackingActive( false );
+ GlobalPose->Pitch.curvePtrAlt->setTrackingActive( false );
+ GlobalPose->Roll.curvePtr->setTrackingActive( false );
+ if (Libraries->pFilter)
+ Libraries->pFilter->Initialize();
+ }
+
+ //for lower cpu load
+ usleep(10000);
+ }
+
+ GlobalPose->X.curvePtr->setTrackingActive( false );
+ GlobalPose->Y.curvePtr->setTrackingActive( false );
+ GlobalPose->Z.curvePtr->setTrackingActive( false );
+ GlobalPose->Yaw.curvePtr->setTrackingActive( false );
+ GlobalPose->Pitch.curvePtr->setTrackingActive( false );
+ GlobalPose->Pitch.curvePtrAlt->setTrackingActive( false );
+ GlobalPose->Roll.curvePtr->setTrackingActive( false );
}
//
@@ -850,8 +319,8 @@ QString str;
char dest[100];
str = QString("No protocol active?");
- if (pProtocol) {
- pProtocol->getNameFromGame( dest );
+ if (Libraries->pProtocol) {
+ Libraries->pProtocol->getNameFromGame( dest );
str = QString( dest );
}
return str;
@@ -877,35 +346,16 @@ bool Tracker::handleGameCommand ( int command ) {
}
//
-// Add the new Raw value to the QList.
-// Remove the last item(s), depending on the set maximum list-items.
-//
-void Tracker::addRaw2List ( QList<float> *rawList, float maxIndex, float raw ) {
- //
- // Remove old values from the end of the QList.
- // If the setting for MaxItems was lowered, the QList is shortened here...
- //
- while (rawList->size() >= maxIndex) {
- rawList->removeLast();
- }
-
- //
- // Insert the newest at the beginning.
- //
- rawList->prepend ( raw );
-}
-
-//
// Get the raw headpose, so it can be displayed.
//
void Tracker::getHeadPose( THeadPoseData *data ) {
- data->x = Tracker::X.headPos; // centimeters
- data->y = Tracker::Y.headPos;
- data->z = Tracker::Z.headPos;
+ data->x = GlobalPose->X.headPos; // centimeters
+ data->y = GlobalPose->Y.headPos;
+ data->z = GlobalPose->Z.headPos;
- data->pitch = Tracker::Pitch.headPos; // degrees
- data->yaw = Tracker::Yaw.headPos;
- data->roll = Tracker::Roll.headPos;
+ data->pitch = GlobalPose->Pitch.headPos; // degrees
+ data->yaw = GlobalPose->Yaw.headPos;
+ data->roll = GlobalPose->Roll.headPos;
}
//
@@ -922,30 +372,9 @@ void Tracker::getOutputHeadPose( THeadPoseData *data ) {
}
//
-// Get the Smoothed value from the QList.
-//
-float Tracker::getSmoothFromList ( QList<float> *rawList ) {
-float sum = 0;
-
- if (rawList->isEmpty()) return 0.0f;
-
- //
- // Add the Raw values and divide.
- //
- for ( int i = 0; i < rawList->size(); i++) {
- sum += rawList->at(i);
- }
- return sum / rawList->size();
-}
-
-//
// Load the current Settings from the currently 'active' INI-file.
//
void Tracker::loadSettings() {
-//int NeutralZone;
-//int sensYaw, sensPitch, sensRoll;
-//int sensX, sensY, sensZ;
-
qDebug() << "Tracker::loadSettings says: Starting ";
QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER)
@@ -954,128 +383,27 @@ void Tracker::loadSettings() {
qDebug() << "loadSettings says: iniFile = " << currentFile;
- //
- // Read the Tracking settings, to fill the curves.
- //
- //iniFile.beginGroup ( "Tracking" );
- //NeutralZone = iniFile.value ( "NeutralZone", 5 ).toInt();
- //sensYaw = iniFile.value ( "sensYaw", 100 ).toInt();
- //sensPitch = iniFile.value ( "sensPitch", 100 ).toInt();
- //sensRoll = iniFile.value ( "sensRoll", 100 ).toInt();
- //sensX = iniFile.value ( "sensX", 100 ).toInt();
- //sensY = iniFile.value ( "sensY", 100 ).toInt();
- //sensZ = iniFile.value ( "sensZ", 100 ).toInt();
- //iniFile.endGroup ();
-
- //
- // Read the keyboard shortcuts.
- //
+ iniFile.beginGroup ( "Tracking" );
+ iniFile.endGroup ();
iniFile.beginGroup ( "KB_Shortcuts" );
-
- // Center key
- CenterMouseKey = iniFile.value ( "MouseKey_Center", 0 ).toInt();
- CenterKey.keycode = iniFile.value ( "Keycode_Center", DIK_HOME ).toInt();
- CenterKey.shift = iniFile.value ( "Shift_Center", 0 ).toBool();
- CenterKey.ctrl = iniFile.value ( "Ctrl_Center", 0 ).toBool();
- CenterKey.alt = iniFile.value ( "Alt_Center", 0 ).toBool();
- DisableBeep = iniFile.value ( "Disable_Beep", 0 ).toBool();
-
- // StartStop key
- StartStopMouseKey = iniFile.value ( "MouseKey_StartStop", 0 ).toInt();
- StartStopKey.keycode = iniFile.value ( "Keycode_StartStop", DIK_END ).toInt();
- StartStopKey.shift = iniFile.value ( "Shift_StartStop", 0 ).toBool();
- StartStopKey.ctrl = iniFile.value ( "Ctrl_StartStop", 0 ).toBool();
- StartStopKey.alt = iniFile.value ( "Alt_StartStop", 0 ).toBool();
- setZero = iniFile.value ( "SetZero", 1 ).toBool();
- setEngineStop = iniFile.value ( "SetEngineStop", 1 ).toBool();
-
- // Inhibit key
- InhibitMouseKey = iniFile.value ( "MouseKey_Inhibit", 0 ).toInt();
- InhibitKey.keycode = iniFile.value ( "Keycode_Inhibit", 0 ).toInt();
- InhibitKey.shift = iniFile.value ( "Shift_Inhibit", 0 ).toBool();
- InhibitKey.ctrl = iniFile.value ( "Ctrl_Inhibit", 0 ).toBool();
- InhibitKey.alt = iniFile.value ( "Alt_Inhibit", 0 ).toBool();
- InhibitKey.doPitch = iniFile.value ( "Inhibit_Pitch", 0 ).toBool();
- InhibitKey.doYaw = iniFile.value ( "Inhibit_Yaw", 0 ).toBool();
- InhibitKey.doRoll = iniFile.value ( "Inhibit_Roll", 0 ).toBool();
- InhibitKey.doX = iniFile.value ( "Inhibit_X", 0 ).toBool();
- InhibitKey.doY = iniFile.value ( "Inhibit_Y", 0 ).toBool();
- InhibitKey.doZ = iniFile.value ( "Inhibit_Z", 0 ).toBool();
-
- // Game Zero key
- GameZeroMouseKey = iniFile.value ( "MouseKey_GameZero", 0 ).toInt();
- GameZeroKey.keycode = iniFile.value ( "Keycode_GameZero", 0 ).toInt();
- GameZeroKey.shift = iniFile.value ( "Shift_GameZero", 0 ).toBool();
- GameZeroKey.ctrl = iniFile.value ( "Ctrl_GameZero", 0 ).toBool();
- GameZeroKey.alt = iniFile.value ( "Alt_GameZero", 0 ).toBool();
-
- // Axis Reverse key
- //AxisReverseKey.keycode = DIK_R;
- //AxisReverseKey.shift = false;
- //AxisReverseKey.ctrl = false;
- //AxisReverseKey.alt = false;
-
- // Reverse Axis
- useAxisReverse = iniFile.value ( "Enable_ReverseAxis", 0 ).toBool();
- YawAngle4ReverseAxis = iniFile.value ( "RA_Yaw", 40 ).toInt();
- Z_Pos4ReverseAxis = iniFile.value ( "RA_ZPos", 50 ).toInt();
- Z_PosWhenReverseAxis = iniFile.value ( "RA_ToZPos", 80 ).toInt();
-
+ // Reverse Axis
+ useAxisReverse = iniFile.value ( "Enable_ReverseAxis", 0 ).toBool();
+ YawAngle4ReverseAxis = iniFile.value ( "RA_Yaw", 40 ).toInt();
+ Z_Pos4ReverseAxis = iniFile.value ( "RA_ZPos", 50 ).toInt();
+ Z_PosWhenReverseAxis = iniFile.value ( "RA_ToZPos", 80 ).toInt();
+ inhibit_rx = iniFile.value("Inhibit_Yaw", false).toBool();
+ inhibit_ry = iniFile.value("Inhibit_Pitch", false).toBool();
+ inhibit_rz = iniFile.value("Inhibit_Roll", false).toBool();
+ inhibit_tx = iniFile.value("Inhibit_X", false).toBool();
+ inhibit_ty = iniFile.value("Inhibit_Y", false).toBool();
+ inhibit_tz = iniFile.value("Inhibit_Z", false).toBool();
+ inhibit_zero = iniFile.value("SetZero", false).toBool();
iniFile.endGroup ();
}
-//
-// Determine if the ShortKey (incl. CTRL, SHIFT and/or ALT) is pressed.
-//
-bool Tracker::isShortKeyPressed( TShortKey *key, BYTE *keystate ){
-bool shift;
-bool ctrl;
-bool alt;
-
- //
- // First, check if the right key is pressed. If so, check the modifiers
- //
- if (keystate[key->keycode] & 0x80) {
- shift = ( (keystate[DIK_LSHIFT] & 0x80) || (keystate[DIK_RSHIFT] & 0x80) );
- 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;
- }
- else {
- return false;
- }
-}
-
-//
-// Determine if the MouseKey is pressed.
-//
-bool Tracker::isMouseKeyPressed( int *key, DIMOUSESTATE *mousestate ){
-
- //
- // If key == NONE, or invalid: ready!
- //
- if ((*key <= 0) || (*key > 5)) {
- return false;
- }
-
- //
- // Now, check if the right key is pressed.
- //
- if (mousestate->rgbButtons[*key-1] & 0x80) {
- return true;
- }
- else {
- return false;
- }
-}
+void Tracker::setInvertPitch(bool invert) { GlobalPose->Pitch.invert = invert?-1.0f:1.0f; }
+void Tracker::setInvertYaw(bool invert) { GlobalPose->Yaw.invert = invert?-1.0f:+1.0f; }
+void Tracker::setInvertRoll(bool invert) { GlobalPose->Roll.invert = invert?-1.0f:+1.0f; }
+void Tracker::setInvertX(bool invert) { GlobalPose->X.invert = invert?-1.0f:+1.0f; }
+void Tracker::setInvertY(bool invert) { GlobalPose->Y.invert = invert?-1.0f:+1.0f; }
+void Tracker::setInvertZ(bool invert) { GlobalPose->Z.invert = invert?-1.0f:+1.0f; }