diff options
Diffstat (limited to 'FTNoIR_Tracker_SM')
| -rw-r--r-- | FTNoIR_Tracker_SM/FTNoIR_SM_Controls.ui | 272 | ||||
| -rw-r--r-- | FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h | 36 | ||||
| -rw-r--r-- | FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp | 99 | ||||
| -rw-r--r-- | FTNoIR_Tracker_SM/ftnoir_tracker_faceapi_dialog.cpp | 122 | 
4 files changed, 511 insertions, 18 deletions
| diff --git a/FTNoIR_Tracker_SM/FTNoIR_SM_Controls.ui b/FTNoIR_Tracker_SM/FTNoIR_SM_Controls.ui index 2f699672..170a4a46 100644 --- a/FTNoIR_Tracker_SM/FTNoIR_SM_Controls.ui +++ b/FTNoIR_Tracker_SM/FTNoIR_SM_Controls.ui @@ -6,8 +6,8 @@     <rect>
      <x>0</x>
      <y>0</y>
 -    <width>406</width>
 -    <height>160</height>
 +    <width>383</width>
 +    <height>344</height>
     </rect>
    </property>
    <property name="windowTitle">
 @@ -93,6 +93,274 @@      </layout>
     </item>
     <item>
 +    <layout class="QGridLayout" name="gridLayout_2">
 +     <item row="1" column="0">
 +      <widget class="QLabel" name="label_6">
 +       <property name="text">
 +        <string>Roll:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="2" column="0">
 +      <widget class="QLabel" name="label_7">
 +       <property name="text">
 +        <string>Pitch:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="3" column="0">
 +      <widget class="QLabel" name="label_8">
 +       <property name="text">
 +        <string>Yaw:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="1" 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="0" column="1">
 +      <widget class="QLabel" name="label_10">
 +       <property name="text">
 +        <string>Enable Axis:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="4" column="0">
 +      <widget class="QLabel" name="label_12">
 +       <property name="text">
 +        <string>X:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="5" column="0">
 +      <widget class="QLabel" name="label_13">
 +       <property name="text">
 +        <string>Y:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="6" column="0">
 +      <widget class="QLabel" name="label_14">
 +       <property name="text">
 +        <string>Z:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="2" 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="3" 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="3" column="2">
 +      <widget class="QCheckBox" name="chkInvertYaw">
 +       <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="QCheckBox" name="chkInvertPitch">
 +       <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="QCheckBox" name="chkInvertRoll">
 +       <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">
 +      <widget class="QLabel" name="label_11">
 +       <property name="text">
 +        <string>Invert Axis:</string>
 +       </property>
 +      </widget>
 +     </item>
 +     <item row="1" column="3">
 +      <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>
 +     <item row="4" column="1">
 +      <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="5" column="1">
 +      <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="6" column="1">
 +      <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="4" column="2">
 +      <widget class="QCheckBox" name="chkInvertX">
 +       <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="5" column="2">
 +      <widget class="QCheckBox" name="chkInvertY">
 +       <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="6" column="2">
 +      <widget class="QCheckBox" name="chkInvertZ">
 +       <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>
 +   </item>
 +   <item>
      <spacer name="verticalSpacer">
       <property name="orientation">
        <enum>Qt::Vertical</enum>
 diff --git a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h index 5f3eb9b9..e62009f5 100644 --- a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h +++ b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h @@ -55,6 +55,21 @@ private:  	SMMemMap *pMemData;
  	HANDLE hSMMutex;
  	QProcess *faceAPI;
 +
 +	int numTracker;
 +	bool bEnableRoll;
 +	bool bEnablePitch;
 +	bool bEnableYaw;
 +	bool bEnableX;
 +	bool bEnableY;
 +	bool bEnableZ;
 +
 +	double dInvertRoll;
 +	double dInvertPitch;
 +	double dInvertYaw;
 +	double dInvertX;
 +	double dInvertY;
 +	double dInvertZ;
  };
  // Widget that has controls for SMoIR protocol client-settings.
 @@ -68,8 +83,12 @@ public:  	void showEvent ( QShowEvent * event );
      void Initialize(QWidget *parent, int numTracker);
 -	void registerTracker(ITracker *tracker) {};
 -	void unRegisterTracker() {};
 +	void registerTracker(ITracker *tracker) {
 +		theTracker = (FTNoIR_Tracker *) tracker;			// Accept the pointer to the Tracker
 +	};
 +	void unRegisterTracker() {
 +		theTracker = NULL;									// Reset the pointer
 +	};
  private:
  	Ui::UICSMClientControls ui;
 @@ -92,6 +111,16 @@ private:      smEngineHandle *engine_handle;
  	QTimer *timUpdateSettings;								// Timer to display current settings
 +	FTNoIR_Tracker *theTracker;
 +	int numTracker;											// Primary (1) or secondary tracker (2)
 +
 +	int numRoll;											// Number of Tracker (1 or 2) which tracks this axis
 +	int numPitch;
 +	int numYaw;
 +	int numX;
 +	int numY;
 +	int numZ;
 +
  private slots:
  	void doOK();
  	void doCancel();
 @@ -110,6 +139,9 @@ private slots:  	void doSetFilter(int value){
  		doCommand(FT_SM_SET_PAR_FILTER, value);
  	}
 +	void settingChanged(int dummy) { 
 +		settingsDirty = true;
 +	};
  signals:
       void stateChanged(int newState);
 diff --git a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp index b04c856b..23b973cb 100644 --- a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp +++ b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp @@ -36,13 +36,28 @@ FTNoIR_Tracker::~FTNoIR_Tracker()  	if ( pMemData != NULL ) {
  		UnmapViewOfFile ( pMemData );
  	}
 +
 +	numTracker = 1;
 +	bEnableRoll = true;
 +	bEnablePitch = true;
 +	bEnableYaw = true;
 +	bEnableX = true;
 +	bEnableY = true;
 +	bEnableZ = true;
 +
 +	dInvertRoll = 1.0f;
 +	dInvertPitch = 1.0f;
 +	dInvertYaw = 1.0f;
 +	dInvertX = 1.0f;
 +	dInvertY = 1.0f;
 +	dInvertZ = 1.0f;
  	CloseHandle( hSMMutex );
  	CloseHandle( hSMMemMap );
  	hSMMemMap = 0;
  }
 -void FTNoIR_Tracker::Initialize( QFrame *videoframe, int numTracker )
 +void FTNoIR_Tracker::Initialize( QFrame *videoframe, int num)
  {
  	qDebug() << "FTNoIR_Tracker::Initialize says: Starting ";
 @@ -53,11 +68,17 @@ void FTNoIR_Tracker::Initialize( QFrame *videoframe, int numTracker )  		QMessageBox::warning(0,"FaceTrackNoIR Error","Memory mapping not created!",QMessageBox::Ok,QMessageBox::NoButton);
  	}
 +	numTracker = num;
  	loadSettings();
  	if ( pMemData != NULL ) {
 -		pMemData->command = 0;						// Reset any and all commands
 -		pMemData->handle = videoframe->winId();		// Handle of Videoframe widget
 +		pMemData->command = 0;							// Reset any and all commands
 +		if (videoframe != NULL) {
 +			pMemData->handle = videoframe->winId();		// Handle of Videoframe widget
 +		}
 +		else {
 +			pMemData->handle = NULL;					// reset Handle of Videoframe widget
 +		}
  	}
  	//
 @@ -70,7 +91,9 @@ void FTNoIR_Tracker::Initialize( QFrame *videoframe, int numTracker )  	// Show the video widget
  	qDebug() << "FTNoIR_Tracker::Initialize says: videoframe = " << videoframe;
 -	videoframe->show();
 +	if (videoframe != NULL) {
 +		videoframe->show();
 +	}
  	return;
  }
 @@ -110,12 +133,24 @@ bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)  		//
  		// Copy the measurements to FaceTrackNoIR.
  		//
 -		data->x     = pMemData->data.new_pose.head_pos.x * 100.0f;					// From meters to centimeters
 -		data->y     = pMemData->data.new_pose.head_pos.y * 100.0f;
 -		data->z     = pMemData->data.new_pose.head_pos.z * 100.0f;
 -		data->yaw   = pMemData->data.new_pose.head_rot.y_rads * 57.295781f;			// From rads to degrees
 -		data->pitch = pMemData->data.new_pose.head_rot.x_rads * 57.295781f;
 -		data->roll  = pMemData->data.new_pose.head_rot.z_rads * 57.295781f;
 +		if (bEnableX) {
 +			data->x     = dInvertX * pMemData->data.new_pose.head_pos.x * 100.0f;						// From meters to centimeters
 +		}
 +		if (bEnableY) {
 +			data->y     = dInvertY * pMemData->data.new_pose.head_pos.y * 100.0f;
 +		}
 +		if (bEnableZ) {
 +			data->z     = dInvertZ * pMemData->data.new_pose.head_pos.z * 100.0f;
 +		}
 +		if (bEnableYaw) {
 +			data->yaw   = dInvertYaw * pMemData->data.new_pose.head_rot.y_rads * 57.295781f;			// From rads to degrees
 +		}
 +		if (bEnablePitch) {
 +			data->pitch = dInvertPitch * pMemData->data.new_pose.head_rot.x_rads * 57.295781f;
 +		}
 +		if (bEnableRoll) {
 +			data->roll  = dInvertRoll * pMemData->data.new_pose.head_rot.z_rads * 57.295781f;
 +		}
  		//
  		// Reset the handshake, to let faceAPI know we're still here!
 @@ -132,6 +167,12 @@ bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)  // Load the current Settings from the currently 'active' INI-file.
  //
  void FTNoIR_Tracker::loadSettings() {
 +int numRoll;											// Number of Tracker (1 or 2) which tracks this axis
 +int numPitch;
 +int numYaw;
 +int numX;
 +int numY;
 +int numZ;
  	qDebug() << "FTNoIR_Tracker::loadSettings says: Starting ";
  	QSettings settings("Abbequerque Inc.", "FaceTrackNoIR");	// Registry settings (in HK_USER)
 @@ -145,7 +186,45 @@ void FTNoIR_Tracker::loadSettings() {  	if (pMemData) {
  		pMemData->initial_filter_level = iniFile.value ( "FilterLevel", 1 ).toInt();
  	}
 +	dInvertRoll = (iniFile.value ( "InvertRoll", 0 ).toBool()) ? -1.0f : 1.0f;
 +	dInvertPitch = (iniFile.value ( "InvertPitch", 0 ).toBool()) ? -1.0f : 1.0f;
 +	dInvertYaw = (iniFile.value ( "InvertYaw", 0 ).toBool()) ? -1.0f : 1.0f;
 +	dInvertX = (iniFile.value ( "InvertX", 0 ).toBool()) ? -1.0f : 1.0f;
 +	dInvertY = (iniFile.value ( "InvertY", 0 ).toBool()) ? -1.0f : 1.0f;
 +	dInvertZ = (iniFile.value ( "InvertZ", 0 ).toBool()) ? -1.0f : 1.0f;
 +
 +	iniFile.endGroup ();
 +
 +	iniFile.beginGroup ( "HeadTracker" );
 +	//
 +	// Check if the Tracker is the Primary one.
 +	// If the property is not found in the INI-file, set the value.
 +	//
 +	if (numTracker == 1) {
 +		numRoll = iniFile.value ( "RollTracker", 1 ).toInt();
 +		numPitch = iniFile.value ( "PitchTracker", 1 ).toInt();
 +		numYaw = iniFile.value ( "YawTracker", 1 ).toInt();
 +		numX = iniFile.value ( "XTracker", 0 ).toInt();
 +		numY = iniFile.value ( "YTracker", 0 ).toInt();
 +		numZ = iniFile.value ( "ZTracker", 0 ).toInt();
 +	}
 +	else {
 +		numRoll = iniFile.value ( "RollTracker", 0 ).toInt();
 +		numPitch = iniFile.value ( "PitchTracker", 0 ).toInt();
 +		numYaw = iniFile.value ( "YawTracker", 0 ).toInt();
 +		numX = iniFile.value ( "XTracker", 0 ).toInt();
 +		numY = iniFile.value ( "YTracker", 0 ).toInt();
 +		numZ = iniFile.value ( "ZTracker", 0 ).toInt();
 +	}
 +	bEnableRoll = (numRoll == numTracker);
 +	bEnablePitch = (numPitch == numTracker);
 +	bEnableYaw = (numYaw == numTracker);
 +	bEnableX = (numX == numTracker);
 +	bEnableY = (numY == numTracker);
 +	bEnableZ = (numZ == numTracker);
 +
  	iniFile.endGroup ();
 +
  }
  //
 diff --git a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi_dialog.cpp b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi_dialog.cpp index e04af2f7..f9d1047f 100644 --- a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi_dialog.cpp +++ b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi_dialog.cpp @@ -37,6 +37,8 @@ QWidget()  {
  	ui.setupUi( this );
 +	theTracker = NULL;
 +
  	// Connect Qt signals to member-functions
  	connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
  	connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
 @@ -56,15 +58,26 @@ QWidget()  		QMessageBox::warning(0,"FaceTrackNoIR Error","Memory mapping not created!",QMessageBox::Ok,QMessageBox::NoButton);
  	}
 -	// Load the settings from the current .INI-file
 -	loadSettings();
 -
  	//Setup the timer for showing the headpose.
  	timUpdateSettings = new QTimer(this);
      connect(timUpdateSettings, SIGNAL(timeout()), this, SLOT(doTimUpdate()));
  	timUpdateSettings->start(100);
  	connect(this, SIGNAL(stateChanged( int )), this, SLOT(showSettings( int )));
 +	connect(ui.chkInvertRoll, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkInvertPitch, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkInvertYaw, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkInvertX, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkInvertY, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkInvertZ, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +
 +	connect(ui.chkEnableRoll, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkEnablePitch, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkEnableYaw, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkEnableX, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkEnableY, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +	connect(ui.chkEnableZ, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
 +
  }
  //
 @@ -77,12 +90,17 @@ TrackerControls::~TrackerControls() {  //
  // Initialize tracker-client-dialog
  //
 -void TrackerControls::Initialize(QWidget *parent, int numTracker) {
 +void TrackerControls::Initialize(QWidget *parent, int num) {
  	QPoint offsetpos(200, 200);
  	if (parent) {
  		this->move(parent->pos() + offsetpos);
  	}
 +
 +	// Load the settings from the current .INI-file
 +	numTracker = num;
 +	loadSettings();
 +
  	show();
  }
 @@ -147,6 +165,42 @@ void TrackerControls::loadSettings() {  	iniFile.beginGroup ( "SMTracker" );
  	ui.cbxFilterSetting->setCurrentIndex(iniFile.value ( "FilterLevel", 1 ).toInt());
 +	ui.chkInvertRoll->setChecked(iniFile.value ( "InvertRoll", 0 ).toBool());
 +	ui.chkInvertPitch->setChecked(iniFile.value ( "InvertPitch", 0 ).toBool());
 +	ui.chkInvertYaw->setChecked(iniFile.value ( "InvertYaw", 0 ).toBool());
 +	ui.chkInvertX->setChecked(iniFile.value ( "InvertX", 0 ).toBool());
 +	ui.chkInvertY->setChecked(iniFile.value ( "InvertY", 0 ).toBool());
 +	ui.chkInvertZ->setChecked(iniFile.value ( "InvertZ", 0 ).toBool());
 +
 +	iniFile.endGroup ();
 +
 +	iniFile.beginGroup ( "HeadTracker" );
 +	//
 +	// Check if the Tracker is the Primary one.
 +	// If the property is not found in the INI-file, set the value.
 +	//
 +	if (numTracker == 1) {
 +		numRoll = iniFile.value ( "RollTracker", 1 ).toInt();
 +		numPitch = iniFile.value ( "PitchTracker", 1 ).toInt();
 +		numYaw = iniFile.value ( "YawTracker", 1 ).toInt();
 +		numX = iniFile.value ( "XTracker", 0 ).toInt();
 +		numY = iniFile.value ( "YTracker", 0 ).toInt();
 +		numZ = iniFile.value ( "ZTracker", 0 ).toInt();
 +	}
 +	else {
 +		numRoll = iniFile.value ( "RollTracker", 0 ).toInt();
 +		numPitch = iniFile.value ( "PitchTracker", 0 ).toInt();
 +		numYaw = iniFile.value ( "YawTracker", 0 ).toInt();
 +		numX = iniFile.value ( "XTracker", 0 ).toInt();
 +		numY = iniFile.value ( "YTracker", 0 ).toInt();
 +		numZ = iniFile.value ( "ZTracker", 0 ).toInt();
 +	}
 +	ui.chkEnableRoll->setChecked(numRoll == numTracker);
 +	ui.chkEnablePitch->setChecked(numPitch == numTracker);
 +	ui.chkEnableYaw->setChecked(numYaw == numTracker);
 +	ui.chkEnableX->setChecked(numX == numTracker);
 +	ui.chkEnableY->setChecked(numY == numTracker);
 +	ui.chkEnableZ->setChecked(numZ == numTracker);
  	iniFile.endGroup ();
  	settingsDirty = false;
 @@ -164,6 +218,66 @@ void TrackerControls::save() {  	iniFile.beginGroup ( "SMTracker" );
  	iniFile.setValue ( "FilterLevel", ui.cbxFilterSetting->currentIndex() );
 +	iniFile.setValue ( "InvertRoll", ui.chkInvertRoll->isChecked() );
 +	iniFile.setValue ( "InvertPitch", ui.chkInvertPitch->isChecked() );
 +	iniFile.setValue ( "InvertYaw", ui.chkInvertYaw->isChecked() );
 +	iniFile.setValue ( "InvertX", ui.chkInvertX->isChecked() );
 +	iniFile.setValue ( "InvertY", ui.chkInvertY->isChecked() );
 +	iniFile.setValue ( "InvertZ", ui.chkInvertZ->isChecked() );
 +	iniFile.endGroup ();
 +
 +	iniFile.beginGroup ( "HeadTracker" );
 +	if ( ui.chkEnableRoll->isChecked() ) {
 +		iniFile.setValue ( "RollTracker", numTracker );
 +	}
 +	else {
 +		if (numRoll == numTracker) {
 +			iniFile.setValue ( "RollTracker", 0 );
 +		}
 +	}
 +
 +	if ( ui.chkEnablePitch->isChecked() ) {
 +		iniFile.setValue ( "PitchTracker", numTracker );
 +	}
 +	else {
 +		if (numPitch == numTracker) {
 +			iniFile.setValue ( "PitchTracker", 0 );
 +		}
 +	}
 +
 +	if ( ui.chkEnableYaw->isChecked() ) {
 +		iniFile.setValue ( "YawTracker", numTracker );
 +	}
 +	else {
 +		if (numYaw == numTracker) {
 +			iniFile.setValue ( "YawTracker", 0 );
 +		}
 +	}
 +	if ( ui.chkEnableX->isChecked() ) {
 +		iniFile.setValue ( "XTracker", numTracker );
 +	}
 +	else {
 +		if (numX == numTracker) {
 +			iniFile.setValue ( "XTracker", 0 );
 +		}
 +	}
 +	if ( ui.chkEnableY->isChecked() ) {
 +		iniFile.setValue ( "YTracker", numTracker );
 +	}
 +	else {
 +		if (numY == numTracker) {
 +			iniFile.setValue ( "YTracker", 0 );
 +		}
 +	}
 +	if ( ui.chkEnableZ->isChecked() ) {
 +		iniFile.setValue ( "ZTracker", numTracker );
 +	}
 +	else {
 +		if (numZ == numTracker) {
 +			iniFile.setValue ( "ZTracker", 0 );
 +		}
 +	}
 +
  	iniFile.endGroup ();
  	settingsDirty = false;
 | 
