/******************************************************************************** * 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 . * * * ********************************************************************************/ /** * This file is part of libfreespace-examples. * * Copyright (c) 2009-2012, Hillcrest Laboratories, 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 the Hillcrest Laboratories, 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 * HOLDER 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. */ #include #include #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifdef WIN32 #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #endif // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. #ifndef WINVER // Allow use of features specific to Windows XP or later. #define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif #ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. #define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. #endif #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include #else #include #endif #include "ftnoir_tracker_hillcrest.h" #include "facetracknoir/global-settings.h" static struct freespace_BodyFrame cachedBodyFrame; static void receiveMessageCallback(FreespaceDeviceId id, struct freespace_message* message, void* cookie, int result) { if (result == FREESPACE_SUCCESS && message != NULL && message->messageType == FREESPACE_MESSAGE_BODYFRAME) { cachedBodyFrame = message->bodyFrame; } } static FreespaceDeviceId initializeFreespace() { struct freespace_message message; FreespaceDeviceId device; int numIds; int rc; // Initialize the freespace library rc = freespace_init(); if (rc != FREESPACE_SUCCESS) { qDebug() << "Initialization error" << rc; return -1; } /** --- START EXAMPLE INITIALIZATION OF DEVICE -- **/ rc = freespace_getDeviceList(&device, 1, &numIds); if (numIds == 0) { qDebug() << "freespaceInputThread: Didn't find any device"; return -1; } rc = freespace_openDevice(device); if (rc != FREESPACE_SUCCESS) { qDebug() << "freespaceInputThread: Error opening device" << rc; return -1; } freespace_setReceiveMessageCallback(device, receiveMessageCallback, NULL); rc = freespace_flush(device); if (rc != FREESPACE_SUCCESS) { qDebug() << "freespaceInputThread: Error flushing device" << rc; return -1; } memset(&cachedBodyFrame, 0, sizeof(cachedBodyFrame)); memset(&message, 0, sizeof(message)); if (FREESPACE_SUCCESS == freespace_isNewDevice(device)) { message.messageType = FREESPACE_MESSAGE_DATAMODECONTROLV2REQUEST; message.dataModeControlV2Request.packetSelect = 2; message.dataModeControlV2Request.modeAndStatus |= 0 << 1; } else { message.messageType = FREESPACE_MESSAGE_DATAMODEREQUEST; message.dataModeRequest.enableBodyMotion = 1; message.dataModeRequest.inhibitPowerManager = 1; } rc = freespace_sendMessage(device, &message); if (rc != FREESPACE_SUCCESS) { qDebug() << "freespaceInputThread: Could not send message" << rc; } /** --- END EXAMPLE INITIALIZATION OF DEVICE -- **/ return device; } static void finalizeFreespace(FreespaceDeviceId device) { struct freespace_message message; int rc; if (device != -1) { /** --- START EXAMPLE FINALIZATION OF DEVICE --- **/ memset(&message, 0, sizeof(message)); if (FREESPACE_SUCCESS == freespace_isNewDevice(device)) { message.messageType = FREESPACE_MESSAGE_DATAMODECONTROLV2REQUEST; message.dataModeControlV2Request.packetSelect = 1; } else { message.messageType = FREESPACE_MESSAGE_DATAMODEREQUEST; message.dataModeRequest.enableMouseMovement = 1; } rc = freespace_sendMessage(device, &message); if (rc != FREESPACE_SUCCESS) { qDebug() << "freespaceInputThread: Could not send message" << rc; } freespace_closeDevice(device); } /** --- END EXAMPLE FINALIZATION OF DEVICE --- **/ freespace_exit(); } FTNoIR_Tracker::FTNoIR_Tracker() { device = initializeFreespace(); } FTNoIR_Tracker::~FTNoIR_Tracker() { finalizeFreespace(device); } void FTNoIR_Tracker::StartTracker(QFrame* videoFrame) { loadSettings(); } #define TO_DEG (180. / M_PI / 1e3 / 3.6) bool FTNoIR_Tracker::GiveHeadPoseData(double *data) { if (device != -1) { struct freespace_BodyFrame body; freespace_perform(); body = cachedBodyFrame; if (bEnableYaw) data[Yaw] = body.angularVelZ * TO_DEG; if (bEnablePitch) data[Pitch] = body.angularVelY * TO_DEG; if (bEnableRoll) data[Roll] = body.angularVelX * TO_DEG; } return device != -1; } // // Load the current Settings from the currently 'active' INI-file. // void FTNoIR_Tracker::loadSettings() { qDebug() << "FTNoIR_Tracker::loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "hillcrest-tracker" ); bEnableRoll = iniFile.value ( "EnableRoll", 1 ).toBool(); bEnablePitch = iniFile.value ( "EnablePitch", 1 ).toBool(); bEnableYaw = iniFile.value ( "EnableYaw", 1 ).toBool(); iniFile.endGroup (); } //////////////////////////////////////////////////////////////////////////////// // Factory function that creates instances if the Tracker object. // Export both decorated and undecorated names. // GetTracker - Undecorated name, which can be easily used with GetProcAddress // Win32 API function. // _GetTracker@0 - Common name decoration for __stdcall functions in C language. //#pragma comment(linker, "/export:GetTracker=_GetTracker@0") extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() { return new FTNoIR_Tracker; }