From 6be2bbea386c0fb98c750927b1ade2c6dd9d3fbe Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 13 Sep 2013 15:02:31 +0200 Subject: Remove per-file version history. Be careful not to touch copyright information. --- qfunctionconfigurator/qfunctionconfigurator.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 304d252e..17905752 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -32,14 +32,6 @@ * provided that the above copyright notice and this permission * * notice appear in all copies. * ********************************************************************************/ -/* - Modifications (last one on top): - 20120830 - WVR: Changed functionality a bit. Now only draw the handles, when the function is drawn. - Only check mouseMoves, when they occur 'in range'. Redraw the curve, when a resize occurs. - Somehow, the curve was not drawn correctly, when this was not done (all points were too high). - After a 'Reset' this would disappear... - 20120828 - WVR: Removed bSkipText, which was used to not show a number below each vertical gridline. -*/ #include "qfunctionconfigurator/qfunctionconfigurator.h" #include #include -- cgit v1.2.3 From c58c0af311892929dbce4e5437c4035214552438 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 15:34:44 +0200 Subject: Run dos2unix on the tree. No user-facing changes. --- faceapi/build_options.h | 16 +- faceapi/lock.h | 70 +- faceapi/lockfree.h | 130 +- faceapi/main.cpp | 1058 +++---- faceapi/mutex.h | 92 +- faceapi/stdafx.cpp | 16 +- faceapi/stdafx.h | 72 +- faceapi/utils.h | 698 ++--- facetracknoir/facetracknoir.cpp | 3126 ++++++++++---------- facetracknoir/facetracknoir.h | 588 ++-- facetracknoir/main.cpp | 114 +- facetracknoir/rotation.h | 128 +- facetracknoir/tracker.cpp | 436 +-- facetracknoir/tracker.h | 290 +- facetracknoir/tracker_types.cpp | 88 +- facetracknoir/tracker_types.h | 82 +- freetrackclient/ftclient.h | 60 +- ftnoir_filter_accela/ftnoir_filter_accela.cpp | 180 +- ftnoir_filter_accela/ftnoir_filter_accela.h | 214 +- .../ftnoir_filter_accela_dialog.cpp | 380 +-- ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp | 78 +- ftnoir_filter_base/ftnoir_filter_base.h | 82 +- ftnoir_filter_base/ftnoir_filter_base_global.h | 24 +- ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp | 346 +-- ftnoir_filter_ewma2/ftnoir_filter_ewma2.h | 232 +- ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp | 396 +-- ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp | 98 +- ftnoir_posewidget/glwidget.cpp | 458 +-- ftnoir_posewidget/glwidget.h | 232 +- ftnoir_protocol_base/ftnoir_protocol_base.h | 150 +- ftnoir_protocol_base/ftnoir_protocol_base_global.h | 24 +- ftnoir_protocol_fg/fgtypes.h | 54 +- ftnoir_protocol_fg/ftnoir_protocol_fg.cpp | 444 +-- ftnoir_protocol_fg/ftnoir_protocol_fg.h | 242 +- ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp | 430 +-- ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp | 98 +- ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp | 410 +-- ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h | 262 +- .../ftnoir_protocol_fsuipc_dialog.cpp | 370 +-- .../ftnoir_protocol_fsuipc_dll.cpp | 98 +- ftnoir_protocol_ft/ftnoir_protocol_ft.cpp | 566 ++-- ftnoir_protocol_ft/ftnoir_protocol_ft.h | 282 +- ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp | 450 +-- ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp | 90 +- ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp | 236 +- ftnoir_protocol_ftn/ftnoir_protocol_ftn.h | 208 +- ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp | 360 +-- ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp | 98 +- ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp | 202 +- ftnoir_protocol_mouse/ftnoir_protocol_mouse.h | 256 +- .../ftnoir_protocol_mouse_dialog.cpp | 362 +-- .../ftnoir_protocol_mouse_dll.cpp | 98 +- ftnoir_protocol_sc/ftnoir_protocol_sc.cpp | 712 ++--- ftnoir_protocol_sc/ftnoir_protocol_sc.h | 352 +-- ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp | 290 +- ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp | 98 +- ftnoir_tracker_base/ftnoir_tracker_base.h | 162 +- ftnoir_tracker_base/ftnoir_tracker_base_global.h | 24 +- ftnoir_tracker_base/ftnoir_tracker_sm_types.h | 72 +- ftnoir_tracker_base/ftnoir_tracker_types.h | 74 +- ftnoir_tracker_pt/camera.cpp | 426 +-- ftnoir_tracker_pt/camera.h | 238 +- ftnoir_tracker_pt/ftnoir_tracker_pt.cpp | 522 ++-- ftnoir_tracker_pt/ftnoir_tracker_pt.h | 192 +- ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp | 674 ++--- ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h | 204 +- ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp | 80 +- ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h | 36 +- ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp | 298 +- ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h | 166 +- ftnoir_tracker_pt/point_extractor.cpp | 192 +- ftnoir_tracker_pt/point_extractor.h | 62 +- ftnoir_tracker_pt/point_tracker.cpp | 704 ++--- ftnoir_tracker_pt/point_tracker.h | 228 +- ftnoir_tracker_pt/resource.h | 28 +- ftnoir_tracker_pt/timer.cpp | 128 +- ftnoir_tracker_pt/timer.h | 86 +- ftnoir_tracker_pt/trans_calib.cpp | 86 +- ftnoir_tracker_pt/trans_calib.h | 76 +- ftnoir_tracker_pt/video_widget.cpp | 104 +- ftnoir_tracker_pt/video_widget.h | 84 +- ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp | 346 +-- .../ftnoir_tracker_faceapi_dialog.cpp | 564 ++-- ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp | 144 +- ftnoir_tracker_sm/ftnoir_tracker_sm.h | 312 +- ftnoir_tracker_udp/ftnoir_tracker_udp.cpp | 346 +-- ftnoir_tracker_udp/ftnoir_tracker_udp.h | 194 +- ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp | 364 +-- ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp | 146 +- qfunctionconfigurator/functionconfig.cpp | 564 ++-- qfunctionconfigurator/functionconfig.h | 156 +- 91 files changed, 12554 insertions(+), 12554 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/faceapi/build_options.h b/faceapi/build_options.h index 6bc6a44c..e298686e 100644 --- a/faceapi/build_options.h +++ b/faceapi/build_options.h @@ -1,8 +1,8 @@ -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Build Options -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//controls whether or not FaceAPI should use the callback or poll -#define USE_HEADPOSE_CALLBACK 1 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Build Options +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//controls whether or not FaceAPI should use the callback or poll +#define USE_HEADPOSE_CALLBACK 1 diff --git a/faceapi/lock.h b/faceapi/lock.h index efe38605..bb095675 100644 --- a/faceapi/lock.h +++ b/faceapi/lock.h @@ -1,35 +1,35 @@ -#ifndef SM_API_TESTAPPCONSOLE_LOCK_H -#define SM_API_TESTAPPCONSOLE_LOCK_H - -#include "mutex.h" - -namespace sm -{ - namespace faceapi - { - namespace samplecode - { - // A very simple scoped-lock class for sample code purposes. - // It is recommended that you use the boost threads library. - class Lock - { - public: - Lock(const Mutex &mutex): _mutex(mutex) - { - _mutex.lock(); - } - ~Lock() - { - _mutex.unlock(); - } - private: - // Noncopyable - Lock(const Lock &); - Lock &operator=(const Lock &); - private: - const Mutex &_mutex; - }; - } - } -} -#endif +#ifndef SM_API_TESTAPPCONSOLE_LOCK_H +#define SM_API_TESTAPPCONSOLE_LOCK_H + +#include "mutex.h" + +namespace sm +{ + namespace faceapi + { + namespace samplecode + { + // A very simple scoped-lock class for sample code purposes. + // It is recommended that you use the boost threads library. + class Lock + { + public: + Lock(const Mutex &mutex): _mutex(mutex) + { + _mutex.lock(); + } + ~Lock() + { + _mutex.unlock(); + } + private: + // Noncopyable + Lock(const Lock &); + Lock &operator=(const Lock &); + private: + const Mutex &_mutex; + }; + } + } +} +#endif diff --git a/faceapi/lockfree.h b/faceapi/lockfree.h index ce7d2a64..47b810fa 100644 --- a/faceapi/lockfree.h +++ b/faceapi/lockfree.h @@ -1,65 +1,65 @@ -//lock free queue template class by Herb Sutter -//Dr Dobbs Journal article http://www.drdobbs.com/cpp/210604448;jsessionid=OQGQPSMNL4X4XQE1GHPSKH4ATMY32JVN?pgno=1 - -template class LockFreeQueue -{ -private: - struct Node - { - Node( T val ) : value(val), next(nullptr) { } - T value; - Node* next; - }; - - Node* first; // for producer only - Node* divider, last; // shared - - //not working in VC2008 - //atomic divider, last; // shared - -public: - LockFreeQueue() - { - // add dummy separator - first = divider = last = new Node( T() ); - } - - ~LockFreeQueue() - { - while( first != nullptr ) - { - // release the list - Node* tmp = first; - first = tmp->next; - delete tmp; - } - } - - void Produce( const T& t ) - { - last->next = new Node(t); // add the new item - last = last->next; // publish it - - while( first != divider ) - { - // trim unused nodes - Node* tmp = first; - first = first->next; - delete tmp; - } - } - - bool Consume( T& result ) - { - if( divider != last ) - { - // if queue is nonempty - result = divider->next->value; // copy it back - divider = divider->next; // publish that we took it - return true; // and report success - } - - return false; // else report empty - } -}; - +//lock free queue template class by Herb Sutter +//Dr Dobbs Journal article http://www.drdobbs.com/cpp/210604448;jsessionid=OQGQPSMNL4X4XQE1GHPSKH4ATMY32JVN?pgno=1 + +template class LockFreeQueue +{ +private: + struct Node + { + Node( T val ) : value(val), next(nullptr) { } + T value; + Node* next; + }; + + Node* first; // for producer only + Node* divider, last; // shared + + //not working in VC2008 + //atomic divider, last; // shared + +public: + LockFreeQueue() + { + // add dummy separator + first = divider = last = new Node( T() ); + } + + ~LockFreeQueue() + { + while( first != nullptr ) + { + // release the list + Node* tmp = first; + first = tmp->next; + delete tmp; + } + } + + void Produce( const T& t ) + { + last->next = new Node(t); // add the new item + last = last->next; // publish it + + while( first != divider ) + { + // trim unused nodes + Node* tmp = first; + first = first->next; + delete tmp; + } + } + + bool Consume( T& result ) + { + if( divider != last ) + { + // if queue is nonempty + result = divider->next->value; // copy it back + divider = divider->next; // publish that we took it + return true; // and report success + } + + return false; // else report empty + } +}; + diff --git a/faceapi/main.cpp b/faceapi/main.cpp index 9fe0af95..8128ee97 100644 --- a/faceapi/main.cpp +++ b/faceapi/main.cpp @@ -1,529 +1,529 @@ -/******************************************************************************** -* 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) 2013 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 . * -*********************************************************************************/ - -//Precompiled header -#include "stdafx.h" - -//FaceAPI headers -#include -#include "ftnoir_tracker_base/ftnoir_tracker_sm_types.h" -#include "utils.h" -#include - -//local headers -#include "build_options.h" - -//namespaces -using namespace std; -using namespace sm::faceapi::samplecode; - -// -// global variables -// -HANDLE hSMMemMap = NULL; -SMMemMap *pMemData; -HANDLE hSMMutex; -smEngineHeadPoseData new_head_pose; -bool stopCommand = false; -bool ftnoirConnected = false; - -//enums -enum GROUP_ID -{ - GROUP0=0, -}; - -enum EVENT_ID -{ - EVENT_PING=0, - EVENT_INIT, -}; - -enum INPUT_ID -{ - INPUT0=0, -}; - -//function definitions -void updateHeadPose(smEngineHeadPoseData* temp_head_pose); -bool SMCreateMapping(); - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -//FaceAPI function implementations -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void STDCALL receiveLogMessage(void *, const char *buf, int /*buf_len*/) -{ - Lock lock(g_mutex); // serialize logging calls from different threads to avoid garbled output. - //cout << string(buf); -} - -// Callback function for face-data -void STDCALL receiveFaceData(void *, smEngineFaceData face_data, smCameraVideoFrame video_frame) -{ - Lock lock(g_mutex); - - // Get info including data pointer to original image from camera - smImageInfo video_frame_image_info; - THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok - - // video_frame_image_info.plane_addr[*] now point to the image memory planes. - // The memory is only valid until the end of this routine unless you call smImageAddRef(video_frame.image_handle). - // So you can deep copy the image data here, or use smImageAddRef() and just copy the pointer. - // If you use smImageAddRef() you are responsible for calling smImageDestroy() to avoid a memory leak later. - - // In this callback you will typically want to copy the smEngineFaceData data into your own data-structure. - // Since the smEngineFaceData contains multiple pod types copying it is not atomic and - // a mutex is required to avoid the race-condition with any thread simultaneously - // reading from your data-structure. - // Such a race condition will not crash your code but will create weird noise in the tracking data. - - if (g_do_face_data_printing) - { - //cout << video_frame << " " << face_data; - - // Save any face texture to a PNG file - if (face_data.texture) - { - // Create a unique filename - std::stringstream filename; - filename << "face_" << video_frame.frame_num << ".png"; - // Try saving to a file - if (saveToPNGFile(filename.str(), face_data.texture->image_info) == SM_API_OK) - { - cout << "Saved face-texture to " << filename.str() << std::endl; - } - else - { - cout << "Error saving face-texture to " << filename.str() << std::endl; - } - } - } -} - -// Callback function for head-pose -void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame) -{ - Lock lock(g_mutex); - - // Get info including data pointer to original image from camera - smImageInfo video_frame_image_info; - THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok - - // video_frame_image_info.plane_addr[*] now point to the image memory planes. - // The memory is only valid until the end of this routine unless you call smImageAddRef(video_frame.image_handle). - // So you can deep copy the image data here, or use smImageAddRef() and just copy the pointer. - // If you use smImageAddRef() you are responsible for calling smImageDestroy() to avoid a memory leak later. - - // In this callback you will typically want to copy the smEngineFaceData data into your own data-structure. - // Since the smEngineFaceData contains multiple pod types copying it is not atomic and - // a mutex is required to avoid the race-condition with any thread simultaneously - // reading from your data-structure. - // Such a race condition will not crash your code but will create weird noise in the tracking data. - - if (g_do_head_pose_printing) - { - //cout << video_frame << " " << head_pose << std::endl; - } - - //make a copy of the new head pose data and send it to simconnect - //when we get a simmconnect frame event the new offset will be applied to the camera - updateHeadPose(&head_pose); -} - -// Create the first available camera detected on the system, and return its handle -smCameraHandle createFirstCamera() -{ - // Detect cameras - smCameraInfoList info_list; - THROW_ON_ERROR(smCameraCreateInfoList(&info_list)); - - if (info_list.num_cameras == 0) - { - throw std::exception(); - } - else - { - cout << "The followings cameras were detected: " << endl; - for (int i=0; ihandle,TRUE)); - THROW_ON_ERROR(smHTV2SetHeadPoseFilterLevel(engine_handle, pMemData->initial_filter_level)); - pMemData->handshake = 0; - } - else { - THROW_ON_ERROR(smVideoDisplayCreate(engine_handle,&video_display_handle,0,TRUE)); - } - - // Setup the VideoDisplay - THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); - - // Get the handle to the window and change the title to "Hello World" - smWindowHandle win_handle = 0; - THROW_ON_ERROR(smVideoDisplayGetWindowHandle(video_display_handle,&win_handle)); - SetWindowText(win_handle, _T("faceAPI Video-widget")); - MoveWindow(win_handle, 0, 0, 250, 180, true); - - // Loop on the keyboard - while (processKeyPress(engine_handle, video_display_handle) && !stopCommand) - { - // Read and print the current head-pose (if not using the callback mechanism) - #if (USE_HEADPOSE_CALLBACK==0) - #pragma message("Polling Headpose Manually") - if (engine_licensed) - { - smEngineHeadPoseData head_pose; - Lock lock(g_mutex); - - THROW_ON_ERROR(smHTCurrentHeadPose(engine_handle,&head_pose)); - if (g_do_head_pose_printing) - { - std::cout << head_pose << std::endl; - } - - } - #endif - - // NOTE: If you have a windows event loop in your program you - // will not need to call smAPIProcessEvents(). This manually redraws the video window. - THROW_ON_ERROR(smAPIProcessEvents()); - - // Prevent CPU overload in our simple loop. - const int frame_period_ms = 10; - Sleep(frame_period_ms); - - // - // Process the command sent by FaceTrackNoIR. - // - if (ftnoirConnected && (pMemData != 0)) { - - // - // Determine the trackers' state and send it to FaceTrackNoIR. - // - THROW_ON_ERROR(smEngineGetState(engine_handle, &state)); - pMemData->state = state; - pMemData->handshake += 1; - - // - // Check if FaceTrackNoIR is still 'in contact'. - // FaceTrackNoIR will reset the handshake, every time in writes data. - // If the value rises too high, this exe will stop itself... - // - if ( pMemData->handshake > 200) { - stopCommand = TRUE; - } - - // - // Check if a command was issued and do something with it! - // - switch (pMemData->command) { - case FT_SM_START: - - // - // Only execute Start, if the engine is not yet tracking. - // - if (state != SM_API_ENGINE_STATE_HT_TRACKING) { - THROW_ON_ERROR(smEngineStart(engine_handle)); // Start tracking - } - pMemData->command = 0; // Reset - break; - - case FT_SM_STOP: - THROW_ON_ERROR(smEngineStop(engine_handle)); // Stop tracking - pMemData->command = 0; // Reset - break; - - case FT_SM_EXIT: - THROW_ON_ERROR(smEngineStop(engine_handle)); // Stop tracking - stopCommand = TRUE; - pMemData->command = 0; // Reset - pMemData->state = SM_API_ENGINE_STATE_TERMINATED; // One last update, before quitting... - break; - - case FT_SM_SET_PAR_FILTER: - THROW_ON_ERROR(smHTV2SetHeadPoseFilterLevel(engine_handle, pMemData->par_val_int)); - pMemData->command = 0; // Reset - break; - - case FT_SM_SHOW_CAM: - THROW_ON_ERROR(smEngineShowCameraControlPanel(engine_handle)); - pMemData->command = 0; // Reset - break; - - default: - pMemData->command = 0; // Reset - // should never be reached - break; - } - } - } // While(1) - - // Destroy engine - THROW_ON_ERROR(smEngineDestroy(&engine_handle)); - // Destroy video display - THROW_ON_ERROR(smVideoDisplayDestroy(&video_display_handle)); - - if (ftnoirConnected) { - if ( pMemData != NULL ) { - UnmapViewOfFile ( pMemData ); - } - - if (hSMMutex != 0) { - CloseHandle( hSMMutex ); - } - hSMMutex = 0; - - if (hSMMemMap != 0) { - CloseHandle( hSMMemMap ); - } - hSMMemMap = 0; - } - -} // run() - -// Application entry point -int _tmain(int /*argc*/, _TCHAR** /*argv*/) -{ - OutputDebugString(_T("_tmain() says: Starting Function\n")); - - try - { - if (SMCreateMapping()) { - run(); - } - } - catch (exception &e) - { - cerr << e.what() << endl; - } - - return smAPIQuit(); -} - -// -// This is called exactly once for each FaceAPI callback and must be within an exclusive lock -// -void updateHeadPose(smEngineHeadPoseData* temp_head_pose) -{ - // - // Check if the pointer is OK and wait for the Mutex. - // - if ( (pMemData != NULL) && (WaitForSingleObject(hSMMutex, 100) == WAIT_OBJECT_0) ) { - - // - // Copy the Raw measurements directly to the client. - // - if (temp_head_pose->confidence > 0.0f) - { - memcpy(&pMemData->data.new_pose,temp_head_pose,sizeof(smEngineHeadPoseData)); - } - ReleaseMutex(hSMMutex); - } -}; - -// -// Create a memory-mapping to the faceAPI data. -// It contains the tracking data, a command-code from FaceTrackNoIR -// -// -bool SMCreateMapping() -{ - OutputDebugString(_T("FTCreateMapping says: Starting Function\n")); - - // - // A FileMapping is used to create 'shared memory' between the faceAPI and FaceTrackNoIR. - // FaceTrackNoIR creates the mapping, this program only opens it. - // If it's not there: the program was apparently started by the user instead of FaceTrackNoIR... - // - // Open an existing FileMapping, Read/Write access - // - hSMMemMap = OpenFileMappingA( FILE_MAP_WRITE , false , (LPCSTR) SM_MM_DATA ); - if ( ( hSMMemMap != 0 ) ) { - ftnoirConnected = true; - OutputDebugString(_T("FTCreateMapping says: FileMapping opened successfully...\n")); - pMemData = (SMMemMap *) MapViewOfFile(hSMMemMap, FILE_MAP_WRITE, 0, 0, sizeof(TFaceData)); - if (pMemData != NULL) { - OutputDebugString(_T("FTCreateMapping says: MapViewOfFile OK.\n")); - pMemData->state = 0; - } - hSMMutex = CreateMutexA(NULL, false, SM_MUTEX); - } - else { - OutputDebugString(_T("FTCreateMapping says: FileMapping not opened...FaceTrackNoIR not connected!\n")); - ftnoirConnected = false; - pMemData = 0; - } - - return true; -} +/******************************************************************************** +* 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) 2013 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 . * +*********************************************************************************/ + +//Precompiled header +#include "stdafx.h" + +//FaceAPI headers +#include +#include "ftnoir_tracker_base/ftnoir_tracker_sm_types.h" +#include "utils.h" +#include + +//local headers +#include "build_options.h" + +//namespaces +using namespace std; +using namespace sm::faceapi::samplecode; + +// +// global variables +// +HANDLE hSMMemMap = NULL; +SMMemMap *pMemData; +HANDLE hSMMutex; +smEngineHeadPoseData new_head_pose; +bool stopCommand = false; +bool ftnoirConnected = false; + +//enums +enum GROUP_ID +{ + GROUP0=0, +}; + +enum EVENT_ID +{ + EVENT_PING=0, + EVENT_INIT, +}; + +enum INPUT_ID +{ + INPUT0=0, +}; + +//function definitions +void updateHeadPose(smEngineHeadPoseData* temp_head_pose); +bool SMCreateMapping(); + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +//FaceAPI function implementations +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void STDCALL receiveLogMessage(void *, const char *buf, int /*buf_len*/) +{ + Lock lock(g_mutex); // serialize logging calls from different threads to avoid garbled output. + //cout << string(buf); +} + +// Callback function for face-data +void STDCALL receiveFaceData(void *, smEngineFaceData face_data, smCameraVideoFrame video_frame) +{ + Lock lock(g_mutex); + + // Get info including data pointer to original image from camera + smImageInfo video_frame_image_info; + THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok + + // video_frame_image_info.plane_addr[*] now point to the image memory planes. + // The memory is only valid until the end of this routine unless you call smImageAddRef(video_frame.image_handle). + // So you can deep copy the image data here, or use smImageAddRef() and just copy the pointer. + // If you use smImageAddRef() you are responsible for calling smImageDestroy() to avoid a memory leak later. + + // In this callback you will typically want to copy the smEngineFaceData data into your own data-structure. + // Since the smEngineFaceData contains multiple pod types copying it is not atomic and + // a mutex is required to avoid the race-condition with any thread simultaneously + // reading from your data-structure. + // Such a race condition will not crash your code but will create weird noise in the tracking data. + + if (g_do_face_data_printing) + { + //cout << video_frame << " " << face_data; + + // Save any face texture to a PNG file + if (face_data.texture) + { + // Create a unique filename + std::stringstream filename; + filename << "face_" << video_frame.frame_num << ".png"; + // Try saving to a file + if (saveToPNGFile(filename.str(), face_data.texture->image_info) == SM_API_OK) + { + cout << "Saved face-texture to " << filename.str() << std::endl; + } + else + { + cout << "Error saving face-texture to " << filename.str() << std::endl; + } + } + } +} + +// Callback function for head-pose +void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame) +{ + Lock lock(g_mutex); + + // Get info including data pointer to original image from camera + smImageInfo video_frame_image_info; + THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok + + // video_frame_image_info.plane_addr[*] now point to the image memory planes. + // The memory is only valid until the end of this routine unless you call smImageAddRef(video_frame.image_handle). + // So you can deep copy the image data here, or use smImageAddRef() and just copy the pointer. + // If you use smImageAddRef() you are responsible for calling smImageDestroy() to avoid a memory leak later. + + // In this callback you will typically want to copy the smEngineFaceData data into your own data-structure. + // Since the smEngineFaceData contains multiple pod types copying it is not atomic and + // a mutex is required to avoid the race-condition with any thread simultaneously + // reading from your data-structure. + // Such a race condition will not crash your code but will create weird noise in the tracking data. + + if (g_do_head_pose_printing) + { + //cout << video_frame << " " << head_pose << std::endl; + } + + //make a copy of the new head pose data and send it to simconnect + //when we get a simmconnect frame event the new offset will be applied to the camera + updateHeadPose(&head_pose); +} + +// Create the first available camera detected on the system, and return its handle +smCameraHandle createFirstCamera() +{ + // Detect cameras + smCameraInfoList info_list; + THROW_ON_ERROR(smCameraCreateInfoList(&info_list)); + + if (info_list.num_cameras == 0) + { + throw std::exception(); + } + else + { + cout << "The followings cameras were detected: " << endl; + for (int i=0; ihandle,TRUE)); + THROW_ON_ERROR(smHTV2SetHeadPoseFilterLevel(engine_handle, pMemData->initial_filter_level)); + pMemData->handshake = 0; + } + else { + THROW_ON_ERROR(smVideoDisplayCreate(engine_handle,&video_display_handle,0,TRUE)); + } + + // Setup the VideoDisplay + THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); + + // Get the handle to the window and change the title to "Hello World" + smWindowHandle win_handle = 0; + THROW_ON_ERROR(smVideoDisplayGetWindowHandle(video_display_handle,&win_handle)); + SetWindowText(win_handle, _T("faceAPI Video-widget")); + MoveWindow(win_handle, 0, 0, 250, 180, true); + + // Loop on the keyboard + while (processKeyPress(engine_handle, video_display_handle) && !stopCommand) + { + // Read and print the current head-pose (if not using the callback mechanism) + #if (USE_HEADPOSE_CALLBACK==0) + #pragma message("Polling Headpose Manually") + if (engine_licensed) + { + smEngineHeadPoseData head_pose; + Lock lock(g_mutex); + + THROW_ON_ERROR(smHTCurrentHeadPose(engine_handle,&head_pose)); + if (g_do_head_pose_printing) + { + std::cout << head_pose << std::endl; + } + + } + #endif + + // NOTE: If you have a windows event loop in your program you + // will not need to call smAPIProcessEvents(). This manually redraws the video window. + THROW_ON_ERROR(smAPIProcessEvents()); + + // Prevent CPU overload in our simple loop. + const int frame_period_ms = 10; + Sleep(frame_period_ms); + + // + // Process the command sent by FaceTrackNoIR. + // + if (ftnoirConnected && (pMemData != 0)) { + + // + // Determine the trackers' state and send it to FaceTrackNoIR. + // + THROW_ON_ERROR(smEngineGetState(engine_handle, &state)); + pMemData->state = state; + pMemData->handshake += 1; + + // + // Check if FaceTrackNoIR is still 'in contact'. + // FaceTrackNoIR will reset the handshake, every time in writes data. + // If the value rises too high, this exe will stop itself... + // + if ( pMemData->handshake > 200) { + stopCommand = TRUE; + } + + // + // Check if a command was issued and do something with it! + // + switch (pMemData->command) { + case FT_SM_START: + + // + // Only execute Start, if the engine is not yet tracking. + // + if (state != SM_API_ENGINE_STATE_HT_TRACKING) { + THROW_ON_ERROR(smEngineStart(engine_handle)); // Start tracking + } + pMemData->command = 0; // Reset + break; + + case FT_SM_STOP: + THROW_ON_ERROR(smEngineStop(engine_handle)); // Stop tracking + pMemData->command = 0; // Reset + break; + + case FT_SM_EXIT: + THROW_ON_ERROR(smEngineStop(engine_handle)); // Stop tracking + stopCommand = TRUE; + pMemData->command = 0; // Reset + pMemData->state = SM_API_ENGINE_STATE_TERMINATED; // One last update, before quitting... + break; + + case FT_SM_SET_PAR_FILTER: + THROW_ON_ERROR(smHTV2SetHeadPoseFilterLevel(engine_handle, pMemData->par_val_int)); + pMemData->command = 0; // Reset + break; + + case FT_SM_SHOW_CAM: + THROW_ON_ERROR(smEngineShowCameraControlPanel(engine_handle)); + pMemData->command = 0; // Reset + break; + + default: + pMemData->command = 0; // Reset + // should never be reached + break; + } + } + } // While(1) + + // Destroy engine + THROW_ON_ERROR(smEngineDestroy(&engine_handle)); + // Destroy video display + THROW_ON_ERROR(smVideoDisplayDestroy(&video_display_handle)); + + if (ftnoirConnected) { + if ( pMemData != NULL ) { + UnmapViewOfFile ( pMemData ); + } + + if (hSMMutex != 0) { + CloseHandle( hSMMutex ); + } + hSMMutex = 0; + + if (hSMMemMap != 0) { + CloseHandle( hSMMemMap ); + } + hSMMemMap = 0; + } + +} // run() + +// Application entry point +int _tmain(int /*argc*/, _TCHAR** /*argv*/) +{ + OutputDebugString(_T("_tmain() says: Starting Function\n")); + + try + { + if (SMCreateMapping()) { + run(); + } + } + catch (exception &e) + { + cerr << e.what() << endl; + } + + return smAPIQuit(); +} + +// +// This is called exactly once for each FaceAPI callback and must be within an exclusive lock +// +void updateHeadPose(smEngineHeadPoseData* temp_head_pose) +{ + // + // Check if the pointer is OK and wait for the Mutex. + // + if ( (pMemData != NULL) && (WaitForSingleObject(hSMMutex, 100) == WAIT_OBJECT_0) ) { + + // + // Copy the Raw measurements directly to the client. + // + if (temp_head_pose->confidence > 0.0f) + { + memcpy(&pMemData->data.new_pose,temp_head_pose,sizeof(smEngineHeadPoseData)); + } + ReleaseMutex(hSMMutex); + } +}; + +// +// Create a memory-mapping to the faceAPI data. +// It contains the tracking data, a command-code from FaceTrackNoIR +// +// +bool SMCreateMapping() +{ + OutputDebugString(_T("FTCreateMapping says: Starting Function\n")); + + // + // A FileMapping is used to create 'shared memory' between the faceAPI and FaceTrackNoIR. + // FaceTrackNoIR creates the mapping, this program only opens it. + // If it's not there: the program was apparently started by the user instead of FaceTrackNoIR... + // + // Open an existing FileMapping, Read/Write access + // + hSMMemMap = OpenFileMappingA( FILE_MAP_WRITE , false , (LPCSTR) SM_MM_DATA ); + if ( ( hSMMemMap != 0 ) ) { + ftnoirConnected = true; + OutputDebugString(_T("FTCreateMapping says: FileMapping opened successfully...\n")); + pMemData = (SMMemMap *) MapViewOfFile(hSMMemMap, FILE_MAP_WRITE, 0, 0, sizeof(TFaceData)); + if (pMemData != NULL) { + OutputDebugString(_T("FTCreateMapping says: MapViewOfFile OK.\n")); + pMemData->state = 0; + } + hSMMutex = CreateMutexA(NULL, false, SM_MUTEX); + } + else { + OutputDebugString(_T("FTCreateMapping says: FileMapping not opened...FaceTrackNoIR not connected!\n")); + ftnoirConnected = false; + pMemData = 0; + } + + return true; +} diff --git a/faceapi/mutex.h b/faceapi/mutex.h index a4f84705..b1a013e8 100644 --- a/faceapi/mutex.h +++ b/faceapi/mutex.h @@ -1,46 +1,46 @@ -#ifndef SM_API_TESTAPPCONSOLE_MUTEX_H -#define SM_API_TESTAPPCONSOLE_MUTEX_H - -#include - -namespace sm -{ - namespace faceapi - { - namespace samplecode - { - // A very simple mutex class for sample code purposes. - // It is recommended that you use the boost threads library. - class Mutex - { - public: - Mutex() - { - if (!InitializeCriticalSectionAndSpinCount(&_cs,0x80000400)) - { - throw std::exception(); - } - } - ~Mutex() - { - DeleteCriticalSection(&_cs); - } - void lock() const - { - EnterCriticalSection(&_cs); - } - void unlock() const - { - LeaveCriticalSection(&_cs); - } - private: - // Noncopyable - Mutex(const Mutex &); - Mutex &operator=(const Mutex &); - private: - mutable CRITICAL_SECTION _cs; - }; - } - } -} -#endif +#ifndef SM_API_TESTAPPCONSOLE_MUTEX_H +#define SM_API_TESTAPPCONSOLE_MUTEX_H + +#include + +namespace sm +{ + namespace faceapi + { + namespace samplecode + { + // A very simple mutex class for sample code purposes. + // It is recommended that you use the boost threads library. + class Mutex + { + public: + Mutex() + { + if (!InitializeCriticalSectionAndSpinCount(&_cs,0x80000400)) + { + throw std::exception(); + } + } + ~Mutex() + { + DeleteCriticalSection(&_cs); + } + void lock() const + { + EnterCriticalSection(&_cs); + } + void unlock() const + { + LeaveCriticalSection(&_cs); + } + private: + // Noncopyable + Mutex(const Mutex &); + Mutex &operator=(const Mutex &); + private: + mutable CRITICAL_SECTION _cs; + }; + } + } +} +#endif diff --git a/faceapi/stdafx.cpp b/faceapi/stdafx.cpp index b4263f59..981c9e33 100644 --- a/faceapi/stdafx.cpp +++ b/faceapi/stdafx.cpp @@ -1,8 +1,8 @@ -// stdafx.cpp : source file that includes just the standard includes -// TestAppConsole.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file +// stdafx.cpp : source file that includes just the standard includes +// TestAppConsole.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/faceapi/stdafx.h b/faceapi/stdafx.h index 1fdab0b1..92e24b3e 100644 --- a/faceapi/stdafx.h +++ b/faceapi/stdafx.h @@ -1,36 +1,36 @@ -#pragma once - -#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 - -#include -#include - -#ifndef _MSC_VER - -#include - -typedef uint64_t u_int64_t; -typedef uint32_t u_int32_t; -typedef uint16_t u_int16_t; -typedef uint8_t u_int8_t; -#endif - -#include -#include -#include -#include -#include -#include -#ifdef SM_API -# undef SM_API -#endif -#ifdef STDCALL -# undef STDCALL -#endif - -#define SM_API(type) type __declspec(dllimport) __stdcall -#define STDCALL __stdcall - -#include +#pragma once + +#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 + +#include +#include + +#ifndef _MSC_VER + +#include + +typedef uint64_t u_int64_t; +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; +#endif + +#include +#include +#include +#include +#include +#include +#ifdef SM_API +# undef SM_API +#endif +#ifdef STDCALL +# undef STDCALL +#endif + +#define SM_API(type) type __declspec(dllimport) __stdcall +#define STDCALL __stdcall + +#include diff --git a/faceapi/utils.h b/faceapi/utils.h index 5d25e9a7..80555d22 100644 --- a/faceapi/utils.h +++ b/faceapi/utils.h @@ -1,349 +1,349 @@ -#ifndef SM_API_TESTAPPCONSOLE_UTILS_H -#define SM_API_TESTAPPCONSOLE_UTILS_H - -#include "lock.h" -#include -#include - -#define THROW_ON_ERROR(x) \ -{ \ - smReturnCode result = (x); \ - if (result < 0) \ - { \ - std::stringstream s; \ - s << "API error code: " << result; \ - std::cerr << s; \ - throw std::exception(); \ - } \ -} - -namespace sm -{ - namespace faceapi - { - namespace samplecode - { - // Global variables - Mutex g_mutex; - bool g_ctrl_c_detected(false); - bool g_do_head_pose_printing(false); - bool g_do_face_data_printing(false); - unsigned short g_overlay_flags(SM_API_VIDEO_DISPLAY_HEAD_MESH | SM_API_VIDEO_DISPLAY_PERFORMANCE); - - // CTRL-C handler function - void __cdecl CtrlCHandler(int) - { - Lock lock(g_mutex); - std::cout << "Ctrl-C detected, stopping..." << std::endl; - g_ctrl_c_detected = true; - } - - // Radians to degrees conversion - float rad2deg(float rad) - { - return rad*57.2957795f; - } - - void toggleFlag(unsigned short &val, unsigned short flag) - { - if (val & flag) - { - val = val & ~flag; - } - else - { - val = val | flag; - } - } - - // Save an image to PNG file - smReturnCode saveToPNGFile(const std::string& filepath, smImageInfo image_info) - { - smBool ok; - smReturnCode error; - - // Create an API string - smStringHandle filepath_handle = 0; - ok = (error = smStringCreate(&filepath_handle)) == SM_API_OK; - ok = ok && (error = smStringReadBuffer(filepath_handle,filepath.c_str(),filepath.size())) == SM_API_OK; - - // Create an API image - smImageHandle image_handle = 0; - smImageMemoryCopyMode copy_mode = SM_API_IMAGE_MEMORYCOPYMODE_AUTO; - ok = ok && (error = smImageCreateFromInfo(&image_info,©_mode,&image_handle)) == SM_API_OK; - - // Save the image as PNG - ok = ok && (error = smImageSaveToPNG(image_handle,filepath_handle)) == SM_API_OK; - - // Destroy the image and string - smStringDestroy(&filepath_handle); - smImageDestroy(&image_handle); - return error; - } - - // Stream operators for printing - - std::ostream &operator<<(std::ostream & os, const smSize2i &s) - { - return os << "[" << s.h << "," << s.h << "]"; - } - - std::ostream &operator<<(std::ostream & os, const smCoord3f &pos) - { - return os << "(" << pos.x << "," << pos.y << "," << pos.z << ")"; - } - - std::ostream &operator<<(std::ostream & os, const smRotEuler &rot) - { - return os << "(" << rad2deg(rot.x_rads) << "," << rad2deg(rot.y_rads) << "," << rad2deg(rot.z_rads) << ")"; - } - - std::ostream &operator<<(std::ostream & os, const smPixel &p) - { - return os << "[" << static_cast(p.x) << "," << static_cast(p.y) << "]"; - } - - std::ostream &operator<<(std::ostream & os, const smFaceTexCoord &ftc) - { - return os << "{" << ftc.u << "," << ftc.v << "}"; - } - - std::ostream &operator<<(std::ostream & os, const smFaceLandmark &lm) - { - return os << "id "<< lm.id << " fc" << lm.fc << " ftc" << lm.ftc << " pc" << lm.pc << " wc" << lm.wc; - } - - std::ostream &operator<<(std::ostream & os, const smImageInfo &im) - { - os << "format "; - switch (im.format) - { - case SM_API_IMAGECODE_GRAY_8U: - os << "GRAY_8U"; - break; - case SM_API_IMAGECODE_GRAY_16U: - os << "GRAY_16U"; - break; - case SM_API_IMAGECODE_YUY2: - os << "YUY2"; - break; - case SM_API_IMAGECODE_I420: - os << "I420"; - break; - case SM_API_IMAGECODE_BGRA_32U: - os << "BGRA_32U"; - break; - case SM_API_IMAGECODE_ARGB_32U: - os << "ARGB_32U"; - break; - case SM_API_IMAGECODE_BGR_24U: - os << "BGR_24U"; - break; - case SM_API_IMAGECODE_RGB_24U: - os << "RGB_24U"; - break; - default: - os << "unknown"; - break; - } - os << " res" << im.res; - os << " plane_addr(" << static_cast(im.plane_addr[0]) << "," - << static_cast(im.plane_addr[1]) << "," - << static_cast(im.plane_addr[2]) << "," - << static_cast(im.plane_addr[3]) << ")"; - os << " step_bytes(" << im.step_bytes[0] << "," << im.step_bytes[1] << "," << im.step_bytes[2] << "," << im.step_bytes[3] << ")"; - os << " user_data " << im.user_data; - return os; - } - - std::ostream &operator<<(std::ostream & os, const smFaceTexture &t) - { - os << "type "; - switch (t.type) - { - case SM_ORTHOGRAPHIC_PROJECTION: - os << "orthographic"; - break; - default: - os << "unknown"; - break; - } - os << " origin" << t.origin << " scale" << t.scale << std::endl; - os << " image_info " << t.image_info << std::endl; - os << " num_mask_landmarks " << t.num_mask_landmarks << std::endl; - for (int i=0; i +#include + +#define THROW_ON_ERROR(x) \ +{ \ + smReturnCode result = (x); \ + if (result < 0) \ + { \ + std::stringstream s; \ + s << "API error code: " << result; \ + std::cerr << s; \ + throw std::exception(); \ + } \ +} + +namespace sm +{ + namespace faceapi + { + namespace samplecode + { + // Global variables + Mutex g_mutex; + bool g_ctrl_c_detected(false); + bool g_do_head_pose_printing(false); + bool g_do_face_data_printing(false); + unsigned short g_overlay_flags(SM_API_VIDEO_DISPLAY_HEAD_MESH | SM_API_VIDEO_DISPLAY_PERFORMANCE); + + // CTRL-C handler function + void __cdecl CtrlCHandler(int) + { + Lock lock(g_mutex); + std::cout << "Ctrl-C detected, stopping..." << std::endl; + g_ctrl_c_detected = true; + } + + // Radians to degrees conversion + float rad2deg(float rad) + { + return rad*57.2957795f; + } + + void toggleFlag(unsigned short &val, unsigned short flag) + { + if (val & flag) + { + val = val & ~flag; + } + else + { + val = val | flag; + } + } + + // Save an image to PNG file + smReturnCode saveToPNGFile(const std::string& filepath, smImageInfo image_info) + { + smBool ok; + smReturnCode error; + + // Create an API string + smStringHandle filepath_handle = 0; + ok = (error = smStringCreate(&filepath_handle)) == SM_API_OK; + ok = ok && (error = smStringReadBuffer(filepath_handle,filepath.c_str(),filepath.size())) == SM_API_OK; + + // Create an API image + smImageHandle image_handle = 0; + smImageMemoryCopyMode copy_mode = SM_API_IMAGE_MEMORYCOPYMODE_AUTO; + ok = ok && (error = smImageCreateFromInfo(&image_info,©_mode,&image_handle)) == SM_API_OK; + + // Save the image as PNG + ok = ok && (error = smImageSaveToPNG(image_handle,filepath_handle)) == SM_API_OK; + + // Destroy the image and string + smStringDestroy(&filepath_handle); + smImageDestroy(&image_handle); + return error; + } + + // Stream operators for printing + + std::ostream &operator<<(std::ostream & os, const smSize2i &s) + { + return os << "[" << s.h << "," << s.h << "]"; + } + + std::ostream &operator<<(std::ostream & os, const smCoord3f &pos) + { + return os << "(" << pos.x << "," << pos.y << "," << pos.z << ")"; + } + + std::ostream &operator<<(std::ostream & os, const smRotEuler &rot) + { + return os << "(" << rad2deg(rot.x_rads) << "," << rad2deg(rot.y_rads) << "," << rad2deg(rot.z_rads) << ")"; + } + + std::ostream &operator<<(std::ostream & os, const smPixel &p) + { + return os << "[" << static_cast(p.x) << "," << static_cast(p.y) << "]"; + } + + std::ostream &operator<<(std::ostream & os, const smFaceTexCoord &ftc) + { + return os << "{" << ftc.u << "," << ftc.v << "}"; + } + + std::ostream &operator<<(std::ostream & os, const smFaceLandmark &lm) + { + return os << "id "<< lm.id << " fc" << lm.fc << " ftc" << lm.ftc << " pc" << lm.pc << " wc" << lm.wc; + } + + std::ostream &operator<<(std::ostream & os, const smImageInfo &im) + { + os << "format "; + switch (im.format) + { + case SM_API_IMAGECODE_GRAY_8U: + os << "GRAY_8U"; + break; + case SM_API_IMAGECODE_GRAY_16U: + os << "GRAY_16U"; + break; + case SM_API_IMAGECODE_YUY2: + os << "YUY2"; + break; + case SM_API_IMAGECODE_I420: + os << "I420"; + break; + case SM_API_IMAGECODE_BGRA_32U: + os << "BGRA_32U"; + break; + case SM_API_IMAGECODE_ARGB_32U: + os << "ARGB_32U"; + break; + case SM_API_IMAGECODE_BGR_24U: + os << "BGR_24U"; + break; + case SM_API_IMAGECODE_RGB_24U: + os << "RGB_24U"; + break; + default: + os << "unknown"; + break; + } + os << " res" << im.res; + os << " plane_addr(" << static_cast(im.plane_addr[0]) << "," + << static_cast(im.plane_addr[1]) << "," + << static_cast(im.plane_addr[2]) << "," + << static_cast(im.plane_addr[3]) << ")"; + os << " step_bytes(" << im.step_bytes[0] << "," << im.step_bytes[1] << "," << im.step_bytes[2] << "," << im.step_bytes[3] << ")"; + os << " user_data " << im.user_data; + return os; + } + + std::ostream &operator<<(std::ostream & os, const smFaceTexture &t) + { + os << "type "; + switch (t.type) + { + case SM_ORTHOGRAPHIC_PROJECTION: + os << "orthographic"; + break; + default: + os << "unknown"; + break; + } + os << " origin" << t.origin << " scale" << t.scale << std::endl; + os << " image_info " << t.image_info << std::endl; + os << " num_mask_landmarks " << t.num_mask_landmarks << std::endl; + for (int i=0; i. * -*********************************************************************************/ -#include "facetracknoir.h" -#include "tracker.h" -#include -#include - -#if defined(__WIN32) || defined(_WIN32) -# include -#endif - -#if defined(__APPLE__) -# define SONAME "dylib" -#elif defined(_WIN32) || defined(__WIN32) -# define SONAME "dll" -#else -# define SONAME "so" -#endif - -#include - -#if defined(__WIN32) || defined(_WIN32) -#undef DIRECTINPUT_VERSION -#define DIRECTINPUT_VERSION 0x0800 -#include -#include - -KeybindingWorkerDummy::~KeybindingWorkerDummy() { - if (dinkeyboard) { - dinkeyboard->Unacquire(); - dinkeyboard->Release(); - } - if (din) - din->Release(); -} - -KeybindingWorkerDummy::KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter) -: kCenter(keyCenter), window(w), should_quit(true), din(0), dinkeyboard(0) -{ - if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&din, NULL) != DI_OK) { - qDebug() << "setup DirectInput8 Creation failed!" << GetLastError(); - return; - } - if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) { - din->Release(); - din = 0; - qDebug() << "setup CreateDevice function failed!" << GetLastError(); - return; - } - if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) { - qDebug() << "setup SetDataFormat function failed!" << GetLastError(); - dinkeyboard->Release(); - dinkeyboard = 0; - din->Release(); - din = 0; - return; - } - - if (dinkeyboard->SetCooperativeLevel(window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) { - dinkeyboard->Release(); - din->Release(); - din = 0; - dinkeyboard = 0; - qDebug() << "setup SetCooperativeLevel function failed!" << GetLastError(); - return; - } - if (dinkeyboard->Acquire() != DI_OK) - { - dinkeyboard->Release(); - din->Release(); - din = 0; - dinkeyboard = 0; - qDebug() << "setup dinkeyboard Acquire failed!" << GetLastError(); - return; - } - should_quit = false; -} - -#define PROCESS_KEY(k, s) \ - if (isKeyPressed(&k, keystate) && (!k.ever_pressed ? (k.timer.start(), k.ever_pressed = true) : k.timer.restart() > 100)) \ - window.s(); - -static bool isKeyPressed( const Key *key, const BYTE *keystate ) { - bool shift; - bool ctrl; - bool alt; - - 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; - } - return false; -} - -void KeybindingWorkerDummy::run() { - BYTE keystate[256]; - while (!should_quit) - { - if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) { - qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError(); - Sleep(25); - continue; - } - - PROCESS_KEY(kCenter, shortcutRecentered); - - Sleep(25); - } -} -#else -#endif - -#ifdef _MSC_VER -# define LIB_PREFIX "" -#else -# define LIB_PREFIX "lib" -#endif - -// -// Setup the Main Dialog -// -FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WFlags flags) : - #if defined(__WIN32) || defined(_WIN32) - keybindingWorker(NULL), - #else - keyCenter(0), - #endif - QMainWindow(parent, flags), - pTrackerDialog(NULL), - pSecondTrackerDialog(NULL), - pProtocolDialog(NULL), - pFilterDialog(NULL), - looping(false), - timUpdateHeadPose(this) -{ - ui.setupUi(this); - cameraDetected = false; - - // - // Initialize Widget handles, to prevent memory-access errors. - // - _keyboard_shortcuts = 0; - _curve_config = 0; - - tracker = 0; - - setupFaceTrackNoIR(); - - //Q_INIT_RESOURCE(PoseWidget); - - ui.lblX->setVisible(false); - ui.lblY->setVisible(false); - ui.lblZ->setVisible(false); - ui.lblRotX->setVisible(false); - ui.lblRotY->setVisible(false); - ui.lblRotZ->setVisible(false); - - ui.lcdNumOutputPosX->setVisible(false); - ui.lcdNumOutputPosY->setVisible(false); - ui.lcdNumOutputPosZ->setVisible(false); - ui.lcdNumOutputRotX->setVisible(false); - ui.lcdNumOutputRotY->setVisible(false); - ui.lcdNumOutputRotZ->setVisible(false); -} - -/** sets up all objects and connections to buttons */ -void FaceTrackNoIR::setupFaceTrackNoIR() { - // if we simply place a global variable with THeadPoseData, - // it gets initialized and pulls in QSettings before - // main() starts. program can and will crash. - - ui.headPoseWidget->show(); - ui.video_frame->hide(); - - // menu objects will be connected with the functions in FaceTrackNoIR class - connect(ui.btnLoad, SIGNAL(clicked()), this, SLOT(open())); - connect(ui.btnSave, SIGNAL(clicked()), this, SLOT(save())); - connect(ui.btnSaveAs, SIGNAL(clicked()), this, SLOT(saveAs())); - - 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())); - - // Connect checkboxes - connect(ui.chkInvertYaw, SIGNAL(stateChanged(int)), this, SLOT(setInvertYaw(int))); - connect(ui.chkInvertRoll, SIGNAL(stateChanged(int)), this, SLOT(setInvertRoll(int))); - connect(ui.chkInvertPitch, SIGNAL(stateChanged(int)), this, SLOT(setInvertPitch(int))); - connect(ui.chkInvertX, SIGNAL(stateChanged(int)), this, SLOT(setInvertX(int))); - connect(ui.chkInvertY, SIGNAL(stateChanged(int)), this, SLOT(setInvertY(int))); - connect(ui.chkInvertZ, SIGNAL(stateChanged(int)), this, SLOT(setInvertZ(int))); - - // button methods connect with methods in this class - connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(startTracker())); - connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stopTracker())); - - //read the camera-name, using DirectShow - GetCameraNameDX(); - - //Create the system-tray and connect the events for that. - createIconGroupBox(); - - //Load the tracker-settings, from the INI-file - loadSettings(); - - connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); - connect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int))); - connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); - - //Setup the timer for showing the headpose. - connect(&timUpdateHeadPose, SIGNAL(timeout()), this, SLOT(showHeadPose())); - settingsDirty = false; -} - -/** destructor stops the engine and quits the faceapi **/ -FaceTrackNoIR::~FaceTrackNoIR() { - - // - // Stop the tracker, by simulating a button-push - // - stopTracker(); - save(); -} - -// -// Update the Settings, after a value has changed. This way, the Tracker does not have to re-start. -// -void FaceTrackNoIR::updateSettings() { - if ( tracker != NULL ) { - tracker->loadSettings(); - } -} - -// -// Get a pointer to the video-widget, to use in the DLL -// -QFrame *FaceTrackNoIR::get_video_widget() { - return ui.video_frame; -} - -/** read the name of the first video-capturing device at start up **/ -/** FaceAPI can only use this first one... **/ -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!"; - - // Enumerate the monikers. - 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)) { - // 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)); - qDebug() << "GetWDM says: Moniker found:" << str; - ui.cameraName->setText(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(); -#endif -} - -// -// Open an INI-file with the QFileDialog -// If succesfull, the settings in it will be read -// -void FaceTrackNoIR::open() { - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::ExistingFile); - - QString fileName = dialog.getOpenFileName( - this, - tr("Select one FTNoir settings file"), - QCoreApplication::applicationDirPath() + "/Settings/", - tr("Settings file (*.ini);;All Files (*)"), - NULL); - - // - // If a file was selected, save it's name and read it's contents. - // - if (! fileName.isEmpty() ) { - QSettings settings("opentrack"); // Registry settings (in HK_USER) - settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath()); - loadSettings(); - } -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FaceTrackNoIR::save() { - - 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 ( "Tracking" ); - iniFile.setValue ( "invertYaw", ui.chkInvertYaw->isChecked() ); - iniFile.setValue ( "invertPitch", ui.chkInvertPitch->isChecked() ); - iniFile.setValue ( "invertRoll", ui.chkInvertRoll->isChecked() ); - iniFile.setValue ( "invertX", ui.chkInvertX->isChecked() ); - iniFile.setValue ( "invertY", ui.chkInvertY->isChecked() ); - iniFile.setValue ( "invertZ", ui.chkInvertZ->isChecked() ); - iniFile.endGroup (); - - iniFile.beginGroup ( "GameProtocol" ); - { - DynamicLibrary* proto = dlopen_protocols.value( ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); - iniFile.setValue ( "DLL", proto == NULL ? "" : proto->filename); - } - iniFile.endGroup (); - - iniFile.beginGroup ( "TrackerSource" ); - { - DynamicLibrary* tracker = dlopen_trackers.value( ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); - iniFile.setValue ( "DLL", tracker == NULL ? "" : tracker->filename); - } - { - DynamicLibrary* tracker = dlopen_trackers.value( ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL); - iniFile.setValue ( "2ndDLL", tracker == NULL ? "" : tracker->filename); - } - iniFile.endGroup (); - - // - // Save the name of the filter in the INI-file. - // - iniFile.beginGroup ( "Filter" ); - { - DynamicLibrary* filter = dlopen_filters.value( ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); - iniFile.setValue ( "DLL", filter == NULL ? "" : filter->filename); - } - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Get the new name of the INI-file and save the settings to it. -// -// The user may choose to overwrite an existing file. This will be deleted, before copying the current file to it. -// -void FaceTrackNoIR::saveAs() -{ - // - // Get the current filename of the INI-file. - // - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - - // - // Get the new filename of the INI-file. - // - QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), - oldFile, -// QCoreApplication::applicationDirPath() + "/Settings", - tr("Settings file (*.ini);;All Files (*)")); - if (!fileName.isEmpty()) { - - // - // Remove the file, if it already exists. - // - QFileInfo newFileInfo ( fileName ); - if ((newFileInfo.exists()) && (oldFile != fileName)) { - QFile newFileFile ( fileName ); - newFileFile.remove(); - } - - // - // Copy the current INI-file to the new name. - // - QFileInfo oldFileInfo ( oldFile ); - if (oldFileInfo.exists()) { - QFile oldFileFile ( oldFile ); - oldFileFile.copy( fileName ); - } - - // - // Write the new name to the Registry and save the other INI-values. - // - settings.setValue ("SettingsFile", fileName); - save(); - - // - // Reload the settings, to get the GUI right again... - // - loadSettings(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FaceTrackNoIR::loadSettings() { - looping = true; - qDebug() << "loadSettings says: Starting "; - QSettings settings("opentrack"); // Registry settings (in HK_USER) - - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - qDebug() << "Config file now" << currentFile; - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - - // - // Put the filename in the window-title. - // - QFileInfo pathInfo ( currentFile ); - setWindowTitle ( "opentrack (1.8 alpha) - " + pathInfo.fileName() ); - - // - // Get a List of all the INI-files in the (currently active) Settings-folder. - // - QDir settingsDir( pathInfo.dir() ); - QStringList filters; - filters << "*.ini"; - iniFileList.clear(); - iniFileList = settingsDir.entryList( filters, QDir::Files, QDir::Name ); - - // - // Add strings to the Listbox. - // - ui.iconcomboProfile->clear(); - 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->setItemIcon(i, QIcon(":/images/settingsopen16.png")); - ui.iconcomboProfile->setCurrentIndex( i ); - } - } - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "Tracking" ); - ui.chkInvertYaw->setChecked (iniFile.value ( "invertYaw", 0 ).toBool()); - ui.chkInvertPitch->setChecked (iniFile.value ( "invertPitch", 0 ).toBool()); - ui.chkInvertRoll->setChecked (iniFile.value ( "invertRoll", 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 (); - - // Read the currently selected Protocol from the INI-file. - // If the setting "DLL" isn't found (pre-1.7 version of INI), then the setting 'Selection' is evaluated. - // - iniFile.beginGroup ( "GameProtocol" ); - QString selectedProtocolName = iniFile.value ( "DLL", "" ).toString(); - iniFile.endGroup (); - - // - // Find the Index of the DLL and set the selection. - // - for ( int i = 0; i < dlopen_protocols.size(); i++) { - if (dlopen_protocols.at(i)->filename.compare( selectedProtocolName, Qt::CaseInsensitive ) == 0) { - ui.iconcomboProtocol->setCurrentIndex( i ); - break; - } - } - - // - // Read the currently selected Tracker from the INI-file. - // If the setting "DLL" isn't found (pre-1.7 version), then the setting 'Selection' is evaluated. - // - iniFile.beginGroup ( "TrackerSource" ); - QString selectedTrackerName = iniFile.value ( "DLL", "" ).toString(); - qDebug() << "loadSettings says: selectedTrackerName = " << selectedTrackerName; - QString secondTrackerName = iniFile.value ( "2ndDLL", "None" ).toString(); - qDebug() << "loadSettings says: secondTrackerName = " << secondTrackerName; - iniFile.endGroup (); - - for ( int i = 0; i < dlopen_trackers.size(); i++) { - DynamicLibrary* foo = dlopen_trackers.at(i); - if (foo && foo->filename.compare( selectedTrackerName, Qt::CaseInsensitive ) == 0) { - ui.iconcomboTrackerSource->setCurrentIndex( i ); - } - if (foo && foo->filename.compare( secondTrackerName, Qt::CaseInsensitive ) == 0) { - ui.cbxSecondTrackerSource->setCurrentIndex( i + 1 ); - } - } - - // - // Read the currently selected Filter from the INI-file. - // - iniFile.beginGroup ( "Filter" ); - QString selectedFilterName = iniFile.value ( "DLL", "" ).toString(); - qDebug() << "createIconGroupBox says: selectedFilterName = " << selectedFilterName; - iniFile.endGroup (); - - // - // Find the Index of the DLL and set the selection. - // - for ( int i = 0; i < dlopen_filters.size(); i++) { - DynamicLibrary* foo = dlopen_filters.at(i); - if (foo && foo->filename.compare( selectedFilterName, Qt::CaseInsensitive ) == 0) { - ui.iconcomboFilter->setCurrentIndex( i ); - break; - } - } - - settingsDirty = false; - looping = false; -} - -/** start tracking the face **/ -void FaceTrackNoIR::startTracker( ) { - bindKeyboardShortcuts(); - - // - // Disable buttons - // - ui.iconcomboProfile->setEnabled ( false ); - ui.btnLoad->setEnabled ( false ); - ui.btnSave->setEnabled ( false ); - ui.btnSaveAs->setEnabled ( false ); - ui.btnShowFilterControls->setEnabled ( true ); - - // - // Create the Tracker and setup - // - - if (Libraries) - delete Libraries; - Libraries = new SelectedLibraries(this); - - if (!Libraries->correct) - { - QMessageBox::warning(this, "Something went wrong", "Tracking can't be initialized, probably protocol prerequisites missing", QMessageBox::Ok, QMessageBox::NoButton); - stopTracker(); - return; - } - -#if defined(_WIN32) || defined(__WIN32) - keybindingWorker = new KeybindingWorker(*this, keyCenter); - keybindingWorker->start(); -#endif - - if (tracker) { - tracker->wait(); - delete tracker; - } - - 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) - - for (int i = 0; i < 6; i++) - { - axis(i).curve.loadSettings(iniFile); - axis(i).curveAlt.loadSettings(iniFile); - } - - static const char* names[] = { - "tx_alt", - "ty_alt", - "tz_alt", - "rx_alt", - "ry_alt", - "rz_alt", - }; - - static const char* invert_names[] = { - "invertX", - "invertY", - "invertZ", - "invertYaw", - "invertPitch", - "invertRoll" - }; - - iniFile.beginGroup("Tracking"); - - for (int i = 0; i < 6; i++) { - axis(i).altp = iniFile.value(names[i], false).toBool(); - axis(i).invert = iniFile.value(invert_names[i], false).toBool() ? 1 : -1; - } - - iniFile.endGroup(); - - tracker = new Tracker ( this ); - - // - // Setup the Tracker and send the settings. - // This is necessary, because the events are only triggered 'on change' - // - tracker->setInvertAxis(Yaw, ui.chkInvertYaw->isChecked() ); - tracker->setInvertAxis(Pitch, ui.chkInvertPitch->isChecked() ); - tracker->setInvertAxis(Roll, ui.chkInvertRoll->isChecked() ); - tracker->setInvertAxis(TX, ui.chkInvertX->isChecked() ); - tracker->setInvertAxis(TY, ui.chkInvertY->isChecked() ); - tracker->setInvertAxis(TZ, ui.chkInvertZ->isChecked() ); - - // - // Register the Tracker instance with the Tracker Dialog (if open) - // - if (pTrackerDialog && Libraries->pTracker) { - pTrackerDialog->registerTracker( Libraries->pTracker ); - } - - if (pFilterDialog && Libraries->pFilter) - pFilterDialog->registerFilter(Libraries->pFilter); - - tracker->start(); - - ui.headPoseWidget->show(); - - // - ui.btnStartTracker->setEnabled ( false ); - ui.btnStopTracker->setEnabled ( true ); - - // Enable/disable Protocol-server Settings - ui.iconcomboTrackerSource->setEnabled ( false ); - ui.cbxSecondTrackerSource->setEnabled ( false ); - ui.iconcomboProtocol->setEnabled ( false ); - ui.btnShowServerControls->setEnabled ( false ); - ui.iconcomboFilter->setEnabled ( false ); - - // - // Update the camera-name, FaceAPI can only use the 1st one found! - // - GetCameraNameDX(); - - // - // Start the timer to update the head-pose (digits and 'man in black') - // - timUpdateHeadPose.start(40); - - ui.lblX->setVisible(true); - ui.lblY->setVisible(true); - ui.lblZ->setVisible(true); - ui.lblRotX->setVisible(true); - ui.lblRotY->setVisible(true); - ui.lblRotZ->setVisible(true); - - ui.lcdNumOutputPosX->setVisible(true); - ui.lcdNumOutputPosY->setVisible(true); - ui.lcdNumOutputPosZ->setVisible(true); - ui.lcdNumOutputRotX->setVisible(true); - ui.lcdNumOutputRotY->setVisible(true); - ui.lcdNumOutputRotZ->setVisible(true); -} - -/** stop tracking the face **/ -void FaceTrackNoIR::stopTracker( ) { - ui.game_name->setText("Not connected"); -#if defined(_WIN32) || defined(__WIN32) - if (keybindingWorker) - { - keybindingWorker->should_quit = true; - keybindingWorker->wait(); - delete keybindingWorker; - keybindingWorker = NULL; - } -#endif - // - // Stop displaying the head-pose. - // - timUpdateHeadPose.stop(); - ui.pose_display->rotateBy(0, 0, 0); - - ui.lblX->setVisible(false); - ui.lblY->setVisible(false); - ui.lblZ->setVisible(false); - ui.lblRotX->setVisible(false); - ui.lblRotY->setVisible(false); - ui.lblRotZ->setVisible(false); - - ui.lcdNumOutputPosX->setVisible(false); - ui.lcdNumOutputPosY->setVisible(false); - ui.lcdNumOutputPosZ->setVisible(false); - ui.lcdNumOutputRotX->setVisible(false); - ui.lcdNumOutputRotY->setVisible(false); - ui.lcdNumOutputRotZ->setVisible(false); - - // - // UnRegister the Tracker instance with the Tracker Dialog (if open) - // - if (pTrackerDialog) { - pTrackerDialog->unRegisterTracker(); - } - if (pProtocolDialog) { - pProtocolDialog->unRegisterProtocol(); - } - if (pFilterDialog) - pFilterDialog->unregisterFilter(); - - // - // Delete the tracker (after stopping things and all). - // - if ( tracker ) { - qDebug() << "Done with tracking"; - tracker->should_quit = true; - tracker->wait(); - - qDebug() << "stopTracker says: Deleting tracker!"; - delete tracker; - qDebug() << "stopTracker says: Tracker deleted!"; - tracker = 0; - if (Libraries) { - delete Libraries; - Libraries = NULL; - } - } - ui.btnStartTracker->setEnabled ( true ); - ui.btnStopTracker->setEnabled ( false ); -// ui.btnShowEngineControls->setEnabled ( false ); - ui.iconcomboProtocol->setEnabled ( true ); - ui.iconcomboTrackerSource->setEnabled ( true ); - ui.cbxSecondTrackerSource->setEnabled ( true ); - ui.iconcomboFilter->setEnabled ( true ); - - // Enable/disable Protocol-server Settings - ui.btnShowServerControls->setEnabled ( true ); - ui.video_frame->hide(); - - // - ui.iconcomboProfile->setEnabled ( true ); - ui.btnLoad->setEnabled ( true ); - ui.btnSave->setEnabled ( true ); - ui.btnSaveAs->setEnabled ( true ); - ui.btnShowFilterControls->setEnabled ( true ); -} - -/** set the invert from the checkbox **/ -void FaceTrackNoIR::setInvertAxis(Axis axis, int invert ) { - if (tracker) - tracker->setInvertAxis (axis, (invert != 0)?true:false ); - settingsDirty = true; -} - -/** Show the headpose in the widget (triggered by timer) **/ -void FaceTrackNoIR::showHeadPose() { - double newdata[6]; - - ui.lblX->setVisible(true); - ui.lblY->setVisible(true); - ui.lblZ->setVisible(true); - ui.lblRotX->setVisible(true); - ui.lblRotY->setVisible(true); - ui.lblRotZ->setVisible(true); - - ui.lcdNumOutputPosX->setVisible(true); - ui.lcdNumOutputPosY->setVisible(true); - ui.lcdNumOutputPosZ->setVisible(true); - ui.lcdNumOutputRotX->setVisible(true); - ui.lcdNumOutputRotY->setVisible(true); - ui.lcdNumOutputRotZ->setVisible(true); - - // - // Get the pose and also display it. - // Updating the pose from within the Tracker-class caused crashes... - // - tracker->getHeadPose(newdata); - ui.lcdNumX->display(QString("%1").arg(newdata[TX], 0, 'f', 1)); - ui.lcdNumY->display(QString("%1").arg(newdata[TY], 0, 'f', 1)); - ui.lcdNumZ->display(QString("%1").arg(newdata[TZ], 0, 'f', 1)); - - - ui.lcdNumRotX->display(QString("%1").arg(newdata[Yaw], 0, 'f', 1)); - ui.lcdNumRotY->display(QString("%1").arg(newdata[Pitch], 0, 'f', 1)); - ui.lcdNumRotZ->display(QString("%1").arg(newdata[Roll], 0, 'f', 1)); - - // - // Get the output-pose and also display it. - // - tracker->getOutputHeadPose(newdata); - - ui.pose_display->rotateBy(newdata[Yaw], newdata[Roll], newdata[Pitch]); - - ui.lcdNumOutputPosX->display(QString("%1").arg(newdata[TX], 0, 'f', 1)); - ui.lcdNumOutputPosY->display(QString("%1").arg(newdata[TY], 0, 'f', 1)); - ui.lcdNumOutputPosZ->display(QString("%1").arg(newdata[TZ], 0, 'f', 1)); - - - ui.lcdNumOutputRotX->display(QString("%1").arg(newdata[Yaw], 0, 'f', 1)); - ui.lcdNumOutputRotY->display(QString("%1").arg(newdata[Pitch], 0, 'f', 1)); - ui.lcdNumOutputRotZ->display(QString("%1").arg(newdata[Roll], 0, 'f', 1)); - - // - // Update the curves in the curve-configurator. This shows the ball with the red lines. - // - if (_curve_config) { - _curve_config->update(); - } - if (Libraries->pProtocol) - { - QString name = Libraries->pProtocol->getGameName(); - ui.game_name->setText(name); - } -} - -/** toggles Video Widget **/ -void FaceTrackNoIR::showVideoWidget() { - if(ui.video_frame->isHidden()) - ui.video_frame->show(); - else - ui.video_frame->hide(); -} - -/** toggles Video Widget **/ -void FaceTrackNoIR::showHeadPoseWidget() { - if(ui.headPoseWidget->isHidden()) - ui.headPoseWidget->show(); - else - ui.headPoseWidget->hide(); -} - -/** toggles Engine Controls Dialog **/ -void FaceTrackNoIR::showTrackerSettings() { - if (pTrackerDialog) { - delete pTrackerDialog; - pTrackerDialog = NULL; - } - - DynamicLibrary* lib = dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); - - if (lib) { - pTrackerDialog = (ITrackerDialog*) lib->Dialog(); - if (pTrackerDialog) { - if (Libraries && Libraries->pTracker) - pTrackerDialog->registerTracker(Libraries->pTracker); - pTrackerDialog->Initialize(this); - } - } -} - -// Show the Settings dialog for the secondary Tracker -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) { - if (Libraries && Libraries->pSecondTracker) - pSecondTrackerDialog->registerTracker(Libraries->pSecondTracker); - pSecondTrackerDialog->Initialize(this); - } - } -} - -/** toggles Server Controls Dialog **/ -void FaceTrackNoIR::showServerControls() { - if (pProtocolDialog) { - delete pProtocolDialog; - pProtocolDialog = NULL; - } - - DynamicLibrary* lib = dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); - - if (lib && lib->Dialog) { - pProtocolDialog = (IProtocolDialog*) lib->Dialog(); - if (pProtocolDialog) { - pProtocolDialog->Initialize(this); - } - } -} - -/** toggles Filter Controls Dialog **/ -void FaceTrackNoIR::showFilterControls() { - if (pFilterDialog) { - delete pFilterDialog; - pFilterDialog = NULL; - } - - DynamicLibrary* lib = dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); - - if (lib && lib->Dialog) { - pFilterDialog = (IFilterDialog*) lib->Dialog(); - if (pFilterDialog) { - pFilterDialog->Initialize(this); - if (Libraries && Libraries->pFilter) - pFilterDialog->registerFilter(Libraries->pFilter); - } - } -} -/** toggles Keyboard Shortcut Dialog **/ -void FaceTrackNoIR::showKeyboardShortcuts() { - - // Create if new - if (!_keyboard_shortcuts) - { - _keyboard_shortcuts = new KeyboardShortcutDialog( this, this, Qt::Dialog ); - } - - // Show if already created - if (_keyboard_shortcuts) { - _keyboard_shortcuts->show(); - _keyboard_shortcuts->raise(); - } -} - -/** toggles Curve Configuration Dialog **/ -void FaceTrackNoIR::showCurveConfiguration() { - - // Create if new - if (!_curve_config) - { - _curve_config = new CurveConfigurationDialog( this, this, Qt::Dialog ); - } - - // Show if already created - if (_curve_config) { - _curve_config->show(); - _curve_config->raise(); - } -} - -/** exit application **/ -void FaceTrackNoIR::exit() { - QCoreApplication::exit(0); -} - -static bool get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon) -{ - Metadata* meta; - if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) - { - delete lib; - return false; - } - meta->getFullName(&longName); - meta->getIcon(&icon); - delete meta; - return true; -} - -static void fill_combobox(const QString& filter, QList& list, QComboBox* cbx, QComboBox* cbx2) -{ - QDir settingsDir( QCoreApplication::applicationDirPath() ); - QStringList filenames = settingsDir.entryList( QStringList() << (LIB_PREFIX + filter + SONAME), QDir::Files, QDir::Name ); - for ( int i = 0; i < filenames.size(); i++) { - QIcon icon; - QString longName; - QString str = filenames.at(i); - DynamicLibrary* lib = new DynamicLibrary(str); - qDebug() << "Loading" << str; - std::cout.flush(); - if (!get_metadata(lib, longName, icon)) - { - delete lib; - continue; - } - list.push_back(lib); - cbx->addItem(icon, longName); - if (cbx2) - cbx2->addItem(icon, longName); - } -} - -// -// Setup the icons for the comboBoxes -// -void FaceTrackNoIR::createIconGroupBox() -{ - ui.cbxSecondTrackerSource->addItem(QIcon(), "None"); - dlopen_filters.push_back((DynamicLibrary*) NULL); - ui.iconcomboFilter->addItem(QIcon(), "None"); - - 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); - - connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); - connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); - connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); - connect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); -} - -// -// Handle changes of the Protocol selection -// -void FaceTrackNoIR::protocolSelected(int index) -{ - settingsDirty = true; - ui.btnShowServerControls->setEnabled ( true ); - - //setWindowIcon(QIcon(":/images/FaceTrackNoIR.png")); - //breaks with transparency -sh - //ui.btnShowServerControls->setIcon(icon);] -} - -// -// Handle changes of the Tracking Source selection -// -void FaceTrackNoIR::trackingSourceSelected(int index) -{ - settingsDirty = true; - ui.btnShowEngineControls->setEnabled ( true ); -} - -// -// Handle changes of the Profile selection -// -void FaceTrackNoIR::profileSelected(int index) -{ - if (looping) - return; - // - // Read the current INI-file setting, to get the folder in which it's located... - // - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QFileInfo pathInfo ( currentFile ); - - // - // Save the name of the INI-file in the Registry. - // - settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + iniFileList.value(ui.iconcomboProfile->currentIndex(), "")); - loadSettings(); -} - -// -// Handle changes of the Filter selection -// -void FaceTrackNoIR::filterSelected(int index) -{ - settingsDirty = true; - - //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) - - ui.btnShowFilterControls->setEnabled ( true ); -} - -//**************************************************************************************************// -//**************************************************************************************************// -// -// Constructor for Keyboard-shortcuts-dialog -// -KeyboardShortcutDialog::KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *parent, Qt::WindowFlags f ) : -QWidget( parent , f) -{ - ui.setupUi( this ); - - QPoint offsetpos(100, 100); - this->move(parent->pos() + offsetpos); - - mainApp = ftnoir; // Preserve a pointer to FTNoIR - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - - // Clear the Lists with key-descriptions and keycodes and build the Lists - // The strings will all be added to the ListBoxes for each Shortkey - // - - // Add strings to the Listboxes. - // - - for ( int i = 0; i < global_key_sequences.size(); i++) { - ui.cbxCenterKey->addItem(global_key_sequences.at(i)); - } - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -KeyboardShortcutDialog::~KeyboardShortcutDialog() { - qDebug() << "~KeyboardShortcutDialog() says: started"; -} - -// -// OK clicked on server-dialog -// -void KeyboardShortcutDialog::doOK() { - save(); - this->close(); - mainApp->bindKeyboardShortcuts(); -} - -// override show event -void KeyboardShortcutDialog::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void KeyboardShortcutDialog::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -void FaceTrackNoIR::bindKeyboardShortcuts() -{ - 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 ( "KB_Shortcuts" ); - int idxCenter = iniFile.value("Key_index_Center", 0).toInt(); - -#if !defined(_WIN32) && !defined(__WIN32) - if (keyCenter) { - delete keyCenter; - keyCenter = NULL; - } - - if (idxCenter > 0) - { - QString seq(global_key_sequences.value(idxCenter, "")); - if (!seq.isEmpty()) - { - if (iniFile.value("Shift_Center", false).toBool()) - seq = "Shift+" + seq; - if (iniFile.value("Alt_Center", false).toBool()) - seq = "Alt+" + seq; - if (iniFile.value("Ctrl_Center", false).toBool()) - seq = "Ctrl+" + seq; - keyCenter = new QxtGlobalShortcut(QKeySequence(seq)); - connect(keyCenter, SIGNAL(activated()), this, SLOT(shortcutRecentered())); - } - } - -#else - keyCenter.keycode = 0; - keyCenter.shift = keyCenter.alt = keyCenter.ctrl = 0; - if (idxCenter > 0 && idxCenter < global_windows_key_sequences.size()) - keyCenter.keycode = global_windows_key_sequences[idxCenter]; - keyCenter.shift = iniFile.value("Shift_Center", false).toBool(); - keyCenter.alt = iniFile.value("Alt_Center", false).toBool(); - keyCenter.ctrl = iniFile.value("Ctrl_Center", false).toBool(); -#endif - iniFile.endGroup (); - - if (tracker) /* running already */ - { -#if defined(_WIN32) || defined(__WIN32) - if (keybindingWorker) - { - keybindingWorker->should_quit = true; - keybindingWorker->wait(); - delete keybindingWorker; - keybindingWorker = NULL; - } - keybindingWorker = new KeybindingWorker(*this, keyCenter); - keybindingWorker->start(); -#endif - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void KeyboardShortcutDialog::loadSettings() { - qDebug() << "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) - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "KB_Shortcuts" ); - - ui.chkCenterShift->setChecked (iniFile.value ( "Shift_Center", 0 ).toBool()); - ui.chkCenterCtrl->setChecked (iniFile.value ( "Ctrl_Center", 0 ).toBool()); - ui.chkCenterAlt->setChecked (iniFile.value ( "Alt_Center", 0 ).toBool()); - - ui.cbxCenterKey->setCurrentIndex(iniFile.value("Key_index_Center", 0).toInt()); - - iniFile.endGroup (); - - settingsDirty = false; - -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void KeyboardShortcutDialog::save() { - - qDebug() << "save() says: started"; - - 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 ( "KB_Shortcuts" ); - iniFile.setValue ( "Key_index_Center", ui.cbxCenterKey->currentIndex() ); - iniFile.setValue ( "Shift_Center", ui.chkCenterShift->isChecked() ); - iniFile.setValue ( "Ctrl_Center", ui.chkCenterCtrl->isChecked() ); - iniFile.setValue ( "Alt_Center", ui.chkCenterAlt->isChecked() ); - - iniFile.endGroup (); - - settingsDirty = false; - - // - // Send a message to the main program, to update the Settings (for the tracker) - // - mainApp->updateSettings(); -} - -//**************************************************************************************************// -//**************************************************************************************************// -// -// Constructor for Curve-configuration-dialog -// -CurveConfigurationDialog::CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent, Qt::WindowFlags f ) : -QWidget( parent , f) -{ - ui.setupUi( this ); - - QPoint offsetpos(120, 30); - this->move(parent->pos() + offsetpos); - - mainApp = ftnoir; // Preserve a pointer to FTNoIR - - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - - 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 - }; - - QCheckBox* checkboxes[6] = { - ui.rx_altp, - ui.ry_altp, - ui.rz_altp, - ui.tx_altp, - ui.ty_altp, - ui.tz_altp - }; - - for (int i = 0; i < 6; i++) - { - configs[i]->setConfig(&mainApp->axis(i).curve, currentFile); - alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt, currentFile); - connect(configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - connect(alt_configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - connect(checkboxes[i], SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); - } - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -CurveConfigurationDialog::~CurveConfigurationDialog() { - qDebug() << "~CurveConfigurationDialog() says: started"; -} - -// -// OK clicked on server-dialog -// -void CurveConfigurationDialog::doOK() { - save(); - this->close(); -} - -// override show event -void CurveConfigurationDialog::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void CurveConfigurationDialog::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void CurveConfigurationDialog::loadSettings() { - qDebug() << "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) - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - static const char* names[] = { - "tx_alt", - "ty_alt", - "tz_alt", - "rx_alt", - "ry_alt", - "rz_alt" - }; - - iniFile.beginGroup("Tracking"); - - for (int i = 0; i < 6; i++) - mainApp->axis(i).altp = iniFile.value(names[i], false).toBool(); - - QCheckBox* widgets[] = { - ui.tx_altp, - ui.ty_altp, - ui.tz_altp, - ui.rx_altp, - ui.ry_altp, - ui.rz_altp - }; - - for (int i = 0; i < 6; i++) - widgets[i]->setChecked(mainApp->axis(i).altp); - - QDoubleSpinBox* widgets2[] = { - ui.pos_tx, - ui.pos_ty, - ui.pos_tz, - ui.pos_tx, - ui.pos_ry, - ui.pos_rz - }; - - const char* names2[] = { - "zero_tx", - "zero_ty", - "zero_tz", - "zero_rx", - "zero_ry", - "zero_rz" - }; - - for (int i = 0; i < 6; i++) - widgets2[i]->setValue(iniFile.value(names2[i], 0).toDouble()); - - iniFile.endGroup(); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void CurveConfigurationDialog::save() { - - qDebug() << "save() says: started"; - - QSettings settings("opentrack"); // Registry settings (in HK_USER) - - 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); - - QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) - - iniFile.beginGroup("Tracking"); - - iniFile.setValue("rx_alt", ui.rx_altp->checkState() != Qt::Unchecked); - iniFile.setValue("ry_alt", ui.ry_altp->checkState() != Qt::Unchecked); - iniFile.setValue("rz_alt", ui.rz_altp->checkState() != Qt::Unchecked); - iniFile.setValue("tx_alt", ui.tx_altp->checkState() != Qt::Unchecked); - iniFile.setValue("ty_alt", ui.ty_altp->checkState() != Qt::Unchecked); - iniFile.setValue("tz_alt", ui.tz_altp->checkState() != Qt::Unchecked); - - QDoubleSpinBox* widgets2[] = { - ui.pos_tx, - ui.pos_ty, - ui.pos_tz, - ui.pos_tx, - ui.pos_ry, - ui.pos_rz - }; - - const char* names2[] = { - "zero_tx", - "zero_ty", - "zero_tz", - "zero_rx", - "zero_ry", - "zero_rz" - }; - - for (int i = 0; i < 6; i++) - iniFile.setValue(names2[i], widgets2[i]->value()); - - iniFile.endGroup(); - - settingsDirty = false; - - // - // Send a message to the main program, to update the Settings (for the tracker) - // - mainApp->updateSettings(); -} - -void FaceTrackNoIR::shortcutRecentered() -{ - if (tracker) - { -#if defined(__WIN32) || defined(_WIN32) - MessageBeep(MB_OK); -#else - QApplication::beep(); -#endif - qDebug() << "Center"; - tracker->do_center = true; - } -} +/******************************************************************************** +* 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) 2011 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 . * +*********************************************************************************/ +#include "facetracknoir.h" +#include "tracker.h" +#include +#include + +#if defined(__WIN32) || defined(_WIN32) +# include +#endif + +#if defined(__APPLE__) +# define SONAME "dylib" +#elif defined(_WIN32) || defined(__WIN32) +# define SONAME "dll" +#else +# define SONAME "so" +#endif + +#include + +#if defined(__WIN32) || defined(_WIN32) +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 +#include +#include + +KeybindingWorkerDummy::~KeybindingWorkerDummy() { + if (dinkeyboard) { + dinkeyboard->Unacquire(); + dinkeyboard->Release(); + } + if (din) + din->Release(); +} + +KeybindingWorkerDummy::KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter) +: kCenter(keyCenter), window(w), should_quit(true), din(0), dinkeyboard(0) +{ + if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&din, NULL) != DI_OK) { + qDebug() << "setup DirectInput8 Creation failed!" << GetLastError(); + return; + } + if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) { + din->Release(); + din = 0; + qDebug() << "setup CreateDevice function failed!" << GetLastError(); + return; + } + if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) { + qDebug() << "setup SetDataFormat function failed!" << GetLastError(); + dinkeyboard->Release(); + dinkeyboard = 0; + din->Release(); + din = 0; + return; + } + + if (dinkeyboard->SetCooperativeLevel(window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) { + dinkeyboard->Release(); + din->Release(); + din = 0; + dinkeyboard = 0; + qDebug() << "setup SetCooperativeLevel function failed!" << GetLastError(); + return; + } + if (dinkeyboard->Acquire() != DI_OK) + { + dinkeyboard->Release(); + din->Release(); + din = 0; + dinkeyboard = 0; + qDebug() << "setup dinkeyboard Acquire failed!" << GetLastError(); + return; + } + should_quit = false; +} + +#define PROCESS_KEY(k, s) \ + if (isKeyPressed(&k, keystate) && (!k.ever_pressed ? (k.timer.start(), k.ever_pressed = true) : k.timer.restart() > 100)) \ + window.s(); + +static bool isKeyPressed( const Key *key, const BYTE *keystate ) { + bool shift; + bool ctrl; + bool alt; + + 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; + } + return false; +} + +void KeybindingWorkerDummy::run() { + BYTE keystate[256]; + while (!should_quit) + { + if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) { + qDebug() << "Tracker::run GetDeviceState function failed!" << GetLastError(); + Sleep(25); + continue; + } + + PROCESS_KEY(kCenter, shortcutRecentered); + + Sleep(25); + } +} +#else +#endif + +#ifdef _MSC_VER +# define LIB_PREFIX "" +#else +# define LIB_PREFIX "lib" +#endif + +// +// Setup the Main Dialog +// +FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WFlags flags) : + #if defined(__WIN32) || defined(_WIN32) + keybindingWorker(NULL), + #else + keyCenter(0), + #endif + QMainWindow(parent, flags), + pTrackerDialog(NULL), + pSecondTrackerDialog(NULL), + pProtocolDialog(NULL), + pFilterDialog(NULL), + looping(false), + timUpdateHeadPose(this) +{ + ui.setupUi(this); + cameraDetected = false; + + // + // Initialize Widget handles, to prevent memory-access errors. + // + _keyboard_shortcuts = 0; + _curve_config = 0; + + tracker = 0; + + setupFaceTrackNoIR(); + + //Q_INIT_RESOURCE(PoseWidget); + + ui.lblX->setVisible(false); + ui.lblY->setVisible(false); + ui.lblZ->setVisible(false); + ui.lblRotX->setVisible(false); + ui.lblRotY->setVisible(false); + ui.lblRotZ->setVisible(false); + + ui.lcdNumOutputPosX->setVisible(false); + ui.lcdNumOutputPosY->setVisible(false); + ui.lcdNumOutputPosZ->setVisible(false); + ui.lcdNumOutputRotX->setVisible(false); + ui.lcdNumOutputRotY->setVisible(false); + ui.lcdNumOutputRotZ->setVisible(false); +} + +/** sets up all objects and connections to buttons */ +void FaceTrackNoIR::setupFaceTrackNoIR() { + // if we simply place a global variable with THeadPoseData, + // it gets initialized and pulls in QSettings before + // main() starts. program can and will crash. + + ui.headPoseWidget->show(); + ui.video_frame->hide(); + + // menu objects will be connected with the functions in FaceTrackNoIR class + connect(ui.btnLoad, SIGNAL(clicked()), this, SLOT(open())); + connect(ui.btnSave, SIGNAL(clicked()), this, SLOT(save())); + connect(ui.btnSaveAs, SIGNAL(clicked()), this, SLOT(saveAs())); + + 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())); + + // Connect checkboxes + connect(ui.chkInvertYaw, SIGNAL(stateChanged(int)), this, SLOT(setInvertYaw(int))); + connect(ui.chkInvertRoll, SIGNAL(stateChanged(int)), this, SLOT(setInvertRoll(int))); + connect(ui.chkInvertPitch, SIGNAL(stateChanged(int)), this, SLOT(setInvertPitch(int))); + connect(ui.chkInvertX, SIGNAL(stateChanged(int)), this, SLOT(setInvertX(int))); + connect(ui.chkInvertY, SIGNAL(stateChanged(int)), this, SLOT(setInvertY(int))); + connect(ui.chkInvertZ, SIGNAL(stateChanged(int)), this, SLOT(setInvertZ(int))); + + // button methods connect with methods in this class + connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(startTracker())); + connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stopTracker())); + + //read the camera-name, using DirectShow + GetCameraNameDX(); + + //Create the system-tray and connect the events for that. + createIconGroupBox(); + + //Load the tracker-settings, from the INI-file + loadSettings(); + + connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); + connect(ui.iconcomboProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(profileSelected(int))); + connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); + connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); + + //Setup the timer for showing the headpose. + connect(&timUpdateHeadPose, SIGNAL(timeout()), this, SLOT(showHeadPose())); + settingsDirty = false; +} + +/** destructor stops the engine and quits the faceapi **/ +FaceTrackNoIR::~FaceTrackNoIR() { + + // + // Stop the tracker, by simulating a button-push + // + stopTracker(); + save(); +} + +// +// Update the Settings, after a value has changed. This way, the Tracker does not have to re-start. +// +void FaceTrackNoIR::updateSettings() { + if ( tracker != NULL ) { + tracker->loadSettings(); + } +} + +// +// Get a pointer to the video-widget, to use in the DLL +// +QFrame *FaceTrackNoIR::get_video_widget() { + return ui.video_frame; +} + +/** read the name of the first video-capturing device at start up **/ +/** FaceAPI can only use this first one... **/ +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!"; + + // Enumerate the monikers. + 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)) { + // 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)); + qDebug() << "GetWDM says: Moniker found:" << str; + ui.cameraName->setText(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(); +#endif +} + +// +// Open an INI-file with the QFileDialog +// If succesfull, the settings in it will be read +// +void FaceTrackNoIR::open() { + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFile); + + QString fileName = dialog.getOpenFileName( + this, + tr("Select one FTNoir settings file"), + QCoreApplication::applicationDirPath() + "/Settings/", + tr("Settings file (*.ini);;All Files (*)"), + NULL); + + // + // If a file was selected, save it's name and read it's contents. + // + if (! fileName.isEmpty() ) { + QSettings settings("opentrack"); // Registry settings (in HK_USER) + settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath()); + loadSettings(); + } +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FaceTrackNoIR::save() { + + 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 ( "Tracking" ); + iniFile.setValue ( "invertYaw", ui.chkInvertYaw->isChecked() ); + iniFile.setValue ( "invertPitch", ui.chkInvertPitch->isChecked() ); + iniFile.setValue ( "invertRoll", ui.chkInvertRoll->isChecked() ); + iniFile.setValue ( "invertX", ui.chkInvertX->isChecked() ); + iniFile.setValue ( "invertY", ui.chkInvertY->isChecked() ); + iniFile.setValue ( "invertZ", ui.chkInvertZ->isChecked() ); + iniFile.endGroup (); + + iniFile.beginGroup ( "GameProtocol" ); + { + DynamicLibrary* proto = dlopen_protocols.value( ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", proto == NULL ? "" : proto->filename); + } + iniFile.endGroup (); + + iniFile.beginGroup ( "TrackerSource" ); + { + DynamicLibrary* tracker = dlopen_trackers.value( ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", tracker == NULL ? "" : tracker->filename); + } + { + DynamicLibrary* tracker = dlopen_trackers.value( ui.cbxSecondTrackerSource->currentIndex() - 1, (DynamicLibrary*) NULL); + iniFile.setValue ( "2ndDLL", tracker == NULL ? "" : tracker->filename); + } + iniFile.endGroup (); + + // + // Save the name of the filter in the INI-file. + // + iniFile.beginGroup ( "Filter" ); + { + DynamicLibrary* filter = dlopen_filters.value( ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); + iniFile.setValue ( "DLL", filter == NULL ? "" : filter->filename); + } + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Get the new name of the INI-file and save the settings to it. +// +// The user may choose to overwrite an existing file. This will be deleted, before copying the current file to it. +// +void FaceTrackNoIR::saveAs() +{ + // + // Get the current filename of the INI-file. + // + QSettings settings("opentrack"); // Registry settings (in HK_USER) + QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + + // + // Get the new filename of the INI-file. + // + QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), + oldFile, +// QCoreApplication::applicationDirPath() + "/Settings", + tr("Settings file (*.ini);;All Files (*)")); + if (!fileName.isEmpty()) { + + // + // Remove the file, if it already exists. + // + QFileInfo newFileInfo ( fileName ); + if ((newFileInfo.exists()) && (oldFile != fileName)) { + QFile newFileFile ( fileName ); + newFileFile.remove(); + } + + // + // Copy the current INI-file to the new name. + // + QFileInfo oldFileInfo ( oldFile ); + if (oldFileInfo.exists()) { + QFile oldFileFile ( oldFile ); + oldFileFile.copy( fileName ); + } + + // + // Write the new name to the Registry and save the other INI-values. + // + settings.setValue ("SettingsFile", fileName); + save(); + + // + // Reload the settings, to get the GUI right again... + // + loadSettings(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FaceTrackNoIR::loadSettings() { + looping = true; + qDebug() << "loadSettings says: Starting "; + QSettings settings("opentrack"); // Registry settings (in HK_USER) + + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + qDebug() << "Config file now" << currentFile; + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + + // + // Put the filename in the window-title. + // + QFileInfo pathInfo ( currentFile ); + setWindowTitle ( "opentrack (1.8 alpha) - " + pathInfo.fileName() ); + + // + // Get a List of all the INI-files in the (currently active) Settings-folder. + // + QDir settingsDir( pathInfo.dir() ); + QStringList filters; + filters << "*.ini"; + iniFileList.clear(); + iniFileList = settingsDir.entryList( filters, QDir::Files, QDir::Name ); + + // + // Add strings to the Listbox. + // + ui.iconcomboProfile->clear(); + 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->setItemIcon(i, QIcon(":/images/settingsopen16.png")); + ui.iconcomboProfile->setCurrentIndex( i ); + } + } + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "Tracking" ); + ui.chkInvertYaw->setChecked (iniFile.value ( "invertYaw", 0 ).toBool()); + ui.chkInvertPitch->setChecked (iniFile.value ( "invertPitch", 0 ).toBool()); + ui.chkInvertRoll->setChecked (iniFile.value ( "invertRoll", 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 (); + + // Read the currently selected Protocol from the INI-file. + // If the setting "DLL" isn't found (pre-1.7 version of INI), then the setting 'Selection' is evaluated. + // + iniFile.beginGroup ( "GameProtocol" ); + QString selectedProtocolName = iniFile.value ( "DLL", "" ).toString(); + iniFile.endGroup (); + + // + // Find the Index of the DLL and set the selection. + // + for ( int i = 0; i < dlopen_protocols.size(); i++) { + if (dlopen_protocols.at(i)->filename.compare( selectedProtocolName, Qt::CaseInsensitive ) == 0) { + ui.iconcomboProtocol->setCurrentIndex( i ); + break; + } + } + + // + // Read the currently selected Tracker from the INI-file. + // If the setting "DLL" isn't found (pre-1.7 version), then the setting 'Selection' is evaluated. + // + iniFile.beginGroup ( "TrackerSource" ); + QString selectedTrackerName = iniFile.value ( "DLL", "" ).toString(); + qDebug() << "loadSettings says: selectedTrackerName = " << selectedTrackerName; + QString secondTrackerName = iniFile.value ( "2ndDLL", "None" ).toString(); + qDebug() << "loadSettings says: secondTrackerName = " << secondTrackerName; + iniFile.endGroup (); + + for ( int i = 0; i < dlopen_trackers.size(); i++) { + DynamicLibrary* foo = dlopen_trackers.at(i); + if (foo && foo->filename.compare( selectedTrackerName, Qt::CaseInsensitive ) == 0) { + ui.iconcomboTrackerSource->setCurrentIndex( i ); + } + if (foo && foo->filename.compare( secondTrackerName, Qt::CaseInsensitive ) == 0) { + ui.cbxSecondTrackerSource->setCurrentIndex( i + 1 ); + } + } + + // + // Read the currently selected Filter from the INI-file. + // + iniFile.beginGroup ( "Filter" ); + QString selectedFilterName = iniFile.value ( "DLL", "" ).toString(); + qDebug() << "createIconGroupBox says: selectedFilterName = " << selectedFilterName; + iniFile.endGroup (); + + // + // Find the Index of the DLL and set the selection. + // + for ( int i = 0; i < dlopen_filters.size(); i++) { + DynamicLibrary* foo = dlopen_filters.at(i); + if (foo && foo->filename.compare( selectedFilterName, Qt::CaseInsensitive ) == 0) { + ui.iconcomboFilter->setCurrentIndex( i ); + break; + } + } + + settingsDirty = false; + looping = false; +} + +/** start tracking the face **/ +void FaceTrackNoIR::startTracker( ) { + bindKeyboardShortcuts(); + + // + // Disable buttons + // + ui.iconcomboProfile->setEnabled ( false ); + ui.btnLoad->setEnabled ( false ); + ui.btnSave->setEnabled ( false ); + ui.btnSaveAs->setEnabled ( false ); + ui.btnShowFilterControls->setEnabled ( true ); + + // + // Create the Tracker and setup + // + + if (Libraries) + delete Libraries; + Libraries = new SelectedLibraries(this); + + if (!Libraries->correct) + { + QMessageBox::warning(this, "Something went wrong", "Tracking can't be initialized, probably protocol prerequisites missing", QMessageBox::Ok, QMessageBox::NoButton); + stopTracker(); + return; + } + +#if defined(_WIN32) || defined(__WIN32) + keybindingWorker = new KeybindingWorker(*this, keyCenter); + keybindingWorker->start(); +#endif + + if (tracker) { + tracker->wait(); + delete tracker; + } + + 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) + + for (int i = 0; i < 6; i++) + { + axis(i).curve.loadSettings(iniFile); + axis(i).curveAlt.loadSettings(iniFile); + } + + static const char* names[] = { + "tx_alt", + "ty_alt", + "tz_alt", + "rx_alt", + "ry_alt", + "rz_alt", + }; + + static const char* invert_names[] = { + "invertX", + "invertY", + "invertZ", + "invertYaw", + "invertPitch", + "invertRoll" + }; + + iniFile.beginGroup("Tracking"); + + for (int i = 0; i < 6; i++) { + axis(i).altp = iniFile.value(names[i], false).toBool(); + axis(i).invert = iniFile.value(invert_names[i], false).toBool() ? 1 : -1; + } + + iniFile.endGroup(); + + tracker = new Tracker ( this ); + + // + // Setup the Tracker and send the settings. + // This is necessary, because the events are only triggered 'on change' + // + tracker->setInvertAxis(Yaw, ui.chkInvertYaw->isChecked() ); + tracker->setInvertAxis(Pitch, ui.chkInvertPitch->isChecked() ); + tracker->setInvertAxis(Roll, ui.chkInvertRoll->isChecked() ); + tracker->setInvertAxis(TX, ui.chkInvertX->isChecked() ); + tracker->setInvertAxis(TY, ui.chkInvertY->isChecked() ); + tracker->setInvertAxis(TZ, ui.chkInvertZ->isChecked() ); + + // + // Register the Tracker instance with the Tracker Dialog (if open) + // + if (pTrackerDialog && Libraries->pTracker) { + pTrackerDialog->registerTracker( Libraries->pTracker ); + } + + if (pFilterDialog && Libraries->pFilter) + pFilterDialog->registerFilter(Libraries->pFilter); + + tracker->start(); + + ui.headPoseWidget->show(); + + // + ui.btnStartTracker->setEnabled ( false ); + ui.btnStopTracker->setEnabled ( true ); + + // Enable/disable Protocol-server Settings + ui.iconcomboTrackerSource->setEnabled ( false ); + ui.cbxSecondTrackerSource->setEnabled ( false ); + ui.iconcomboProtocol->setEnabled ( false ); + ui.btnShowServerControls->setEnabled ( false ); + ui.iconcomboFilter->setEnabled ( false ); + + // + // Update the camera-name, FaceAPI can only use the 1st one found! + // + GetCameraNameDX(); + + // + // Start the timer to update the head-pose (digits and 'man in black') + // + timUpdateHeadPose.start(40); + + ui.lblX->setVisible(true); + ui.lblY->setVisible(true); + ui.lblZ->setVisible(true); + ui.lblRotX->setVisible(true); + ui.lblRotY->setVisible(true); + ui.lblRotZ->setVisible(true); + + ui.lcdNumOutputPosX->setVisible(true); + ui.lcdNumOutputPosY->setVisible(true); + ui.lcdNumOutputPosZ->setVisible(true); + ui.lcdNumOutputRotX->setVisible(true); + ui.lcdNumOutputRotY->setVisible(true); + ui.lcdNumOutputRotZ->setVisible(true); +} + +/** stop tracking the face **/ +void FaceTrackNoIR::stopTracker( ) { + ui.game_name->setText("Not connected"); +#if defined(_WIN32) || defined(__WIN32) + if (keybindingWorker) + { + keybindingWorker->should_quit = true; + keybindingWorker->wait(); + delete keybindingWorker; + keybindingWorker = NULL; + } +#endif + // + // Stop displaying the head-pose. + // + timUpdateHeadPose.stop(); + ui.pose_display->rotateBy(0, 0, 0); + + ui.lblX->setVisible(false); + ui.lblY->setVisible(false); + ui.lblZ->setVisible(false); + ui.lblRotX->setVisible(false); + ui.lblRotY->setVisible(false); + ui.lblRotZ->setVisible(false); + + ui.lcdNumOutputPosX->setVisible(false); + ui.lcdNumOutputPosY->setVisible(false); + ui.lcdNumOutputPosZ->setVisible(false); + ui.lcdNumOutputRotX->setVisible(false); + ui.lcdNumOutputRotY->setVisible(false); + ui.lcdNumOutputRotZ->setVisible(false); + + // + // UnRegister the Tracker instance with the Tracker Dialog (if open) + // + if (pTrackerDialog) { + pTrackerDialog->unRegisterTracker(); + } + if (pProtocolDialog) { + pProtocolDialog->unRegisterProtocol(); + } + if (pFilterDialog) + pFilterDialog->unregisterFilter(); + + // + // Delete the tracker (after stopping things and all). + // + if ( tracker ) { + qDebug() << "Done with tracking"; + tracker->should_quit = true; + tracker->wait(); + + qDebug() << "stopTracker says: Deleting tracker!"; + delete tracker; + qDebug() << "stopTracker says: Tracker deleted!"; + tracker = 0; + if (Libraries) { + delete Libraries; + Libraries = NULL; + } + } + ui.btnStartTracker->setEnabled ( true ); + ui.btnStopTracker->setEnabled ( false ); +// ui.btnShowEngineControls->setEnabled ( false ); + ui.iconcomboProtocol->setEnabled ( true ); + ui.iconcomboTrackerSource->setEnabled ( true ); + ui.cbxSecondTrackerSource->setEnabled ( true ); + ui.iconcomboFilter->setEnabled ( true ); + + // Enable/disable Protocol-server Settings + ui.btnShowServerControls->setEnabled ( true ); + ui.video_frame->hide(); + + // + ui.iconcomboProfile->setEnabled ( true ); + ui.btnLoad->setEnabled ( true ); + ui.btnSave->setEnabled ( true ); + ui.btnSaveAs->setEnabled ( true ); + ui.btnShowFilterControls->setEnabled ( true ); +} + +/** set the invert from the checkbox **/ +void FaceTrackNoIR::setInvertAxis(Axis axis, int invert ) { + if (tracker) + tracker->setInvertAxis (axis, (invert != 0)?true:false ); + settingsDirty = true; +} + +/** Show the headpose in the widget (triggered by timer) **/ +void FaceTrackNoIR::showHeadPose() { + double newdata[6]; + + ui.lblX->setVisible(true); + ui.lblY->setVisible(true); + ui.lblZ->setVisible(true); + ui.lblRotX->setVisible(true); + ui.lblRotY->setVisible(true); + ui.lblRotZ->setVisible(true); + + ui.lcdNumOutputPosX->setVisible(true); + ui.lcdNumOutputPosY->setVisible(true); + ui.lcdNumOutputPosZ->setVisible(true); + ui.lcdNumOutputRotX->setVisible(true); + ui.lcdNumOutputRotY->setVisible(true); + ui.lcdNumOutputRotZ->setVisible(true); + + // + // Get the pose and also display it. + // Updating the pose from within the Tracker-class caused crashes... + // + tracker->getHeadPose(newdata); + ui.lcdNumX->display(QString("%1").arg(newdata[TX], 0, 'f', 1)); + ui.lcdNumY->display(QString("%1").arg(newdata[TY], 0, 'f', 1)); + ui.lcdNumZ->display(QString("%1").arg(newdata[TZ], 0, 'f', 1)); + + + ui.lcdNumRotX->display(QString("%1").arg(newdata[Yaw], 0, 'f', 1)); + ui.lcdNumRotY->display(QString("%1").arg(newdata[Pitch], 0, 'f', 1)); + ui.lcdNumRotZ->display(QString("%1").arg(newdata[Roll], 0, 'f', 1)); + + // + // Get the output-pose and also display it. + // + tracker->getOutputHeadPose(newdata); + + ui.pose_display->rotateBy(newdata[Yaw], newdata[Roll], newdata[Pitch]); + + ui.lcdNumOutputPosX->display(QString("%1").arg(newdata[TX], 0, 'f', 1)); + ui.lcdNumOutputPosY->display(QString("%1").arg(newdata[TY], 0, 'f', 1)); + ui.lcdNumOutputPosZ->display(QString("%1").arg(newdata[TZ], 0, 'f', 1)); + + + ui.lcdNumOutputRotX->display(QString("%1").arg(newdata[Yaw], 0, 'f', 1)); + ui.lcdNumOutputRotY->display(QString("%1").arg(newdata[Pitch], 0, 'f', 1)); + ui.lcdNumOutputRotZ->display(QString("%1").arg(newdata[Roll], 0, 'f', 1)); + + // + // Update the curves in the curve-configurator. This shows the ball with the red lines. + // + if (_curve_config) { + _curve_config->update(); + } + if (Libraries->pProtocol) + { + QString name = Libraries->pProtocol->getGameName(); + ui.game_name->setText(name); + } +} + +/** toggles Video Widget **/ +void FaceTrackNoIR::showVideoWidget() { + if(ui.video_frame->isHidden()) + ui.video_frame->show(); + else + ui.video_frame->hide(); +} + +/** toggles Video Widget **/ +void FaceTrackNoIR::showHeadPoseWidget() { + if(ui.headPoseWidget->isHidden()) + ui.headPoseWidget->show(); + else + ui.headPoseWidget->hide(); +} + +/** toggles Engine Controls Dialog **/ +void FaceTrackNoIR::showTrackerSettings() { + if (pTrackerDialog) { + delete pTrackerDialog; + pTrackerDialog = NULL; + } + + DynamicLibrary* lib = dlopen_trackers.value(ui.iconcomboTrackerSource->currentIndex(), (DynamicLibrary*) NULL); + + if (lib) { + pTrackerDialog = (ITrackerDialog*) lib->Dialog(); + if (pTrackerDialog) { + if (Libraries && Libraries->pTracker) + pTrackerDialog->registerTracker(Libraries->pTracker); + pTrackerDialog->Initialize(this); + } + } +} + +// Show the Settings dialog for the secondary Tracker +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) { + if (Libraries && Libraries->pSecondTracker) + pSecondTrackerDialog->registerTracker(Libraries->pSecondTracker); + pSecondTrackerDialog->Initialize(this); + } + } +} + +/** toggles Server Controls Dialog **/ +void FaceTrackNoIR::showServerControls() { + if (pProtocolDialog) { + delete pProtocolDialog; + pProtocolDialog = NULL; + } + + DynamicLibrary* lib = dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); + + if (lib && lib->Dialog) { + pProtocolDialog = (IProtocolDialog*) lib->Dialog(); + if (pProtocolDialog) { + pProtocolDialog->Initialize(this); + } + } +} + +/** toggles Filter Controls Dialog **/ +void FaceTrackNoIR::showFilterControls() { + if (pFilterDialog) { + delete pFilterDialog; + pFilterDialog = NULL; + } + + DynamicLibrary* lib = dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); + + if (lib && lib->Dialog) { + pFilterDialog = (IFilterDialog*) lib->Dialog(); + if (pFilterDialog) { + pFilterDialog->Initialize(this); + if (Libraries && Libraries->pFilter) + pFilterDialog->registerFilter(Libraries->pFilter); + } + } +} +/** toggles Keyboard Shortcut Dialog **/ +void FaceTrackNoIR::showKeyboardShortcuts() { + + // Create if new + if (!_keyboard_shortcuts) + { + _keyboard_shortcuts = new KeyboardShortcutDialog( this, this, Qt::Dialog ); + } + + // Show if already created + if (_keyboard_shortcuts) { + _keyboard_shortcuts->show(); + _keyboard_shortcuts->raise(); + } +} + +/** toggles Curve Configuration Dialog **/ +void FaceTrackNoIR::showCurveConfiguration() { + + // Create if new + if (!_curve_config) + { + _curve_config = new CurveConfigurationDialog( this, this, Qt::Dialog ); + } + + // Show if already created + if (_curve_config) { + _curve_config->show(); + _curve_config->raise(); + } +} + +/** exit application **/ +void FaceTrackNoIR::exit() { + QCoreApplication::exit(0); +} + +static bool get_metadata(DynamicLibrary* lib, QString& longName, QIcon& icon) +{ + Metadata* meta; + if (!lib->Metadata || ((meta = lib->Metadata()), !meta)) + { + delete lib; + return false; + } + meta->getFullName(&longName); + meta->getIcon(&icon); + delete meta; + return true; +} + +static void fill_combobox(const QString& filter, QList& list, QComboBox* cbx, QComboBox* cbx2) +{ + QDir settingsDir( QCoreApplication::applicationDirPath() ); + QStringList filenames = settingsDir.entryList( QStringList() << (LIB_PREFIX + filter + SONAME), QDir::Files, QDir::Name ); + for ( int i = 0; i < filenames.size(); i++) { + QIcon icon; + QString longName; + QString str = filenames.at(i); + DynamicLibrary* lib = new DynamicLibrary(str); + qDebug() << "Loading" << str; + std::cout.flush(); + if (!get_metadata(lib, longName, icon)) + { + delete lib; + continue; + } + list.push_back(lib); + cbx->addItem(icon, longName); + if (cbx2) + cbx2->addItem(icon, longName); + } +} + +// +// Setup the icons for the comboBoxes +// +void FaceTrackNoIR::createIconGroupBox() +{ + ui.cbxSecondTrackerSource->addItem(QIcon(), "None"); + dlopen_filters.push_back((DynamicLibrary*) NULL); + ui.iconcomboFilter->addItem(QIcon(), "None"); + + 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); + + connect(ui.iconcomboProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolSelected(int))); + connect(ui.iconcomboTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); + connect(ui.iconcomboFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(filterSelected(int))); + connect(ui.cbxSecondTrackerSource, SIGNAL(currentIndexChanged(int)), this, SLOT(trackingSourceSelected(int))); +} + +// +// Handle changes of the Protocol selection +// +void FaceTrackNoIR::protocolSelected(int index) +{ + settingsDirty = true; + ui.btnShowServerControls->setEnabled ( true ); + + //setWindowIcon(QIcon(":/images/FaceTrackNoIR.png")); + //breaks with transparency -sh + //ui.btnShowServerControls->setIcon(icon);] +} + +// +// Handle changes of the Tracking Source selection +// +void FaceTrackNoIR::trackingSourceSelected(int index) +{ + settingsDirty = true; + ui.btnShowEngineControls->setEnabled ( true ); +} + +// +// Handle changes of the Profile selection +// +void FaceTrackNoIR::profileSelected(int index) +{ + if (looping) + return; + // + // Read the current INI-file setting, to get the folder in which it's located... + // + QSettings settings("opentrack"); // Registry settings (in HK_USER) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QFileInfo pathInfo ( currentFile ); + + // + // Save the name of the INI-file in the Registry. + // + settings.setValue ("SettingsFile", pathInfo.absolutePath() + "/" + iniFileList.value(ui.iconcomboProfile->currentIndex(), "")); + loadSettings(); +} + +// +// Handle changes of the Filter selection +// +void FaceTrackNoIR::filterSelected(int index) +{ + settingsDirty = true; + + //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) + + ui.btnShowFilterControls->setEnabled ( true ); +} + +//**************************************************************************************************// +//**************************************************************************************************// +// +// Constructor for Keyboard-shortcuts-dialog +// +KeyboardShortcutDialog::KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *parent, Qt::WindowFlags f ) : +QWidget( parent , f) +{ + ui.setupUi( this ); + + QPoint offsetpos(100, 100); + this->move(parent->pos() + offsetpos); + + mainApp = ftnoir; // Preserve a pointer to FTNoIR + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + + // Clear the Lists with key-descriptions and keycodes and build the Lists + // The strings will all be added to the ListBoxes for each Shortkey + // + + // Add strings to the Listboxes. + // + + for ( int i = 0; i < global_key_sequences.size(); i++) { + ui.cbxCenterKey->addItem(global_key_sequences.at(i)); + } + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +KeyboardShortcutDialog::~KeyboardShortcutDialog() { + qDebug() << "~KeyboardShortcutDialog() says: started"; +} + +// +// OK clicked on server-dialog +// +void KeyboardShortcutDialog::doOK() { + save(); + this->close(); + mainApp->bindKeyboardShortcuts(); +} + +// override show event +void KeyboardShortcutDialog::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void KeyboardShortcutDialog::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +void FaceTrackNoIR::bindKeyboardShortcuts() +{ + 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 ( "KB_Shortcuts" ); + int idxCenter = iniFile.value("Key_index_Center", 0).toInt(); + +#if !defined(_WIN32) && !defined(__WIN32) + if (keyCenter) { + delete keyCenter; + keyCenter = NULL; + } + + if (idxCenter > 0) + { + QString seq(global_key_sequences.value(idxCenter, "")); + if (!seq.isEmpty()) + { + if (iniFile.value("Shift_Center", false).toBool()) + seq = "Shift+" + seq; + if (iniFile.value("Alt_Center", false).toBool()) + seq = "Alt+" + seq; + if (iniFile.value("Ctrl_Center", false).toBool()) + seq = "Ctrl+" + seq; + keyCenter = new QxtGlobalShortcut(QKeySequence(seq)); + connect(keyCenter, SIGNAL(activated()), this, SLOT(shortcutRecentered())); + } + } + +#else + keyCenter.keycode = 0; + keyCenter.shift = keyCenter.alt = keyCenter.ctrl = 0; + if (idxCenter > 0 && idxCenter < global_windows_key_sequences.size()) + keyCenter.keycode = global_windows_key_sequences[idxCenter]; + keyCenter.shift = iniFile.value("Shift_Center", false).toBool(); + keyCenter.alt = iniFile.value("Alt_Center", false).toBool(); + keyCenter.ctrl = iniFile.value("Ctrl_Center", false).toBool(); +#endif + iniFile.endGroup (); + + if (tracker) /* running already */ + { +#if defined(_WIN32) || defined(__WIN32) + if (keybindingWorker) + { + keybindingWorker->should_quit = true; + keybindingWorker->wait(); + delete keybindingWorker; + keybindingWorker = NULL; + } + keybindingWorker = new KeybindingWorker(*this, keyCenter); + keybindingWorker->start(); +#endif + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void KeyboardShortcutDialog::loadSettings() { + qDebug() << "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) + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "KB_Shortcuts" ); + + ui.chkCenterShift->setChecked (iniFile.value ( "Shift_Center", 0 ).toBool()); + ui.chkCenterCtrl->setChecked (iniFile.value ( "Ctrl_Center", 0 ).toBool()); + ui.chkCenterAlt->setChecked (iniFile.value ( "Alt_Center", 0 ).toBool()); + + ui.cbxCenterKey->setCurrentIndex(iniFile.value("Key_index_Center", 0).toInt()); + + iniFile.endGroup (); + + settingsDirty = false; + +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void KeyboardShortcutDialog::save() { + + qDebug() << "save() says: started"; + + 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 ( "KB_Shortcuts" ); + iniFile.setValue ( "Key_index_Center", ui.cbxCenterKey->currentIndex() ); + iniFile.setValue ( "Shift_Center", ui.chkCenterShift->isChecked() ); + iniFile.setValue ( "Ctrl_Center", ui.chkCenterCtrl->isChecked() ); + iniFile.setValue ( "Alt_Center", ui.chkCenterAlt->isChecked() ); + + iniFile.endGroup (); + + settingsDirty = false; + + // + // Send a message to the main program, to update the Settings (for the tracker) + // + mainApp->updateSettings(); +} + +//**************************************************************************************************// +//**************************************************************************************************// +// +// Constructor for Curve-configuration-dialog +// +CurveConfigurationDialog::CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent, Qt::WindowFlags f ) : +QWidget( parent , f) +{ + ui.setupUi( this ); + + QPoint offsetpos(120, 30); + this->move(parent->pos() + offsetpos); + + mainApp = ftnoir; // Preserve a pointer to FTNoIR + + QSettings settings("opentrack"); // Registry settings (in HK_USER) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + + 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 + }; + + QCheckBox* checkboxes[6] = { + ui.rx_altp, + ui.ry_altp, + ui.rz_altp, + ui.tx_altp, + ui.ty_altp, + ui.tz_altp + }; + + for (int i = 0; i < 6; i++) + { + configs[i]->setConfig(&mainApp->axis(i).curve, currentFile); + alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt, currentFile); + connect(configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + connect(alt_configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + connect(checkboxes[i], SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + } + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +CurveConfigurationDialog::~CurveConfigurationDialog() { + qDebug() << "~CurveConfigurationDialog() says: started"; +} + +// +// OK clicked on server-dialog +// +void CurveConfigurationDialog::doOK() { + save(); + this->close(); +} + +// override show event +void CurveConfigurationDialog::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void CurveConfigurationDialog::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void CurveConfigurationDialog::loadSettings() { + qDebug() << "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) + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + static const char* names[] = { + "tx_alt", + "ty_alt", + "tz_alt", + "rx_alt", + "ry_alt", + "rz_alt" + }; + + iniFile.beginGroup("Tracking"); + + for (int i = 0; i < 6; i++) + mainApp->axis(i).altp = iniFile.value(names[i], false).toBool(); + + QCheckBox* widgets[] = { + ui.tx_altp, + ui.ty_altp, + ui.tz_altp, + ui.rx_altp, + ui.ry_altp, + ui.rz_altp + }; + + for (int i = 0; i < 6; i++) + widgets[i]->setChecked(mainApp->axis(i).altp); + + QDoubleSpinBox* widgets2[] = { + ui.pos_tx, + ui.pos_ty, + ui.pos_tz, + ui.pos_tx, + ui.pos_ry, + ui.pos_rz + }; + + const char* names2[] = { + "zero_tx", + "zero_ty", + "zero_tz", + "zero_rx", + "zero_ry", + "zero_rz" + }; + + for (int i = 0; i < 6; i++) + widgets2[i]->setValue(iniFile.value(names2[i], 0).toDouble()); + + iniFile.endGroup(); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void CurveConfigurationDialog::save() { + + qDebug() << "save() says: started"; + + QSettings settings("opentrack"); // Registry settings (in HK_USER) + + 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); + + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + + iniFile.beginGroup("Tracking"); + + iniFile.setValue("rx_alt", ui.rx_altp->checkState() != Qt::Unchecked); + iniFile.setValue("ry_alt", ui.ry_altp->checkState() != Qt::Unchecked); + iniFile.setValue("rz_alt", ui.rz_altp->checkState() != Qt::Unchecked); + iniFile.setValue("tx_alt", ui.tx_altp->checkState() != Qt::Unchecked); + iniFile.setValue("ty_alt", ui.ty_altp->checkState() != Qt::Unchecked); + iniFile.setValue("tz_alt", ui.tz_altp->checkState() != Qt::Unchecked); + + QDoubleSpinBox* widgets2[] = { + ui.pos_tx, + ui.pos_ty, + ui.pos_tz, + ui.pos_tx, + ui.pos_ry, + ui.pos_rz + }; + + const char* names2[] = { + "zero_tx", + "zero_ty", + "zero_tz", + "zero_rx", + "zero_ry", + "zero_rz" + }; + + for (int i = 0; i < 6; i++) + iniFile.setValue(names2[i], widgets2[i]->value()); + + iniFile.endGroup(); + + settingsDirty = false; + + // + // Send a message to the main program, to update the Settings (for the tracker) + // + mainApp->updateSettings(); +} + +void FaceTrackNoIR::shortcutRecentered() +{ + if (tracker) + { +#if defined(__WIN32) || defined(_WIN32) + MessageBeep(MB_OK); +#else + QApplication::beep(); +#endif + qDebug() << "Center"; + tracker->do_center = true; + } +} diff --git a/facetracknoir/facetracknoir.h b/facetracknoir/facetracknoir.h index ff0b3642..768f6107 100644 --- a/facetracknoir/facetracknoir.h +++ b/facetracknoir/facetracknoir.h @@ -1,295 +1,295 @@ -/******************************************************************************** -* 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 . * -*********************************************************************************/ - -#ifndef FaceTrackNoIR_H -#define FaceTrackNoIR_H - -#undef FTNOIR_PROTOCOL_BASE_LIB -#undef FTNOIR_TRACKER_BASE_LIB -#undef FTNOIR_FILTER_BASE_LIB -#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(_WIN32) && !defined(__WIN32) -# include -#else -# include -#endif -#include -#include -#include - - -#include "ui_facetracknoir.h" -#include "ui_ftnoir_keyboardshortcuts.h" -#include "ui_ftnoir_curves.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 "global-settings.h" -#include "tracker.h" - -class Tracker; // pre-define class to avoid circular includes -class FaceTrackNoIR; - -class KeybindingWorker; - -#if defined(__WIN32) || defined(_WIN32) -extern QList global_windows_key_sequences; -#undef DIRECTINPUT_VERSION -#define DIRECTINPUT_VERSION 0x0800 -#include -struct Key { - BYTE keycode; - bool shift; - bool ctrl; - bool alt; - bool ever_pressed; - QElapsedTimer timer; -public: - Key() : keycode(0), shift(false), ctrl(false), alt(false), ever_pressed(false) - { - } -}; -#else -typedef unsigned char BYTE; -struct Key { int foo; }; -#endif - -class FaceTrackNoIR : public QMainWindow, IDynamicLibraryProvider -{ - Q_OBJECT - -public: - FaceTrackNoIR(QWidget *parent = 0, Qt::WFlags flags = 0); - ~FaceTrackNoIR(); - - void updateSettings(); // Update the settings (let Tracker read INI-file). - - QFrame *get_video_widget(); // Get a pointer to the video-widget, to use in the DLL - Tracker *tracker; - void bindKeyboardShortcuts(); - DynamicLibrary* current_tracker1() { - 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() { - return dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); - } - DynamicLibrary* current_filter() { - return dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); - } - THeadPoseDOF& axis(int idx) { - return *pose.axes[idx]; - } - -#if defined(_WIN32) || defined(__WIN32) - Key keyCenter; - KeybindingWorker* keybindingWorker; -#else - QxtGlobalShortcut* keyCenter; -#endif -public slots: - void shortcutRecentered(); - -private: - HeadPoseData pose; - Ui::FaceTrackNoIRClass ui; - QTimer timUpdateHeadPose; // Timer to display headpose - QStringList iniFileList; // List of INI-files, that are present in the Settings folder - - 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) - - /** Widget variables **/ - QWidget *_keyboard_shortcuts; - QWidget *_curve_config; - - void createIconGroupBox(); -// void createMessageGroupBox(); - - /** helper **/ - bool cameraDetected; - bool settingsDirty; - - void GetCameraNameDX(); - void loadSettings(); - void setupFaceTrackNoIR(); - - QList dlopen_filters; - QList dlopen_trackers; - QList dlopen_protocols; - - bool looping; - - private slots: - //file menu - void open(); - void save(); - void saveAs(); - void exit(); -// void setIcon(int index); - void profileSelected(int index); - void protocolSelected(int index); - void filterSelected(int index); - void trackingSourceSelected(int index); - - void showVideoWidget(); - void showHeadPoseWidget(); - void showTrackerSettings(); - void showSecondTrackerSettings(); - - void showServerControls(); - void showFilterControls(); - void showKeyboardShortcuts(); - void showCurveConfiguration(); - - void setInvertAxis( Axis axis, int invert ); - void setInvertYaw(int invert) { - setInvertAxis(Yaw, invert); - } - void setInvertPitch(int invert) { - setInvertAxis(Pitch, invert); - } - void setInvertRoll(int invert) { - setInvertAxis(Roll, invert); - } - void setInvertX(int invert) { - setInvertAxis(TX, invert); - } - void setInvertY(int invert) { - setInvertAxis(TY, invert); - } - void setInvertZ(int invert) { - setInvertAxis(TZ, invert); - } - void showHeadPose(); - - void startTracker(); - void stopTracker(); - -}; - -class KeyboardShortcutDialog: public QWidget -{ - Q_OBJECT -public: - - explicit KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *parent=0, Qt::WindowFlags f=0 ); - virtual ~KeyboardShortcutDialog(); - void showEvent ( QShowEvent * event ); - -private: - Ui::UICKeyboardShortcutDialog ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FaceTrackNoIR *mainApp; - -private slots: - void doOK(); - void doCancel(); -}; - -// Widget that has controls for Keyboard shortcuts. -class CurveConfigurationDialog: public QWidget -{ - Q_OBJECT -public: - - explicit CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent=0, Qt::WindowFlags f=0 ); - virtual ~CurveConfigurationDialog(); - void showEvent ( QShowEvent * event ); - -private: - Ui::UICCurveConfigurationDialog ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FaceTrackNoIR *mainApp; - -private slots: - void doOK(); - void doCancel(); - void curveChanged( bool change ) { settingsDirty = true; } - void curveChanged( int change ) { settingsDirty = true; } -}; - -extern QList global_key_sequences; -#if defined(__WIN32) || defined(_WIN32) -class KeybindingWorkerDummy { -private: - LPDIRECTINPUT8 din; - LPDIRECTINPUTDEVICE8 dinkeyboard; - Key kCenter; - FaceTrackNoIR& window; -public: - volatile bool should_quit; - ~KeybindingWorkerDummy(); - KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter); - void run(); -}; -#else -class KeybindingWorkerDummy { -public: - KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter); - void run() {} -}; -#endif - -class KeybindingWorker : public QThread, public KeybindingWorkerDummy { - Q_OBJECT -public: - KeybindingWorker(FaceTrackNoIR& w, Key keyCenter) : KeybindingWorkerDummy(w, keyCenter) - { - } - void run() { - KeybindingWorkerDummy::run(); - } -}; - +/******************************************************************************** +* 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 . * +*********************************************************************************/ + +#ifndef FaceTrackNoIR_H +#define FaceTrackNoIR_H + +#undef FTNOIR_PROTOCOL_BASE_LIB +#undef FTNOIR_TRACKER_BASE_LIB +#undef FTNOIR_FILTER_BASE_LIB +#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_WIN32) && !defined(__WIN32) +# include +#else +# include +#endif +#include +#include +#include + + +#include "ui_facetracknoir.h" +#include "ui_ftnoir_keyboardshortcuts.h" +#include "ui_ftnoir_curves.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 "global-settings.h" +#include "tracker.h" + +class Tracker; // pre-define class to avoid circular includes +class FaceTrackNoIR; + +class KeybindingWorker; + +#if defined(__WIN32) || defined(_WIN32) +extern QList global_windows_key_sequences; +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 +#include +struct Key { + BYTE keycode; + bool shift; + bool ctrl; + bool alt; + bool ever_pressed; + QElapsedTimer timer; +public: + Key() : keycode(0), shift(false), ctrl(false), alt(false), ever_pressed(false) + { + } +}; +#else +typedef unsigned char BYTE; +struct Key { int foo; }; +#endif + +class FaceTrackNoIR : public QMainWindow, IDynamicLibraryProvider +{ + Q_OBJECT + +public: + FaceTrackNoIR(QWidget *parent = 0, Qt::WFlags flags = 0); + ~FaceTrackNoIR(); + + void updateSettings(); // Update the settings (let Tracker read INI-file). + + QFrame *get_video_widget(); // Get a pointer to the video-widget, to use in the DLL + Tracker *tracker; + void bindKeyboardShortcuts(); + DynamicLibrary* current_tracker1() { + 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() { + return dlopen_protocols.value(ui.iconcomboProtocol->currentIndex(), (DynamicLibrary*) NULL); + } + DynamicLibrary* current_filter() { + return dlopen_filters.value(ui.iconcomboFilter->currentIndex(), (DynamicLibrary*) NULL); + } + THeadPoseDOF& axis(int idx) { + return *pose.axes[idx]; + } + +#if defined(_WIN32) || defined(__WIN32) + Key keyCenter; + KeybindingWorker* keybindingWorker; +#else + QxtGlobalShortcut* keyCenter; +#endif +public slots: + void shortcutRecentered(); + +private: + HeadPoseData pose; + Ui::FaceTrackNoIRClass ui; + QTimer timUpdateHeadPose; // Timer to display headpose + QStringList iniFileList; // List of INI-files, that are present in the Settings folder + + 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) + + /** Widget variables **/ + QWidget *_keyboard_shortcuts; + QWidget *_curve_config; + + void createIconGroupBox(); +// void createMessageGroupBox(); + + /** helper **/ + bool cameraDetected; + bool settingsDirty; + + void GetCameraNameDX(); + void loadSettings(); + void setupFaceTrackNoIR(); + + QList dlopen_filters; + QList dlopen_trackers; + QList dlopen_protocols; + + bool looping; + + private slots: + //file menu + void open(); + void save(); + void saveAs(); + void exit(); +// void setIcon(int index); + void profileSelected(int index); + void protocolSelected(int index); + void filterSelected(int index); + void trackingSourceSelected(int index); + + void showVideoWidget(); + void showHeadPoseWidget(); + void showTrackerSettings(); + void showSecondTrackerSettings(); + + void showServerControls(); + void showFilterControls(); + void showKeyboardShortcuts(); + void showCurveConfiguration(); + + void setInvertAxis( Axis axis, int invert ); + void setInvertYaw(int invert) { + setInvertAxis(Yaw, invert); + } + void setInvertPitch(int invert) { + setInvertAxis(Pitch, invert); + } + void setInvertRoll(int invert) { + setInvertAxis(Roll, invert); + } + void setInvertX(int invert) { + setInvertAxis(TX, invert); + } + void setInvertY(int invert) { + setInvertAxis(TY, invert); + } + void setInvertZ(int invert) { + setInvertAxis(TZ, invert); + } + void showHeadPose(); + + void startTracker(); + void stopTracker(); + +}; + +class KeyboardShortcutDialog: public QWidget +{ + Q_OBJECT +public: + + explicit KeyboardShortcutDialog( FaceTrackNoIR *ftnoir, QWidget *parent=0, Qt::WindowFlags f=0 ); + virtual ~KeyboardShortcutDialog(); + void showEvent ( QShowEvent * event ); + +private: + Ui::UICKeyboardShortcutDialog ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FaceTrackNoIR *mainApp; + +private slots: + void doOK(); + void doCancel(); +}; + +// Widget that has controls for Keyboard shortcuts. +class CurveConfigurationDialog: public QWidget +{ + Q_OBJECT +public: + + explicit CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent=0, Qt::WindowFlags f=0 ); + virtual ~CurveConfigurationDialog(); + void showEvent ( QShowEvent * event ); + +private: + Ui::UICCurveConfigurationDialog ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FaceTrackNoIR *mainApp; + +private slots: + void doOK(); + void doCancel(); + void curveChanged( bool change ) { settingsDirty = true; } + void curveChanged( int change ) { settingsDirty = true; } +}; + +extern QList global_key_sequences; +#if defined(__WIN32) || defined(_WIN32) +class KeybindingWorkerDummy { +private: + LPDIRECTINPUT8 din; + LPDIRECTINPUTDEVICE8 dinkeyboard; + Key kCenter; + FaceTrackNoIR& window; +public: + volatile bool should_quit; + ~KeybindingWorkerDummy(); + KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter); + void run(); +}; +#else +class KeybindingWorkerDummy { +public: + KeybindingWorkerDummy(FaceTrackNoIR& w, Key keyCenter); + void run() {} +}; +#endif + +class KeybindingWorker : public QThread, public KeybindingWorkerDummy { + Q_OBJECT +public: + KeybindingWorker(FaceTrackNoIR& w, Key keyCenter) : KeybindingWorkerDummy(w, keyCenter) + { + } + void run() { + KeybindingWorkerDummy::run(); + } +}; + #endif // FaceTrackNoIR_H \ No newline at end of file diff --git a/facetracknoir/main.cpp b/facetracknoir/main.cpp index 7ff9f29f..bc0f973b 100644 --- a/facetracknoir/main.cpp +++ b/facetracknoir/main.cpp @@ -1,57 +1,57 @@ -/******************************************************************************** -* 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 . * -*********************************************************************************/ - -#include "facetracknoir.h" -#include "tracker.h" -#include -#include -#include -#include - -#if defined(_WIN32) -#include -//#pragma comment(linker, "/SUBSYSTEM:console /ENTRY:mainCRTStartup") -#endif -int main(int argc, char** argv) -{ -#if defined(_WIN32) - (void) timeBeginPeriod(1); -#endif - QApplication app(argc, argv); - QFont font; - font.setFamily(font.defaultFamily()); - font.setPointSize(9); - app.setFont(font); - FaceTrackNoIR w; - // - // Create the Main Window and DeskTop and Exec! - // - QDesktopWidget desktop; - w.move(desktop.screenGeometry().width()/2-w.width()/2, 100); - w.show(); - qApp->exec(); - - return 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 . * +*********************************************************************************/ + +#include "facetracknoir.h" +#include "tracker.h" +#include +#include +#include +#include + +#if defined(_WIN32) +#include +//#pragma comment(linker, "/SUBSYSTEM:console /ENTRY:mainCRTStartup") +#endif +int main(int argc, char** argv) +{ +#if defined(_WIN32) + (void) timeBeginPeriod(1); +#endif + QApplication app(argc, argv); + QFont font; + font.setFamily(font.defaultFamily()); + font.setPointSize(9); + app.setFont(font); + FaceTrackNoIR w; + // + // Create the Main Window and DeskTop and Exec! + // + QDesktopWidget desktop; + w.move(desktop.screenGeometry().width()/2-w.width()/2, 100); + w.show(); + qApp->exec(); + + return 0; +} + diff --git a/facetracknoir/rotation.h b/facetracknoir/rotation.h index dd70ca77..e97ec0f0 100644 --- a/facetracknoir/rotation.h +++ b/facetracknoir/rotation.h @@ -1,64 +1,64 @@ -/* 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 -// ---------------------------------------------------------------------------- -class Rotation { - -public: - Rotation() : a(1.0),b(0.0),c(0.0),d(0.0) {} - Rotation(double yaw, double pitch, double roll) { fromEuler(yaw, pitch, roll); } - Rotation(double a, double b, double c, double d) : a(a),b(b),c(c),d(d) {} - - Rotation inv(){ // inverse - return Rotation(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) - { - 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 Rotation operator*(const Rotation& B) - { - const Rotation& A = *this; - return Rotation(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 +/* 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 +// ---------------------------------------------------------------------------- +class Rotation { + +public: + Rotation() : a(1.0),b(0.0),c(0.0),d(0.0) {} + Rotation(double yaw, double pitch, double roll) { fromEuler(yaw, pitch, roll); } + Rotation(double a, double b, double c, double d) : a(a),b(b),c(c),d(d) {} + + Rotation inv(){ // inverse + return Rotation(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) + { + 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 Rotation operator*(const Rotation& B) + { + const Rotation& A = *this; + return Rotation(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/tracker.cpp b/facetracknoir/tracker.cpp index f2b4845f..47daa697 100644 --- a/facetracknoir/tracker.cpp +++ b/facetracknoir/tracker.cpp @@ -1,218 +1,218 @@ -/******************************************************************************** -* 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) 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 . * -*********************************************************************************/ -#include "tracker.h" -#include "facetracknoir.h" - -/** constructor **/ -Tracker::Tracker( FaceTrackNoIR *parent ) : - should_quit(false), - do_center(false) -{ - // Retieve the pointer to the parent - mainApp = parent; - // Load the settings from the INI-file - loadSettings(); -} - -Tracker::~Tracker() -{ -} - -static void get_curve(double pos, double& out, THeadPoseDOF& axis) { - bool altp = (pos < 0) && axis.altp; - if (altp) { - out = axis.invert * axis.curveAlt.getValue(pos); - axis.curve.setTrackingActive( false ); - axis.curveAlt.setTrackingActive( true ); - } - else { - out = axis.invert * axis.curve.getValue(pos); - axis.curve.setTrackingActive( true ); - axis.curveAlt.setTrackingActive( false ); - } - out += axis.zero; -} - -/** QThread run method @override **/ -void Tracker::run() { - T6DOF current_camera; // Used for filtering - T6DOF target_camera; - T6DOF new_camera; - - /** Direct Input variables **/ - T6DOF offset_camera; - T6DOF gameoutput_camera; - - bool bTracker1Confid = false; - bool bTracker2Confid = false; - - double newpose[6]; - double last_post_filter[6]; - - forever - { - if (should_quit) - break; - - for (int i = 0; i < 6; i++) - newpose[i] = 0; - - // - // 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); - } - - { - QMutexLocker foo(&mtx); - const bool confid = bTracker1Confid || bTracker2Confid; - - if ( confid ) { - for (int i = 0; i < 6; i++) - mainApp->axis(i).headPos = newpose[i]; - } - - // - // If Center is pressed, copy the current values to the offsets. - // - if (do_center) { - // - // Only copy valid values - // - for (int i = 0; i < 6; i++) - offset_camera.axes[i] = mainApp->axis(i).headPos; - - Tracker::do_center = false; - - if (Libraries->pTracker) - Libraries->pTracker->NotifyCenter(); - - if (Libraries->pSecondTracker) - Libraries->pSecondTracker->NotifyCenter(); - - if (Libraries->pFilter) - Libraries->pFilter->Initialize(); - } - - if (confid) { - // get values - for (int i = 0; i < 6; i++) - target_camera.axes[i] = mainApp->axis(i).headPos; - - // do the centering - target_camera = target_camera - offset_camera; - - // - // Use advanced filtering, when a filter was selected. - // - if (Libraries->pFilter) { - for (int i = 0; i < 6; i++) - last_post_filter[i] = gameoutput_camera.axes[i]; - Libraries->pFilter->FilterHeadPoseData(current_camera.axes, target_camera.axes, new_camera.axes, last_post_filter); - } - else { - new_camera = target_camera; - } - - for (int i = 0; i < 6; i++) { - get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i)); - } - - // - // Send the headpose to the game - // - if (Libraries->pProtocol) { - gameoutput_camera = output_camera; - Libraries->pProtocol->sendHeadposeToGame( gameoutput_camera.axes, newpose ); // degrees & centimeters - } - } - } - - //for lower cpu load - msleep(8); - } - - for (int i = 0; i < 6; i++) - { - mainApp->axis(i).curve.setTrackingActive(false); - mainApp->axis(i).curveAlt.setTrackingActive(false); - } -} - -// -// Get the raw headpose, so it can be displayed. -// -void Tracker::getHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - { - data[i] = mainApp->axis(i).headPos; - } -} - -// -// Get the output-headpose, so it can be displayed. -// -void Tracker::getOutputHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - data[i] = output_camera.axes[i]; -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void Tracker::loadSettings() { - qDebug() << "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("Tracking"); - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - const char* names2[] = { - "zero_tx", - "zero_ty", - "zero_tz", - "zero_rx", - "zero_ry", - "zero_rz" - }; - - for (int i = 0; i < 6; i++) - mainApp->axis(i).zero = iniFile.value(names2[i], 0).toDouble(); - - iniFile.endGroup(); -} - -void Tracker::setInvertAxis(Axis axis, bool invert) { mainApp->axis(axis).invert = invert?-1.0f:1.0f; } +/******************************************************************************** +* 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) 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 . * +*********************************************************************************/ +#include "tracker.h" +#include "facetracknoir.h" + +/** constructor **/ +Tracker::Tracker( FaceTrackNoIR *parent ) : + should_quit(false), + do_center(false) +{ + // Retieve the pointer to the parent + mainApp = parent; + // Load the settings from the INI-file + loadSettings(); +} + +Tracker::~Tracker() +{ +} + +static void get_curve(double pos, double& out, THeadPoseDOF& axis) { + bool altp = (pos < 0) && axis.altp; + if (altp) { + out = axis.invert * axis.curveAlt.getValue(pos); + axis.curve.setTrackingActive( false ); + axis.curveAlt.setTrackingActive( true ); + } + else { + out = axis.invert * axis.curve.getValue(pos); + axis.curve.setTrackingActive( true ); + axis.curveAlt.setTrackingActive( false ); + } + out += axis.zero; +} + +/** QThread run method @override **/ +void Tracker::run() { + T6DOF current_camera; // Used for filtering + T6DOF target_camera; + T6DOF new_camera; + + /** Direct Input variables **/ + T6DOF offset_camera; + T6DOF gameoutput_camera; + + bool bTracker1Confid = false; + bool bTracker2Confid = false; + + double newpose[6]; + double last_post_filter[6]; + + forever + { + if (should_quit) + break; + + for (int i = 0; i < 6; i++) + newpose[i] = 0; + + // + // 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); + } + + { + QMutexLocker foo(&mtx); + const bool confid = bTracker1Confid || bTracker2Confid; + + if ( confid ) { + for (int i = 0; i < 6; i++) + mainApp->axis(i).headPos = newpose[i]; + } + + // + // If Center is pressed, copy the current values to the offsets. + // + if (do_center) { + // + // Only copy valid values + // + for (int i = 0; i < 6; i++) + offset_camera.axes[i] = mainApp->axis(i).headPos; + + Tracker::do_center = false; + + if (Libraries->pTracker) + Libraries->pTracker->NotifyCenter(); + + if (Libraries->pSecondTracker) + Libraries->pSecondTracker->NotifyCenter(); + + if (Libraries->pFilter) + Libraries->pFilter->Initialize(); + } + + if (confid) { + // get values + for (int i = 0; i < 6; i++) + target_camera.axes[i] = mainApp->axis(i).headPos; + + // do the centering + target_camera = target_camera - offset_camera; + + // + // Use advanced filtering, when a filter was selected. + // + if (Libraries->pFilter) { + for (int i = 0; i < 6; i++) + last_post_filter[i] = gameoutput_camera.axes[i]; + Libraries->pFilter->FilterHeadPoseData(current_camera.axes, target_camera.axes, new_camera.axes, last_post_filter); + } + else { + new_camera = target_camera; + } + + for (int i = 0; i < 6; i++) { + get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i)); + } + + // + // Send the headpose to the game + // + if (Libraries->pProtocol) { + gameoutput_camera = output_camera; + Libraries->pProtocol->sendHeadposeToGame( gameoutput_camera.axes, newpose ); // degrees & centimeters + } + } + } + + //for lower cpu load + msleep(8); + } + + for (int i = 0; i < 6; i++) + { + mainApp->axis(i).curve.setTrackingActive(false); + mainApp->axis(i).curveAlt.setTrackingActive(false); + } +} + +// +// Get the raw headpose, so it can be displayed. +// +void Tracker::getHeadPose( double *data ) { + QMutexLocker foo(&mtx); + for (int i = 0; i < 6; i++) + { + data[i] = mainApp->axis(i).headPos; + } +} + +// +// Get the output-headpose, so it can be displayed. +// +void Tracker::getOutputHeadPose( double *data ) { + QMutexLocker foo(&mtx); + for (int i = 0; i < 6; i++) + data[i] = output_camera.axes[i]; +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void Tracker::loadSettings() { + qDebug() << "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("Tracking"); + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + const char* names2[] = { + "zero_tx", + "zero_ty", + "zero_tz", + "zero_rx", + "zero_ry", + "zero_rz" + }; + + for (int i = 0; i < 6; i++) + mainApp->axis(i).zero = iniFile.value(names2[i], 0).toDouble(); + + iniFile.endGroup(); +} + +void Tracker::setInvertAxis(Axis axis, bool invert) { mainApp->axis(axis).invert = invert?-1.0f:1.0f; } diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h index 7e2b84cd..eeb18dad 100644 --- a/facetracknoir/tracker.h +++ b/facetracknoir/tracker.h @@ -1,145 +1,145 @@ -/******************************************************************************** -* 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 - 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 . * -*********************************************************************************/ -#ifndef __TRACKER_H__ -#define __TRACKER_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "global-settings.h" -#include - -//#define DIRECTINPUT_VERSION 0x0800 -//#include -#undef FTNOIR_PROTOCOL_BASE_LIB -#undef FTNOIR_TRACKER_BASE_LIB -#undef FTNOIR_FILTER_BASE_LIB -#undef FTNOIR_PROTOCOL_BASE_EXPORT -#undef FTNOIR_TRACKER_BASE_EXPORT -#undef FTNOIR_FILTER_BASE_EXPORT -#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT - -#include -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ftnoir_filter_base/ftnoir_filter_base.h" -#include "tracker_types.h" - -class FaceTrackNoIR; // pre-define parent-class to avoid circular includes - -// -// Structure to hold all variables concerning one of 6 DOF's -// -class THeadPoseDOF { -private: - THeadPoseDOF(const THeadPoseDOF &) {} -public: - THeadPoseDOF() : - headPos(0), - invert(0), - altp(false), - zero(0) - { - } - - THeadPoseDOF(QString primary, - QString secondary, - int maxInput1, - int maxOutput1, - int maxInput2, - int maxOutput2) : - curve(primary, maxInput1, maxOutput1), - curveAlt(secondary, maxInput2, maxOutput2), - headPos(0), - invert(1), - zero(0) - { - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - curve.loadSettings(iniFile); - curveAlt.loadSettings(iniFile); - - iniFile.beginGroup("Tracking"); - altp = iniFile.value(secondary).toBool(); - iniFile.endGroup(); - } - double headPos; // Current position (from faceTracker, radials or meters) - float invert; // Invert measured value (= 1.0f or -1.0f) - FunctionConfig curve; // Function to translate input -> output - FunctionConfig curveAlt; - bool altp; - double zero; -}; - -class Tracker : public QThread { - Q_OBJECT - -private: - FaceTrackNoIR *mainApp; - QMutex mtx; - -protected: - // qthread override run method - void run(); - -public: - Tracker( FaceTrackNoIR *parent ); - ~Tracker(); - void loadSettings(); // Load settings from the INI-file - - void setInvertAxis(Axis axis, bool invert); - - void getHeadPose(double *data); // Return the current headpose data - void getOutputHeadPose(double *data); // Return the current (processed) headpose data - - volatile bool should_quit; - // following are now protected by hTrackMutex - volatile bool do_center; // Center head-position, using the shortkey - - T6DOF output_camera; -}; - -class HeadPoseData { -public: - THeadPoseDOF* axes[6]; - HeadPoseData() - { - axes[TX] = new THeadPoseDOF("tx","tx_alt", 100, 100, 100, 100); - axes[TY] = new THeadPoseDOF("ty","ty_alt", 100, 100, 100, 100); - axes[TZ] = new THeadPoseDOF("tz","tz_alt", 100, 100, 100, 100); - axes[Yaw] = new THeadPoseDOF("rx", "rx_alt", 180, 180, 180, 180); - axes[Pitch] = new THeadPoseDOF("ry", "ry_alt", 90, 90, 90, 90); - axes[Roll] = new THeadPoseDOF("rz", "rz_alt", 180, 180, 180, 180); - } -}; - -#endif +/******************************************************************************** +* 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 - 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 . * +*********************************************************************************/ +#ifndef __TRACKER_H__ +#define __TRACKER_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "global-settings.h" +#include + +//#define DIRECTINPUT_VERSION 0x0800 +//#include +#undef FTNOIR_PROTOCOL_BASE_LIB +#undef FTNOIR_TRACKER_BASE_LIB +#undef FTNOIR_FILTER_BASE_LIB +#undef FTNOIR_PROTOCOL_BASE_EXPORT +#undef FTNOIR_TRACKER_BASE_EXPORT +#undef FTNOIR_FILTER_BASE_EXPORT +#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT + +#include +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ftnoir_filter_base/ftnoir_filter_base.h" +#include "tracker_types.h" + +class FaceTrackNoIR; // pre-define parent-class to avoid circular includes + +// +// Structure to hold all variables concerning one of 6 DOF's +// +class THeadPoseDOF { +private: + THeadPoseDOF(const THeadPoseDOF &) {} +public: + THeadPoseDOF() : + headPos(0), + invert(0), + altp(false), + zero(0) + { + } + + THeadPoseDOF(QString primary, + QString secondary, + int maxInput1, + int maxOutput1, + int maxInput2, + int maxOutput2) : + curve(primary, maxInput1, maxOutput1), + curveAlt(secondary, maxInput2, maxOutput2), + headPos(0), + invert(1), + zero(0) + { + QSettings settings("opentrack"); // Registry settings (in HK_USER) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); + curve.loadSettings(iniFile); + curveAlt.loadSettings(iniFile); + + iniFile.beginGroup("Tracking"); + altp = iniFile.value(secondary).toBool(); + iniFile.endGroup(); + } + double headPos; // Current position (from faceTracker, radials or meters) + float invert; // Invert measured value (= 1.0f or -1.0f) + FunctionConfig curve; // Function to translate input -> output + FunctionConfig curveAlt; + bool altp; + double zero; +}; + +class Tracker : public QThread { + Q_OBJECT + +private: + FaceTrackNoIR *mainApp; + QMutex mtx; + +protected: + // qthread override run method + void run(); + +public: + Tracker( FaceTrackNoIR *parent ); + ~Tracker(); + void loadSettings(); // Load settings from the INI-file + + void setInvertAxis(Axis axis, bool invert); + + void getHeadPose(double *data); // Return the current headpose data + void getOutputHeadPose(double *data); // Return the current (processed) headpose data + + volatile bool should_quit; + // following are now protected by hTrackMutex + volatile bool do_center; // Center head-position, using the shortkey + + T6DOF output_camera; +}; + +class HeadPoseData { +public: + THeadPoseDOF* axes[6]; + HeadPoseData() + { + axes[TX] = new THeadPoseDOF("tx","tx_alt", 100, 100, 100, 100); + axes[TY] = new THeadPoseDOF("ty","ty_alt", 100, 100, 100, 100); + axes[TZ] = new THeadPoseDOF("tz","tz_alt", 100, 100, 100, 100); + axes[Yaw] = new THeadPoseDOF("rx", "rx_alt", 180, 180, 180, 180); + axes[Pitch] = new THeadPoseDOF("ry", "ry_alt", 90, 90, 90, 90); + axes[Roll] = new THeadPoseDOF("rz", "rz_alt", 180, 180, 180, 180); + } +}; + +#endif diff --git a/facetracknoir/tracker_types.cpp b/facetracknoir/tracker_types.cpp index 11adc985..da246722 100644 --- a/facetracknoir/tracker_types.cpp +++ b/facetracknoir/tracker_types.cpp @@ -1,44 +1,44 @@ -#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) -{ - Rotation R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R); - Rotation R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R); - Rotation 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) -{ - Rotation R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R); - Rotation R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R); - Rotation 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; -} +#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) +{ + Rotation R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R); + Rotation R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R); + Rotation 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) +{ + Rotation R_A(A.axes[Yaw]*D2R, A.axes[Pitch]*D2R, A.axes[Roll]*D2R); + Rotation R_B(B.axes[Yaw]*D2R, B.axes[Pitch]*D2R, B.axes[Roll]*D2R); + Rotation 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 index ebd89e7c..54d1841e 100644 --- a/facetracknoir/tracker_types.h +++ b/facetracknoir/tracker_types.h @@ -1,41 +1,41 @@ -/******************************************************************************** -* 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 - 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 . * -*********************************************************************************/ -#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__ +/******************************************************************************** +* 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 - 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 . * +*********************************************************************************/ +#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/freetrackclient/ftclient.h b/freetrackclient/ftclient.h index 406e1237..5e5d8747 100644 --- a/freetrackclient/ftclient.h +++ b/freetrackclient/ftclient.h @@ -1,30 +1,30 @@ -/** @file - @brief -*/ -#pragma once -#ifndef INCLUDED_FTCLIENT_H -#define INCLUDED_FTCLIENT_H - - - - - - -#include "Windows.h" -#include "SysUtils.h" -#include "FTTypes.h" - -/*__stdcall*/ bool FTGetData(PFreetrackData data); -/*__stdcall*/ void FTReportName(PAnsiChar name); -/*__stdcall*/ char* FTGetDllVersion(); -/*__stdcall*/ char* FTProvider(); - - -bool OpenMapping(); -void DestroyMapping(); - - - - -#endif//INCLUDED_FTCLIENT_H -//END +/** @file + @brief +*/ +#pragma once +#ifndef INCLUDED_FTCLIENT_H +#define INCLUDED_FTCLIENT_H + + + + + + +#include "Windows.h" +#include "SysUtils.h" +#include "FTTypes.h" + +/*__stdcall*/ bool FTGetData(PFreetrackData data); +/*__stdcall*/ void FTReportName(PAnsiChar name); +/*__stdcall*/ char* FTGetDllVersion(); +/*__stdcall*/ char* FTProvider(); + + +bool OpenMapping(); +void DestroyMapping(); + + + + +#endif//INCLUDED_FTCLIENT_H +//END diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index c2cda351..0b3d6518 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -1,90 +1,90 @@ -/* Copyright (c) 2012 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 -#include -#include -#include "facetracknoir/global-settings.h" - -using namespace std; - -FTNoIR_Filter::FTNoIR_Filter() -{ - first_run = true; - loadSettings(); -} - -FTNoIR_Filter::~FTNoIR_Filter() -{ - -} - -void FTNoIR_Filter::loadSettings() { - 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 ( "Accela" ); - zoom_factor = iniFile.value("zoom-slowness", 0).toDouble(); - rotation_alpha = iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble(); - translation_alpha = iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble(); - iniFile.endGroup (); -} - -void FTNoIR_Filter::receiveSettings(double rot, double trans, double zoom_fac) -{ - QMutexLocker foo(&mutex); - - rotation_alpha = rot; - translation_alpha = trans; - zoom_factor = zoom_fac; -} - -static double parabola(const double a, const double x) -{ - const double a1 = 1./a; - return a1 * x * x; -} - -void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, - double *target_camera_position, - double *new_camera_position, - double *last_post_filter_values) -{ - if (first_run) - { - for (int i = 0; i < 6; i++) - { - new_camera_position[i] = target_camera_position[i]; - current_camera_position[i] = target_camera_position[i]; - } - - first_run = false; - return; - } - - QMutexLocker foo(&mutex); - - for (int i=0;i<6;i++) - { - const double vec = target_camera_position[i] - current_camera_position[i]; - const int sign = vec < 0 ? -1 : 1; - const double x = fabs(vec); - const double a = i >= 3 ? rotation_alpha : translation_alpha; - const double reduction = 1. / std::max(1., 1. + zoom_factor * -last_post_filter_values[TZ] / 1000); - const double velocity = parabola(a, x) * reduction; - const double result = current_camera_position[i] + velocity * sign; - const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i]; - new_camera_position[i] = current_camera_position[i] = done ? target_camera_position[i] : result; - } -} - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Filter; -} +/* Copyright (c) 2012 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 +#include +#include +#include "facetracknoir/global-settings.h" + +using namespace std; + +FTNoIR_Filter::FTNoIR_Filter() +{ + first_run = true; + loadSettings(); +} + +FTNoIR_Filter::~FTNoIR_Filter() +{ + +} + +void FTNoIR_Filter::loadSettings() { + 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 ( "Accela" ); + zoom_factor = iniFile.value("zoom-slowness", 0).toDouble(); + rotation_alpha = iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble(); + translation_alpha = iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble(); + iniFile.endGroup (); +} + +void FTNoIR_Filter::receiveSettings(double rot, double trans, double zoom_fac) +{ + QMutexLocker foo(&mutex); + + rotation_alpha = rot; + translation_alpha = trans; + zoom_factor = zoom_fac; +} + +static double parabola(const double a, const double x) +{ + const double a1 = 1./a; + return a1 * x * x; +} + +void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, + double *target_camera_position, + double *new_camera_position, + double *last_post_filter_values) +{ + if (first_run) + { + for (int i = 0; i < 6; i++) + { + new_camera_position[i] = target_camera_position[i]; + current_camera_position[i] = target_camera_position[i]; + } + + first_run = false; + return; + } + + QMutexLocker foo(&mutex); + + for (int i=0;i<6;i++) + { + const double vec = target_camera_position[i] - current_camera_position[i]; + const int sign = vec < 0 ? -1 : 1; + const double x = fabs(vec); + const double a = i >= 3 ? rotation_alpha : translation_alpha; + const double reduction = 1. / std::max(1., 1. + zoom_factor * -last_post_filter_values[TZ] / 1000); + const double velocity = parabola(a, x) * reduction; + const double result = current_camera_position[i] + velocity * sign; + const bool done = sign > 0 ? result >= target_camera_position[i] : result <= target_camera_position[i]; + new_camera_position[i] = current_camera_position[i] = done ? target_camera_position[i] : result; + } +} + +extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Filter; +} diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h index 0c13c0e8..49b551e7 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -1,107 +1,107 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#pragma once -#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_accela_filtercontrols.h" -#include "facetracknoir/global-settings.h" -#include - -#define ACCELA_SMOOTHING_ROTATION 6.0 -#define ACCELA_SMOOTHING_TRANSLATION 3.0 - -//******************************************************************************************************* -// FaceTrackNoIR Filter class. -//******************************************************************************************************* -class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter -{ -public: - FTNoIR_Filter(); - ~FTNoIR_Filter(); - void FilterHeadPoseData(double *current_camera_position, double *target_camera_position, double *new_camera_position, double *last_post_filter_values); - void Initialize() { - first_run = true; - } - void receiveSettings(double rot, double trans, double zoom_fac); -private: - QMutex mutex; - void loadSettings(); - bool first_run; - double rotation_alpha, translation_alpha, zoom_factor; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* - -// Widget that has controls for FTNoIR protocol filter-settings. -class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog -{ - Q_OBJECT -public: - explicit FilterControls(); - virtual ~FilterControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerFilter(IFilter* filter); - void unregisterFilter(); -private: - Ui::AccelaUICFilterControls ui; - void loadSettings(); - void save(); - bool settingsDirty; - FTNoIR_Filter* accela_filter; -private slots: - void doOK(); - void doCancel(); - void settingChanged(bool) { settingsDirty = true; } - void settingChanged(int) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter -//******************************************************************************************************* -class FTNoIR_FilterDll : public Metadata -{ -public: - FTNoIR_FilterDll(); - ~FTNoIR_FilterDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk3"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk3"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk3"); } - - void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } -}; - - -#endif //INCLUDED_FTN_FILTER_H -//END - +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#pragma once +#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_accela_filtercontrols.h" +#include "facetracknoir/global-settings.h" +#include + +#define ACCELA_SMOOTHING_ROTATION 6.0 +#define ACCELA_SMOOTHING_TRANSLATION 3.0 + +//******************************************************************************************************* +// FaceTrackNoIR Filter class. +//******************************************************************************************************* +class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter +{ +public: + FTNoIR_Filter(); + ~FTNoIR_Filter(); + void FilterHeadPoseData(double *current_camera_position, double *target_camera_position, double *new_camera_position, double *last_post_filter_values); + void Initialize() { + first_run = true; + } + void receiveSettings(double rot, double trans, double zoom_fac); +private: + QMutex mutex; + void loadSettings(); + bool first_run; + double rotation_alpha, translation_alpha, zoom_factor; +}; + +//******************************************************************************************************* +// FaceTrackNoIR Filter Settings-dialog. +//******************************************************************************************************* + +// Widget that has controls for FTNoIR protocol filter-settings. +class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog +{ + Q_OBJECT +public: + explicit FilterControls(); + virtual ~FilterControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerFilter(IFilter* filter); + void unregisterFilter(); +private: + Ui::AccelaUICFilterControls ui; + void loadSettings(); + void save(); + bool settingsDirty; + FTNoIR_Filter* accela_filter; +private slots: + void doOK(); + void doCancel(); + void settingChanged(bool) { settingsDirty = true; } + void settingChanged(int) { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter +//******************************************************************************************************* +class FTNoIR_FilterDll : public Metadata +{ +public: + FTNoIR_FilterDll(); + ~FTNoIR_FilterDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Filter Mk3"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Accela Mk3"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Accela filter Mk3"); } + + void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } +}; + + +#endif //INCLUDED_FTN_FILTER_H +//END + diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp index 8c7cd386..3e74ad81 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp @@ -1,190 +1,190 @@ -/******************************************************************************** -* 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) 2013 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 . * -* * -********************************************************************************/ -#include "ftnoir_filter_accela/ftnoir_filter_accela.h" -#include -#include -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* -// -// Constructor for server-settings-dialog -// -FilterControls::FilterControls() : - QWidget(), accela_filter(NULL) -{ - ui.setupUi( this ); - - // Load the settings from the current .INI-file - loadSettings(); - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.rotation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); - connect(ui.translation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); - - connect(ui.slideZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.spinZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); - - qDebug() << "FilterControls() says: started"; -} - -// -// Destructor for server-dialog -// -FilterControls::~FilterControls() { - qDebug() << "~FilterControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FilterControls::Initialize(QWidget *parent) { - loadSettings(); - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -void FilterControls::registerFilter(IFilter* filter) -{ - accela_filter = (FTNoIR_Filter*) filter; -} - -void FilterControls::unregisterFilter() -{ - accela_filter = NULL; -} - -// -// OK clicked on server-dialog -// -void FilterControls::doOK() { - save(); - this->close(); -} - -// override show event -void FilterControls::showEvent ( QShowEvent * event ) { -} - -// -// Cancel clicked on server-dialog -// -void FilterControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FilterControls::loadSettings() { - 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) - - qDebug() << "FTNoIR_Filter::loadSettings2 says: iniFile = " << currentFile; - - //qDebug() << "FTNoIR_Filter::loadSettings2 says: size = " << NUM_OF(defScaleRotation); - - iniFile.beginGroup ( "Accela" ); - ui.slideZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); - ui.spinZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); - ui.rotation_alpha->setValue(iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble()); - ui.translation_alpha->setValue(iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble()); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FilterControls::save() { - 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) - - qDebug() << "FTNoIR_Filter::save() says: iniFile = " << currentFile; - - double rot, trans, zoom; - - iniFile.beginGroup ( "Accela" ); - iniFile.setValue("zoom-slowness", zoom = ui.slideZoom->value()); - iniFile.setValue("rotation-alpha", rot = ui.rotation_alpha->value()); - iniFile.setValue("translation-alpha", trans = ui.translation_alpha->value()); - iniFile.endGroup (); - - settingsDirty = false; - - if (accela_filter) - accela_filter->receiveSettings(rot, trans, zoom); -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter-settings dialog object. - -// Export both decorated and undecorated names. -// GetFilterDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetFilterDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0") - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog() -{ - return new FilterControls; -} +/******************************************************************************** +* 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) 2013 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 . * +* * +********************************************************************************/ +#include "ftnoir_filter_accela/ftnoir_filter_accela.h" +#include +#include +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Filter Settings-dialog. +//******************************************************************************************************* +// +// Constructor for server-settings-dialog +// +FilterControls::FilterControls() : + QWidget(), accela_filter(NULL) +{ + ui.setupUi( this ); + + // Load the settings from the current .INI-file + loadSettings(); + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.rotation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); + connect(ui.translation_alpha, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(int))); + + connect(ui.slideZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.spinZoom, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + + qDebug() << "FilterControls() says: started"; +} + +// +// Destructor for server-dialog +// +FilterControls::~FilterControls() { + qDebug() << "~FilterControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FilterControls::Initialize(QWidget *parent) { + loadSettings(); + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +void FilterControls::registerFilter(IFilter* filter) +{ + accela_filter = (FTNoIR_Filter*) filter; +} + +void FilterControls::unregisterFilter() +{ + accela_filter = NULL; +} + +// +// OK clicked on server-dialog +// +void FilterControls::doOK() { + save(); + this->close(); +} + +// override show event +void FilterControls::showEvent ( QShowEvent * event ) { +} + +// +// Cancel clicked on server-dialog +// +void FilterControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FilterControls::loadSettings() { + 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) + + qDebug() << "FTNoIR_Filter::loadSettings2 says: iniFile = " << currentFile; + + //qDebug() << "FTNoIR_Filter::loadSettings2 says: size = " << NUM_OF(defScaleRotation); + + iniFile.beginGroup ( "Accela" ); + ui.slideZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); + ui.spinZoom->setValue(iniFile.value("zoom-slowness", 0).toInt()); + ui.rotation_alpha->setValue(iniFile.value("rotation-alpha", ACCELA_SMOOTHING_ROTATION).toDouble()); + ui.translation_alpha->setValue(iniFile.value("translation-alpha", ACCELA_SMOOTHING_TRANSLATION).toDouble()); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FilterControls::save() { + 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) + + qDebug() << "FTNoIR_Filter::save() says: iniFile = " << currentFile; + + double rot, trans, zoom; + + iniFile.beginGroup ( "Accela" ); + iniFile.setValue("zoom-slowness", zoom = ui.slideZoom->value()); + iniFile.setValue("rotation-alpha", rot = ui.rotation_alpha->value()); + iniFile.setValue("translation-alpha", trans = ui.translation_alpha->value()); + iniFile.endGroup (); + + settingsDirty = false; + + if (accela_filter) + accela_filter->receiveSettings(rot, trans, zoom); +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Filter-settings dialog object. + +// Export both decorated and undecorated names. +// GetFilterDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetFilterDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0") + +extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION 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 0235c067..d4a11028 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dll.cpp @@ -1,39 +1,39 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_filter_accela.h" -#include "facetracknoir/global-settings.h" - -FTNoIR_FilterDll::FTNoIR_FilterDll() { -} - -FTNoIR_FilterDll::~FTNoIR_FilterDll() -{ - -} - -extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() -{ - return new FTNoIR_FilterDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_filter_accela.h" +#include "facetracknoir/global-settings.h" + +FTNoIR_FilterDll::FTNoIR_FilterDll() { +} + +FTNoIR_FilterDll::~FTNoIR_FilterDll() +{ + +} + +extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +{ + return new FTNoIR_FilterDll; +} diff --git a/ftnoir_filter_base/ftnoir_filter_base.h b/ftnoir_filter_base/ftnoir_filter_base.h index 9ff286b1..49454a7e 100644 --- a/ftnoir_filter_base/ftnoir_filter_base.h +++ b/ftnoir_filter_base/ftnoir_filter_base.h @@ -1,41 +1,41 @@ -#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 -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -# define EXTERN_C extern "C" -#else -# define EXTERN_C -#endif // __cplusplus - -//////////////////////////////////////////////////////////////////////////////// -// 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 IFilter -{ - virtual ~IFilter() {} - virtual void FilterHeadPoseData(double *current_camera_position, double *target_camera_position, double *new_camera_position, double *last_post_filter) = 0; - virtual void Initialize() = 0; -}; - -struct IFilterDialog -{ - virtual ~IFilterDialog() {} - virtual void Initialize(QWidget *parent) = 0; - virtual void registerFilter(IFilter* tracker) = 0; - virtual void unregisterFilter() = 0; -}; - -#endif // FTNOIR_FILTER_BASE_H +#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 +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif // __cplusplus + +//////////////////////////////////////////////////////////////////////////////// +// 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 IFilter +{ + virtual ~IFilter() {} + virtual void FilterHeadPoseData(double *current_camera_position, double *target_camera_position, double *new_camera_position, double *last_post_filter) = 0; + virtual void Initialize() = 0; +}; + +struct IFilterDialog +{ + virtual ~IFilterDialog() {} + virtual void Initialize(QWidget *parent) = 0; + 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 index a923f6cf..02733ace 100644 --- a/ftnoir_filter_base/ftnoir_filter_base_global.h +++ b/ftnoir_filter_base/ftnoir_filter_base_global.h @@ -1,12 +1,12 @@ -#ifndef FTNOIR_FILTER_BASE_GLOBAL_H -#define FTNOIR_FILTER_BASE_GLOBAL_H - -#include - -#ifdef FTNOIR_FILTER_BASE_LIB -# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT -#else -# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT -#endif - -#endif // FTNOIR_FILTER_BASE_GLOBAL_H +#ifndef FTNOIR_FILTER_BASE_GLOBAL_H +#define FTNOIR_FILTER_BASE_GLOBAL_H + +#include + +#ifdef FTNOIR_FILTER_BASE_LIB +# define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT +#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 43cfd102..b127c665 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp @@ -1,173 +1,173 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_filter_ewma2.h" -#include "math.h" -#include -#include -#include "facetracknoir/global-settings.h" -#include -#include -//#define LOG_OUTPUT - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -FTNoIR_Filter::FTNoIR_Filter() -{ - first_run = true; - alpha_smoothing = 0.02f; // this is a constant for now, might be a parameter later - loadSettings(); // Load the Settings -} - -FTNoIR_Filter::~FTNoIR_Filter() -{ -} - -void FTNoIR_Filter::receiveSettings(double smin, double smax, double sexpt) -{ - QMutexLocker foo(&mutex); - - kMinSmoothing = smin; - kMaxSmoothing = smax; - kSmoothingScaleCurve = sexpt; -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Filter::loadSettings() { - qDebug() << "FTNoIR_Filter::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) - - qDebug() << "FTNoIR_Filter::loadSettings says: iniFile = " << currentFile; - - // - // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR - // - iniFile.beginGroup ( "Tracking" ); - kMinSmoothing = iniFile.value ( "minSmooth", 15 ).toInt(); - kMaxSmoothing = iniFile.value ( "maxSmooth", 50 ).toInt(); - kSmoothingScaleCurve = iniFile.value ( "powCurve", 10 ).toInt(); - iniFile.endGroup (); -} - -void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, - double *target_camera_position, - double *new_camera_position, - double *last_post_filter) -{ - double delta; - double new_alpha; - double scale[]={0.025f,0.025f,0.025f,6.0f,6.0f,6.0f}; - - //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]; - alpha[i] = 0.0f; - } - first_run=false; - return; - } - - QMutexLocker foo(&mutex); - - for (int i=0;i<6;i++) { - // Calculate the delta. - delta=target_camera_position[i]-current_camera_position[i]; - // Normalise the delta. - delta=std::min(std::max(fabs(delta)/scale[i],0.0),1.0); - // Calculate the new alpha from the normalized delta. - new_alpha=1.0/(kMinSmoothing+((1.0-pow(delta,kSmoothingScaleCurve))*(kMaxSmoothing-kMinSmoothing))); - // Update the smoothed alpha. - alpha[i]=(alpha_smoothing*new_alpha)+((1.0f-alpha_smoothing)*alpha[i]); - } - - // Use the same (largest) smoothed alpha for each channel - //NB: larger alpha = *less* lag (opposite to what you'd expect) - float largest_alpha=0.0f; - for (int i=0;i<6;i++) { - largest_alpha=std::max(largest_alpha, alpha[i]); - } - - // Calculate the new camera position. - for (int i=0;i<6;i++) { - new_camera_position[i]=(largest_alpha*target_camera_position[i])+((1.0f-largest_alpha)*current_camera_position[i]); - //new_camera_position[i]=(alpha[i]*target_camera_position[i])+((1.0f-alpha[i])*current_camera_position[i]); - } - -#ifdef LOG_OUTPUT - // Use this for some debug-output to file... - QFile data(QCoreApplication::applicationDirPath() + "\\EWMA_output.txt"); - if (data.open(QFile::WriteOnly | QFile::Append)) { - QTextStream out(&data); - out << "current:\t" << current_camera_position[0] - << "\t" << current_camera_position[1] - << "\t" << current_camera_position[2] - << "\t" << current_camera_position[3] - << "\t" << current_camera_position[4] - << "\t" << current_camera_position[5] << '\n'; - out << "target:\t" << target_camera_position[0] - << "\t" << target_camera_position[1] - << "\t" << target_camera_position[2] - << "\t" << target_camera_position[3] - << "\t" << target_camera_position[4] - << "\t" << target_camera_position[5] << '\n'; - out << "output:\t" << new_camera_position[0] - << "\t" << new_camera_position[1] - << "\t" << new_camera_position[2] - << "\t" << new_camera_position[3] - << "\t" << new_camera_position[4] - << "\t" << new_camera_position[5] << '\n'; - out << "largest_alpha:\t" << largest_alpha << '\n'; - } -#endif - - // Update the current camera position to the new position. - for (int i = 0; i < 6; i++) { - current_camera_position[i] = new_camera_position[i]; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter object. - -// Export both decorated and undecorated names. -// GetFilter - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetFilter@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetFilter=_GetFilter@0") - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Filter; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_filter_ewma2.h" +#include "math.h" +#include +#include +#include "facetracknoir/global-settings.h" +#include +#include +//#define LOG_OUTPUT + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +FTNoIR_Filter::FTNoIR_Filter() +{ + first_run = true; + alpha_smoothing = 0.02f; // this is a constant for now, might be a parameter later + loadSettings(); // Load the Settings +} + +FTNoIR_Filter::~FTNoIR_Filter() +{ +} + +void FTNoIR_Filter::receiveSettings(double smin, double smax, double sexpt) +{ + QMutexLocker foo(&mutex); + + kMinSmoothing = smin; + kMaxSmoothing = smax; + kSmoothingScaleCurve = sexpt; +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Filter::loadSettings() { + qDebug() << "FTNoIR_Filter::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) + + qDebug() << "FTNoIR_Filter::loadSettings says: iniFile = " << currentFile; + + // + // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR + // + iniFile.beginGroup ( "Tracking" ); + kMinSmoothing = iniFile.value ( "minSmooth", 15 ).toInt(); + kMaxSmoothing = iniFile.value ( "maxSmooth", 50 ).toInt(); + kSmoothingScaleCurve = iniFile.value ( "powCurve", 10 ).toInt(); + iniFile.endGroup (); +} + +void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, + double *target_camera_position, + double *new_camera_position, + double *last_post_filter) +{ + double delta; + double new_alpha; + double scale[]={0.025f,0.025f,0.025f,6.0f,6.0f,6.0f}; + + //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]; + alpha[i] = 0.0f; + } + first_run=false; + return; + } + + QMutexLocker foo(&mutex); + + for (int i=0;i<6;i++) { + // Calculate the delta. + delta=target_camera_position[i]-current_camera_position[i]; + // Normalise the delta. + delta=std::min(std::max(fabs(delta)/scale[i],0.0),1.0); + // Calculate the new alpha from the normalized delta. + new_alpha=1.0/(kMinSmoothing+((1.0-pow(delta,kSmoothingScaleCurve))*(kMaxSmoothing-kMinSmoothing))); + // Update the smoothed alpha. + alpha[i]=(alpha_smoothing*new_alpha)+((1.0f-alpha_smoothing)*alpha[i]); + } + + // Use the same (largest) smoothed alpha for each channel + //NB: larger alpha = *less* lag (opposite to what you'd expect) + float largest_alpha=0.0f; + for (int i=0;i<6;i++) { + largest_alpha=std::max(largest_alpha, alpha[i]); + } + + // Calculate the new camera position. + for (int i=0;i<6;i++) { + new_camera_position[i]=(largest_alpha*target_camera_position[i])+((1.0f-largest_alpha)*current_camera_position[i]); + //new_camera_position[i]=(alpha[i]*target_camera_position[i])+((1.0f-alpha[i])*current_camera_position[i]); + } + +#ifdef LOG_OUTPUT + // Use this for some debug-output to file... + QFile data(QCoreApplication::applicationDirPath() + "\\EWMA_output.txt"); + if (data.open(QFile::WriteOnly | QFile::Append)) { + QTextStream out(&data); + out << "current:\t" << current_camera_position[0] + << "\t" << current_camera_position[1] + << "\t" << current_camera_position[2] + << "\t" << current_camera_position[3] + << "\t" << current_camera_position[4] + << "\t" << current_camera_position[5] << '\n'; + out << "target:\t" << target_camera_position[0] + << "\t" << target_camera_position[1] + << "\t" << target_camera_position[2] + << "\t" << target_camera_position[3] + << "\t" << target_camera_position[4] + << "\t" << target_camera_position[5] << '\n'; + out << "output:\t" << new_camera_position[0] + << "\t" << new_camera_position[1] + << "\t" << new_camera_position[2] + << "\t" << new_camera_position[3] + << "\t" << new_camera_position[4] + << "\t" << new_camera_position[5] << '\n'; + out << "largest_alpha:\t" << largest_alpha << '\n'; + } +#endif + + // Update the current camera position to the new position. + for (int i = 0; i < 6; i++) { + current_camera_position[i] = new_camera_position[i]; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Filter object. + +// Export both decorated and undecorated names. +// GetFilter - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetFilter@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetFilter=_GetFilter@0") + +extern "C" FTNOIR_FILTER_BASE_EXPORT IFilter* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Filter; +} diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h index 18fec8d4..91f32816 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h @@ -1,116 +1,116 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#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 "ui_ftnoir_ewma_filtercontrols.h" -#include -#include - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class FTNoIR_Filter : public IFilter -{ -public: - FTNoIR_Filter(); - ~FTNoIR_Filter(); - void Initialize() {} - - void FilterHeadPoseData(double *current_camera_position, - double *target_camera_position, - double *new_camera_position, - double *last_post_filter); - void receiveSettings(double smin, double smax, double sexpt); - -private: - void loadSettings(); // Load the settings from the INI-file - double newHeadPose; // Structure with new headpose - - bool first_run; - double alpha_smoothing; - double alpha[6]; - - double kMinSmoothing; - double kMaxSmoothing; - double kSmoothingScaleCurve; - - QMutex mutex; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* - -// Widget that has controls for FTNoIR protocol filter-settings. -class FilterControls: public QWidget, public IFilterDialog -{ - Q_OBJECT -public: - explicit FilterControls(); - virtual ~FilterControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerFilter(IFilter* flt); - void unregisterFilter(); - -private: - Ui::UICFilterControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - - FTNoIR_Filter* pFilter; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; } - void settingChanged( int ) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter -//******************************************************************************************************* -class FTNoIR_FilterDll : public Metadata -{ -public: - FTNoIR_FilterDll(); - ~FTNoIR_FilterDll(); - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA Filter Mk2"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA"); } - 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 +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#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 "ui_ftnoir_ewma_filtercontrols.h" +#include +#include + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// EWMA Filter: Exponentially Weighted Moving Average filter with dynamic smoothing parameter +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class FTNoIR_Filter : public IFilter +{ +public: + FTNoIR_Filter(); + ~FTNoIR_Filter(); + void Initialize() {} + + void FilterHeadPoseData(double *current_camera_position, + double *target_camera_position, + double *new_camera_position, + double *last_post_filter); + void receiveSettings(double smin, double smax, double sexpt); + +private: + void loadSettings(); // Load the settings from the INI-file + double newHeadPose; // Structure with new headpose + + bool first_run; + double alpha_smoothing; + double alpha[6]; + + double kMinSmoothing; + double kMaxSmoothing; + double kSmoothingScaleCurve; + + QMutex mutex; +}; + +//******************************************************************************************************* +// FaceTrackNoIR Filter Settings-dialog. +//******************************************************************************************************* + +// Widget that has controls for FTNoIR protocol filter-settings. +class FilterControls: public QWidget, public IFilterDialog +{ + Q_OBJECT +public: + explicit FilterControls(); + virtual ~FilterControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerFilter(IFilter* flt); + void unregisterFilter(); + +private: + Ui::UICFilterControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + + FTNoIR_Filter* pFilter; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; } + void settingChanged( int ) { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Filter DLL. Functions used to get general info on the Filter +//******************************************************************************************************* +class FTNoIR_FilterDll : public Metadata +{ +public: + FTNoIR_FilterDll(); + ~FTNoIR_FilterDll(); + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA Filter Mk2"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("EWMA"); } + 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 ebcba5f1..91777213 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp @@ -1,198 +1,198 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_filter_ewma2.h" -#include "math.h" -#include -#include "facetracknoir/global-settings.h" -#include "ui_ftnoir_ewma_filtercontrols.h" - -//******************************************************************************************************* -// FaceTrackNoIR Filter Settings-dialog. -//******************************************************************************************************* -// -// Constructor for server-settings-dialog -// -FilterControls::FilterControls() : - QWidget(), pFilter(NULL) -{ - ui.setupUi( this ); - - QPoint offsetpos(100, 100); - //if (parent) { - // this->move(parent->pos() + offsetpos); - //} - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - - // Connect sliders for reduction factor - connect(ui.minSmooth, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.maxSmooth, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.powCurve, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); - - qDebug() << "FilterControls() says: started"; - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -FilterControls::~FilterControls() { - qDebug() << "~FilterControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FilterControls::Initialize(QWidget *parent) { - // - // - // - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -void FilterControls::registerFilter(IFilter* flt) -{ - pFilter = (FTNoIR_Filter*) flt; -} - -void FilterControls::unregisterFilter() -{ - pFilter = NULL; -} - -// -// OK clicked on server-dialog -// -void FilterControls::doOK() { - save(); - this->close(); -} - -// override show event -void FilterControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void FilterControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FilterControls::loadSettings() { - qDebug() << "FilterControls::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) - - qDebug() << "FilterControls::loadSettings says: iniFile = " << currentFile; - - // - // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR - // - iniFile.beginGroup ( "Tracking" ); - ui.minSmooth->setValue (iniFile.value ( "minSmooth", 15 ).toInt()); - ui.maxSmooth->setValue (iniFile.value ( "maxSmooth", 50 ).toInt()); - ui.powCurve->setValue (iniFile.value ( "powCurve", 10 ).toInt()); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FilterControls::save() { - 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) - - double smooth_min, smooth_max, smooth_expt; - - iniFile.beginGroup ( "Tracking" ); - iniFile.setValue ( "minSmooth", smooth_min = ui.minSmooth->value() ); - iniFile.setValue ( "powCurve", smooth_expt = ui.powCurve->value() ); - iniFile.setValue ( "maxSmooth", smooth_max = ui.maxSmooth->value() ); - iniFile.endGroup (); - - settingsDirty = false; - - if (pFilter) - pFilter->receiveSettings(smooth_min, smooth_max, smooth_expt); -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter-settings dialog object. - -// Export both decorated and undecorated names. -// GetFilterDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetFilterDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0") - -extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION GetDialog( ) -{ - return new FilterControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_filter_ewma2.h" +#include "math.h" +#include +#include "facetracknoir/global-settings.h" +#include "ui_ftnoir_ewma_filtercontrols.h" + +//******************************************************************************************************* +// FaceTrackNoIR Filter Settings-dialog. +//******************************************************************************************************* +// +// Constructor for server-settings-dialog +// +FilterControls::FilterControls() : + QWidget(), pFilter(NULL) +{ + ui.setupUi( this ); + + QPoint offsetpos(100, 100); + //if (parent) { + // this->move(parent->pos() + offsetpos); + //} + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + + // Connect sliders for reduction factor + connect(ui.minSmooth, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.maxSmooth, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.powCurve, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int))); + + qDebug() << "FilterControls() says: started"; + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +FilterControls::~FilterControls() { + qDebug() << "~FilterControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FilterControls::Initialize(QWidget *parent) { + // + // + // + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +void FilterControls::registerFilter(IFilter* flt) +{ + pFilter = (FTNoIR_Filter*) flt; +} + +void FilterControls::unregisterFilter() +{ + pFilter = NULL; +} + +// +// OK clicked on server-dialog +// +void FilterControls::doOK() { + save(); + this->close(); +} + +// override show event +void FilterControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FilterControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FilterControls::loadSettings() { + qDebug() << "FilterControls::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) + + qDebug() << "FilterControls::loadSettings says: iniFile = " << currentFile; + + // + // The EWMA2-filter-settings are in the Tracking group: this is because they used to be on the Main Form of FaceTrackNoIR + // + iniFile.beginGroup ( "Tracking" ); + ui.minSmooth->setValue (iniFile.value ( "minSmooth", 15 ).toInt()); + ui.maxSmooth->setValue (iniFile.value ( "maxSmooth", 50 ).toInt()); + ui.powCurve->setValue (iniFile.value ( "powCurve", 10 ).toInt()); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FilterControls::save() { + 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) + + double smooth_min, smooth_max, smooth_expt; + + iniFile.beginGroup ( "Tracking" ); + iniFile.setValue ( "minSmooth", smooth_min = ui.minSmooth->value() ); + iniFile.setValue ( "powCurve", smooth_expt = ui.powCurve->value() ); + iniFile.setValue ( "maxSmooth", smooth_max = ui.maxSmooth->value() ); + iniFile.endGroup (); + + settingsDirty = false; + + if (pFilter) + pFilter->receiveSettings(smooth_min, smooth_max, smooth_expt); +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Filter-settings dialog object. + +// Export both decorated and undecorated names. +// GetFilterDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetFilterDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetFilterDialog=_GetFilterDialog@0") + +extern "C" FTNOIR_FILTER_BASE_EXPORT IFilterDialog* CALLING_CONVENTION 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 48c9d3be..087ede1b 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_filter_ewma2.h" -#include -#include "facetracknoir/global-settings.h" - -FTNoIR_FilterDll::FTNoIR_FilterDll() { -} - -FTNoIR_FilterDll::~FTNoIR_FilterDll() -{ - -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Filter object. - -// Export both decorated and undecorated names. -// GetFilterDll - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetFilterDll@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0") - -extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() -{ - return new FTNoIR_FilterDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_filter_ewma2.h" +#include +#include "facetracknoir/global-settings.h" + +FTNoIR_FilterDll::FTNoIR_FilterDll() { +} + +FTNoIR_FilterDll::~FTNoIR_FilterDll() +{ + +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Filter object. + +// Export both decorated and undecorated names. +// GetFilterDll - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetFilterDll@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetFilterDll=_GetFilterDll@0") + +extern "C" FTNOIR_FILTER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +{ + return new FTNoIR_FilterDll; +} diff --git a/ftnoir_posewidget/glwidget.cpp b/ftnoir_posewidget/glwidget.cpp index 671dd35d..9f495e0b 100644 --- a/ftnoir_posewidget/glwidget.cpp +++ b/ftnoir_posewidget/glwidget.cpp @@ -1,230 +1,230 @@ -/* Copyright (c) 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 -#include "glwidget.h" -#include -#include -#include - -GLWidget::GLWidget(QWidget *parent) : QWidget(parent) -{ - front = QImage(QString(":/images/side1.png")); - back = QImage(QString(":/images/side6.png")); - rotateBy(0, 0, 0); -} - -GLWidget::~GLWidget() -{ -} - -void GLWidget::paintEvent ( QPaintEvent * event ) { - QWidget::paintEvent(event); - QPainter p(this); - project_quad_texture(); - p.drawPixmap(event->rect(), pixmap, event->rect()); -} - -void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle) -{ - - double ch = cos(xAngle / 57.295781); - double sh = sin(xAngle / 57.295781); - double ca = cos(yAngle / 57.295781); - double sa = sin(yAngle / 57.295781); - double cb = cos(zAngle / 57.295781); - double sb = sin(zAngle / 57.295781); - - matrix[0 * 3 + 0] = ch * ca; - matrix[0 * 3 + 1]= sh*sb - ch*sa*cb; - matrix[0 * 3 + 2]= ch*sa*sb + sh*cb; - matrix[1 * 3 + 0]= sa; - matrix[1 * 3 + 1]= ca*cb; - matrix[1 * 3 + 2]= -ca*sb; - matrix[2 * 3 + 0]= -sh*ca; - matrix[2 * 3 + 1]= sh*sa*cb + ch*sb; - matrix[2 * 3 + 2]= -sh*sa*sb + ch*cb; - update(); -} - -class Triangle { -public: - Triangle(const Vec2f& p1, - const Vec2f& p2, - const Vec2f& p3) - { - origin = p1; - v0 = Vec2f(p3.x - p1.x, p3.y - p1.y); - v1 = Vec2f(p2.x - p1.x, p2.y - p1.y); - dot00 = dot(v0, v0); - dot01 = dot(v0, v1); - dot11 = dot(v1, v1); - invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - } - bool barycentric_coords(const Vec2f& px, Vec2f& uv) const - { - Vec2f v2(px.x - origin.x, px.y - origin.y); - double dot12 = dot(v1, v2); - double dot02 = dot(v0, v2); - double u = (dot11 * dot02 - dot01 * dot12) * invDenom; - double v = (dot00 * dot12 - dot01 * dot02) * invDenom; - uv.x = u; - uv.y = v; - return (u >= 0) && (v >= 0) && (u + v <= 1); - } - -private: - double dot00, dot01, dot11, invDenom; - Vec2f v0, v1, origin; - double dot(const Vec2f& p1, const Vec2f& p2) const { - return p1.x * p2.x + p1.y * p2.y; - } -}; - -static __inline Vec3f cross(const Vec3f& p1, const Vec3f& p2) -{ - return Vec3f(p1.y * p2.z - p2.y * p1.z, - p2.x * p1.z - p1.x * p2.z, - p1.x * p2.y - p1.y * p2.x); -} - -static __inline Vec3f normal(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3) -{ - Vec3f u(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); - Vec3f v(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z); - - Vec3f tmp = cross(u, v); - - double i = 1./sqrt(tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z); - - return Vec3f(i * tmp.x, i * tmp.y, i * tmp.z); -} - -void GLWidget::project_quad_texture() { - const int sx = width(), sy = height(); - Point pt[4]; - static Vec3f corners[] = { - Vec3f(0, 0, 0), - Vec3f(sx-1, 0, 0), - Vec3f(0, sy-1, 0), - Vec3f(sx-1, sy-1, 0) - }; - - for (int i = 0; i < 4; i++) { - pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0)); - pt[i].x += sx/2; - pt[i].y += sy/2; - } - - Vec3f normal1(0, 0, 1); - Vec3f normal2; - { - Vec3f foo[3]; - for (int i = 0; i < 3; i++) - foo[i] = project2(corners[i]); - normal2 = normal(foo[0], foo[1], foo[2]); - } - - double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z; - - QImage& tex = dir < 0 ? back : front; - - int ow = tex.width(), oh = tex.height(); - - Vec2f p2[4]; - - for (int i = 0; i < 4; i++) - p2[i] = Vec2f(pt[i].x, pt[i].y); - - QImage texture(QSize(sx, sy), QImage::Format_RGB888); - texture.fill(Qt::black); - - const Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } }; - const Vec2f origs[2][3] = { - { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) }, - { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) } - }; - const Triangle triangles[2] = { - Triangle(projected[0][0], projected[0][1], projected[0][2]), - Triangle(projected[1][0], projected[1][1], projected[1][2]) - }; - - int orig_pitch = tex.bytesPerLine(); - int dest_pitch = texture.bytesPerLine(); - - const unsigned char* orig = tex.bits(); - unsigned char* dest = texture.bits(); - - int orig_depth = tex.depth() / 8; - int dest_depth = texture.depth() / 8; - - /* image breakage? */ - if (orig_depth < 3) - return; - - for (int y = 0; y < sy; y++) - for (int x = 0; x < sx; x++) { - Vec2f pos; - pos.x = x; - pos.y = y; - for (int i = 0; i < 2; i++) { - Vec2f coords; - if (triangles[i].barycentric_coords(pos, coords)) - { - double qx = origs[i][0].x - + coords.x * (origs[i][2].x - origs[i][0].x) - + coords.y * (origs[i][1].x - origs[i][0].x); - double qy = origs[i][0].y - + coords.x * (origs[i][2].y - origs[i][0].y) - + coords.y * (origs[i][1].y - origs[i][0].y); - int qx1 = std::min(ow - 1, std::max(0, qx - 0.5)); - int qy1 = std::min(oh - 1, std::max(0, qy - 0.5)); - int qx2 = std::min(ow - 1, std::max(0, qx + 0.5)); - int qy2 = std::min(oh - 1, std::max(0, qy + 0.5)); - - double dx1 = qx1 - qx; - double dy1 = qy1 - qy; - double dx2 = qx2 - qx; - double dy2 = qy2 - qy; - - double d1 = 2 - (dx1 * dx1 + dy1 * dy1); - double d2 = 2 - (dx2 * dx2 + dy2 * dy2); - double d3 = 2 - (dx2 * dx2 + dy1 * dy1); - double d4 = 2 - (dx1 * dx1 + dy2 * dy2); - - double inv_norm = 1. / (d1 + d2 + d3 + d4); - - d1 *= inv_norm; - d2 *= inv_norm; - d3 *= inv_norm; - d4 *= inv_norm; - - double r = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 2] - + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 2] - + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 2] - + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 2]; - - double g = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 1] - + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 1] - + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 1] - + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 1]; - - double b = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 0] - + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 0] - + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 0] - + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 0]; - - dest[y * dest_pitch + x * dest_depth + 0] = std::max(0, std::min(255, r)); - dest[y * dest_pitch + x * dest_depth + 1] = std::max(0, std::min(255, g)); - dest[y * dest_pitch + x * dest_depth + 2] = std::max(0, std::min(255, b)); - - break; - } - } - } - pixmap = QPixmap::fromImage(texture); +/* Copyright (c) 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 +#include "glwidget.h" +#include +#include +#include + +GLWidget::GLWidget(QWidget *parent) : QWidget(parent) +{ + front = QImage(QString(":/images/side1.png")); + back = QImage(QString(":/images/side6.png")); + rotateBy(0, 0, 0); +} + +GLWidget::~GLWidget() +{ +} + +void GLWidget::paintEvent ( QPaintEvent * event ) { + QWidget::paintEvent(event); + QPainter p(this); + project_quad_texture(); + p.drawPixmap(event->rect(), pixmap, event->rect()); +} + +void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle) +{ + + double ch = cos(xAngle / 57.295781); + double sh = sin(xAngle / 57.295781); + double ca = cos(yAngle / 57.295781); + double sa = sin(yAngle / 57.295781); + double cb = cos(zAngle / 57.295781); + double sb = sin(zAngle / 57.295781); + + matrix[0 * 3 + 0] = ch * ca; + matrix[0 * 3 + 1]= sh*sb - ch*sa*cb; + matrix[0 * 3 + 2]= ch*sa*sb + sh*cb; + matrix[1 * 3 + 0]= sa; + matrix[1 * 3 + 1]= ca*cb; + matrix[1 * 3 + 2]= -ca*sb; + matrix[2 * 3 + 0]= -sh*ca; + matrix[2 * 3 + 1]= sh*sa*cb + ch*sb; + matrix[2 * 3 + 2]= -sh*sa*sb + ch*cb; + update(); +} + +class Triangle { +public: + Triangle(const Vec2f& p1, + const Vec2f& p2, + const Vec2f& p3) + { + origin = p1; + v0 = Vec2f(p3.x - p1.x, p3.y - p1.y); + v1 = Vec2f(p2.x - p1.x, p2.y - p1.y); + dot00 = dot(v0, v0); + dot01 = dot(v0, v1); + dot11 = dot(v1, v1); + invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + } + bool barycentric_coords(const Vec2f& px, Vec2f& uv) const + { + Vec2f v2(px.x - origin.x, px.y - origin.y); + double dot12 = dot(v1, v2); + double dot02 = dot(v0, v2); + double u = (dot11 * dot02 - dot01 * dot12) * invDenom; + double v = (dot00 * dot12 - dot01 * dot02) * invDenom; + uv.x = u; + uv.y = v; + return (u >= 0) && (v >= 0) && (u + v <= 1); + } + +private: + double dot00, dot01, dot11, invDenom; + Vec2f v0, v1, origin; + double dot(const Vec2f& p1, const Vec2f& p2) const { + return p1.x * p2.x + p1.y * p2.y; + } +}; + +static __inline Vec3f cross(const Vec3f& p1, const Vec3f& p2) +{ + return Vec3f(p1.y * p2.z - p2.y * p1.z, + p2.x * p1.z - p1.x * p2.z, + p1.x * p2.y - p1.y * p2.x); +} + +static __inline Vec3f normal(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3) +{ + Vec3f u(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); + Vec3f v(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z); + + Vec3f tmp = cross(u, v); + + double i = 1./sqrt(tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z); + + return Vec3f(i * tmp.x, i * tmp.y, i * tmp.z); +} + +void GLWidget::project_quad_texture() { + const int sx = width(), sy = height(); + Point pt[4]; + static Vec3f corners[] = { + Vec3f(0, 0, 0), + Vec3f(sx-1, 0, 0), + Vec3f(0, sy-1, 0), + Vec3f(sx-1, sy-1, 0) + }; + + for (int i = 0; i < 4; i++) { + pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0)); + pt[i].x += sx/2; + pt[i].y += sy/2; + } + + Vec3f normal1(0, 0, 1); + Vec3f normal2; + { + Vec3f foo[3]; + for (int i = 0; i < 3; i++) + foo[i] = project2(corners[i]); + normal2 = normal(foo[0], foo[1], foo[2]); + } + + double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z; + + QImage& tex = dir < 0 ? back : front; + + int ow = tex.width(), oh = tex.height(); + + Vec2f p2[4]; + + for (int i = 0; i < 4; i++) + p2[i] = Vec2f(pt[i].x, pt[i].y); + + QImage texture(QSize(sx, sy), QImage::Format_RGB888); + texture.fill(Qt::black); + + const Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } }; + const Vec2f origs[2][3] = { + { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) }, + { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) } + }; + const Triangle triangles[2] = { + Triangle(projected[0][0], projected[0][1], projected[0][2]), + Triangle(projected[1][0], projected[1][1], projected[1][2]) + }; + + int orig_pitch = tex.bytesPerLine(); + int dest_pitch = texture.bytesPerLine(); + + const unsigned char* orig = tex.bits(); + unsigned char* dest = texture.bits(); + + int orig_depth = tex.depth() / 8; + int dest_depth = texture.depth() / 8; + + /* image breakage? */ + if (orig_depth < 3) + return; + + for (int y = 0; y < sy; y++) + for (int x = 0; x < sx; x++) { + Vec2f pos; + pos.x = x; + pos.y = y; + for (int i = 0; i < 2; i++) { + Vec2f coords; + if (triangles[i].barycentric_coords(pos, coords)) + { + double qx = origs[i][0].x + + coords.x * (origs[i][2].x - origs[i][0].x) + + coords.y * (origs[i][1].x - origs[i][0].x); + double qy = origs[i][0].y + + coords.x * (origs[i][2].y - origs[i][0].y) + + coords.y * (origs[i][1].y - origs[i][0].y); + int qx1 = std::min(ow - 1, std::max(0, qx - 0.5)); + int qy1 = std::min(oh - 1, std::max(0, qy - 0.5)); + int qx2 = std::min(ow - 1, std::max(0, qx + 0.5)); + int qy2 = std::min(oh - 1, std::max(0, qy + 0.5)); + + double dx1 = qx1 - qx; + double dy1 = qy1 - qy; + double dx2 = qx2 - qx; + double dy2 = qy2 - qy; + + double d1 = 2 - (dx1 * dx1 + dy1 * dy1); + double d2 = 2 - (dx2 * dx2 + dy2 * dy2); + double d3 = 2 - (dx2 * dx2 + dy1 * dy1); + double d4 = 2 - (dx1 * dx1 + dy2 * dy2); + + double inv_norm = 1. / (d1 + d2 + d3 + d4); + + d1 *= inv_norm; + d2 *= inv_norm; + d3 *= inv_norm; + d4 *= inv_norm; + + double r = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 2] + + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 2] + + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 2] + + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 2]; + + double g = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 1] + + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 1] + + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 1] + + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 1]; + + double b = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 0] + + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 0] + + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 0] + + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 0]; + + dest[y * dest_pitch + x * dest_depth + 0] = std::max(0, std::min(255, r)); + dest[y * dest_pitch + x * dest_depth + 1] = std::max(0, std::min(255, g)); + dest[y * dest_pitch + x * dest_depth + 2] = std::max(0, std::min(255, b)); + + break; + } + } + } + pixmap = QPixmap::fromImage(texture); } \ No newline at end of file diff --git a/ftnoir_posewidget/glwidget.h b/ftnoir_posewidget/glwidget.h index 9525f7d4..f46f3c9e 100644 --- a/ftnoir_posewidget/glwidget.h +++ b/ftnoir_posewidget/glwidget.h @@ -1,116 +1,116 @@ -/******************************************************************************** -* 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. * -* * -* Adopted this widget from the 'textures' sample of the Nokia Qt toolkit. * -* * -* You should have received a copy of the GNU General Public License along * -* with this program; if not, see . * -*********************************************************************************/ - -#ifndef GLWIDGET_H -#define GLWIDGET_H - -#include -#include -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" - -struct Point { - Point(int x, int y) : - x(x), y(y) - { - } - Point() : - x(0), y(0) - { - } - int x, y; -}; - -struct Vec3f { - double x, y, z; - Vec3f(double x, double y, double z) : - x(x), y(y), z(z) - { - } - Vec3f() : - x(0), y(0), z(0) - { - } -}; - -struct Vec2f { - double x, y; - Vec2f(double x, double y) : - x(x), y(y) - { - } - Vec2f() : - x(0), y(0) - { - } -}; - -class FTNOIR_TRACKER_BASE_EXPORT GLWidget : public QWidget -{ - Q_OBJECT - -public: - GLWidget(QWidget *parent); - ~GLWidget(); - void rotateBy(double xAngle, double yAngle, double zAngle); - -protected: - void paintEvent ( QPaintEvent * event ); - -private: - Point project(const Vec3f& point) { - Point rect; - - rect.x = point.x * matrix[0] - + point.y * matrix[1] - + point.z * matrix[2]; - rect.y = point.x * matrix[3] - + point.y * matrix[4] - + point.z * matrix[5]; - - return rect; - } - Vec3f project2(const Vec3f& point) { - Vec3f rect; - - rect.x = point.x * matrix[0] - + point.y * matrix[1] - + point.z * matrix[2]; - rect.y = point.x * matrix[3] - + point.y * matrix[4] - + point.z * matrix[5]; - rect.z = point.x * matrix[6] - + point.y * matrix[7] - + point.z * matrix[8]; - return rect; - } - void project_quad_texture(); - double matrix[9]; - QImage front; - QImage back; - QPixmap pixmap; -}; - -#endif +/******************************************************************************** +* 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. * +* * +* Adopted this widget from the 'textures' sample of the Nokia Qt toolkit. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +*********************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include +#include +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" + +struct Point { + Point(int x, int y) : + x(x), y(y) + { + } + Point() : + x(0), y(0) + { + } + int x, y; +}; + +struct Vec3f { + double x, y, z; + Vec3f(double x, double y, double z) : + x(x), y(y), z(z) + { + } + Vec3f() : + x(0), y(0), z(0) + { + } +}; + +struct Vec2f { + double x, y; + Vec2f(double x, double y) : + x(x), y(y) + { + } + Vec2f() : + x(0), y(0) + { + } +}; + +class FTNOIR_TRACKER_BASE_EXPORT GLWidget : public QWidget +{ + Q_OBJECT + +public: + GLWidget(QWidget *parent); + ~GLWidget(); + void rotateBy(double xAngle, double yAngle, double zAngle); + +protected: + void paintEvent ( QPaintEvent * event ); + +private: + Point project(const Vec3f& point) { + Point rect; + + rect.x = point.x * matrix[0] + + point.y * matrix[1] + + point.z * matrix[2]; + rect.y = point.x * matrix[3] + + point.y * matrix[4] + + point.z * matrix[5]; + + return rect; + } + Vec3f project2(const Vec3f& point) { + Vec3f rect; + + rect.x = point.x * matrix[0] + + point.y * matrix[1] + + point.z * matrix[2]; + rect.y = point.x * matrix[3] + + point.y * matrix[4] + + point.z * matrix[5]; + rect.z = point.x * matrix[6] + + point.y * matrix[7] + + point.z * matrix[8]; + return rect; + } + void project_quad_texture(); + double matrix[9]; + QImage front; + QImage back; + QPixmap pixmap; +}; + +#endif diff --git a/ftnoir_protocol_base/ftnoir_protocol_base.h b/ftnoir_protocol_base/ftnoir_protocol_base.h index 8533363d..1ebafdd5 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base.h @@ -1,75 +1,75 @@ -/******************************************************************************** -* 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 . * -* 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 -#include -//#include "winbase.h" - -//#include "windows.h" -//#include "winable.h" - -//////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -# define EXTERN_C extern "C" -#else -# define EXTERN_C -#endif // __cplusplus - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol -{ - virtual ~IProtocol() {} - virtual bool checkServerInstallationOK() = 0; - virtual void sendHeadposeToGame( double *headpose, double *rawheadpose ) = 0; - virtual QString getGameName() = 0; -}; - -struct IProtocolDialog -{ - virtual ~IProtocolDialog() {} - virtual void Initialize(QWidget *parent) = 0; - virtual void showEvent ( QShowEvent * event ) = 0; - - virtual void registerProtocol(IProtocol *protocol) = 0; - virtual void unRegisterProtocol() = 0; -}; - -#endif // FTNOIR_PROTOCOL_BASE_H +/******************************************************************************** +* 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 . * +* 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 +#include +//#include "winbase.h" + +//#include "windows.h" +//#include "winable.h" + +//////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif // __cplusplus + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol +{ + virtual ~IProtocol() {} + virtual bool checkServerInstallationOK() = 0; + virtual void sendHeadposeToGame( double *headpose, double *rawheadpose ) = 0; + virtual QString getGameName() = 0; +}; + +struct IProtocolDialog +{ + virtual ~IProtocolDialog() {} + virtual void Initialize(QWidget *parent) = 0; + virtual void showEvent ( QShowEvent * event ) = 0; + + 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 index ca51e26d..9f66d67a 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base_global.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base_global.h @@ -1,12 +1,12 @@ -#ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H -#define FTNOIR_PROTOCOL_BASE_GLOBAL_H - -#include - -#ifdef FTNOIR_PROTOCOL_BASE_LIB -# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT -#else -# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#endif - -#endif // FTNOIR_PROTOCOL_BASE_GLOBAL_H +#ifndef FTNOIR_PROTOCOL_BASE_GLOBAL_H +#define FTNOIR_PROTOCOL_BASE_GLOBAL_H + +#include + +#ifdef FTNOIR_PROTOCOL_BASE_LIB +# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT +#else +# define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT +#endif + +#endif // FTNOIR_PROTOCOL_BASE_GLOBAL_H diff --git a/ftnoir_protocol_fg/fgtypes.h b/ftnoir_protocol_fg/fgtypes.h index 68f85877..0f29be3d 100644 --- a/ftnoir_protocol_fg/fgtypes.h +++ b/ftnoir_protocol_fg/fgtypes.h @@ -1,27 +1,27 @@ -/******************************************************************************** -* 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 * -* * -* Type definitions for the FlightGear server. * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FGTYPES_H -#define INCLUDED_FGTYPES_H - -// -// x,y,z position in metres, heading, pitch and roll in degrees... -// -#pragma pack(push, 2) -struct TFlightGearData { - double x, y, z, h, p, r; - int status; -}; -#pragma pack(pop) - -#endif//INCLUDED_FGTYPES_H +/******************************************************************************** +* 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 * +* * +* Type definitions for the FlightGear server. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FGTYPES_H +#define INCLUDED_FGTYPES_H + +// +// x,y,z position in metres, heading, pitch and roll in degrees... +// +#pragma pack(push, 2) +struct TFlightGearData { + double x, y, z, h, p, r; + int status; +}; +#pragma pack(pop) + +#endif//INCLUDED_FGTYPES_H diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp index abc401fa..d80791ce 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp @@ -1,222 +1,222 @@ -/******************************************************************************** -* 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 . * -* * -* FGServer FGServer is the Class, that communicates headpose-data * -* to FlightGear, using UDP. * -* It is based on the (Linux) example made by Melchior FRANZ. * -********************************************************************************/ -#include "ftnoir_protocol_fg.h" -#include -#include "facetracknoir/global-settings.h" -#include - -// For Todd and Arda Kutlu -//#define SEND_ASCII_DATA -//#define LOG_OUTPUT - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() -{ - blnConnectionActive = false; - loadSettings(); -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ - if (inSocket != 0) { - inSocket->close(); - delete inSocket; - } - - if (outSocket != 0) { - outSocket->close(); - delete outSocket; - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { - 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 ( "FG" ); - - bool blnLocalPC = iniFile.value ( "LocalPCOnly", 1 ).toBool(); - if (blnLocalPC) { - destIP = QHostAddress::LocalHost; - } - else { - QString destAddr = iniFile.value ( "IP-1", 192 ).toString() + "." + iniFile.value ( "IP-2", 168 ).toString() + "." + iniFile.value ( "IP-3", 2 ).toString() + "." + iniFile.value ( "IP-4", 1 ).toString(); - destIP = QHostAddress( destAddr ); - } - destPort = iniFile.value ( "PortNumber", 5550 ).toInt(); - - iniFile.endGroup (); - -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame( double *headpose, double *rawheadpose ) { -int no_bytes; -QHostAddress sender; -quint16 senderPort; - - // - // Copy the Raw measurements directly to the client. - // - FlightData.x = headpose[TX]; - FlightData.y = headpose[Pitch]; - FlightData.z = headpose[TZ]; - FlightData.p = headpose[TY]; - FlightData.h = headpose[Yaw]; - FlightData.r = headpose[Roll]; - FlightData.status = fg_cmd; - - // - // Try to send an UDP-message to the FlightGear - // - -#ifdef SEND_ASCII_DATA - sprintf_s(data, "%.2f %.2f %.2f %.2f %.2f %.2f\n\0", FlightData.x, FlightData.y, FlightData.z, FlightData.p, FlightData.h, FlightData.r); - - if (outSocket != 0) { - no_bytes = outSocket->writeDatagram((const char *) &data, strlen( data ), destIP, destPort); - if ( no_bytes > 0) { - qDebug() << "FGServer::writePendingDatagrams says: bytes send =" << data; - } - else { - qDebug() << "FGServer::writePendingDatagrams says: nothing sent!"; - } - } - -#endif - - #ifdef LOG_OUTPUT - // Use this for some debug-output to file... - QFile datafile(QCoreApplication::applicationDirPath() + "\\FG_output.txt"); - if (datafile.open(QFile::WriteOnly | QFile::Append)) { - QTextStream out(&datafile); - out << "output:\t" << FlightData.x << "\t" << FlightData.y << "\t" << FlightData.z << "\t" << FlightData.p << "\t" << FlightData.h << "\t" << FlightData.r << '\n'; - } - #endif - - #ifndef SEND_ASCII_DATA - //! [1] -// no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), QHostAddress::LocalHost, 5550); - if (outSocket != 0) { - no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), destIP, destPort); - if ( no_bytes > 0) { - // qDebug() << "FGServer::writePendingDatagrams says: bytes send =" << no_bytes << sizeof( double ); - } - else { - qDebug() << "FGServer::writePendingDatagrams says: nothing sent!"; - } - } - #endif - - // - // FlightGear keeps sending data, so we must read that here. - // - if (inSocket != 0) { - while (inSocket->hasPendingDatagrams()) { - - QByteArray datagram; - datagram.resize(inSocket->pendingDatagramSize()); - - inSocket->readDatagram( (char * ) &cmd, sizeof(cmd), &sender, &senderPort); - - fg_cmd = cmd; // Let's just accept that command for now... - if ( cmd > 0 ) { - qDebug() << "FGServer::sendHeadposeToGame hasPendingDatagrams, cmd = " << cmd; -// headTracker->handleGameCommand ( cmd ); // Send it upstream, for the Tracker to handle - } - - if (!blnConnectionActive) { - blnConnectionActive = true; - } - } - } -} - -// -// Check if the Client DLL exists and load it (to test it), if so. -// Returns 'true' if all seems OK. -// -bool FTNoIR_Protocol::checkServerInstallationOK() -{ - // Init. the data - FlightData.x = 0.0f; - FlightData.y = 0.0f; - FlightData.z = 0.0f; - FlightData.h = 0.0f; - FlightData.p = 0.0f; - FlightData.r = 0.0f; - FlightData.status = 0; - fg_cmd = 1; - - inSocket = 0; - outSocket = 0; - - // - // Create UDP-sockets. - // - if (inSocket == 0) { - qDebug() << "FGServer::sendHeadposeToGame creating insocket"; - inSocket = new QUdpSocket(); - - // Connect the inSocket to the port, to receive messages - if (!inSocket->bind(QHostAddress::Any, destPort+1)) { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton); - delete inSocket; - inSocket = 0; - return false; - } - } - - if (outSocket == 0) { - outSocket = new QUdpSocket(); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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 . * +* * +* FGServer FGServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#include "ftnoir_protocol_fg.h" +#include +#include "facetracknoir/global-settings.h" +#include + +// For Todd and Arda Kutlu +//#define SEND_ASCII_DATA +//#define LOG_OUTPUT + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() +{ + blnConnectionActive = false; + loadSettings(); +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ + if (inSocket != 0) { + inSocket->close(); + delete inSocket; + } + + if (outSocket != 0) { + outSocket->close(); + delete outSocket; + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { + 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 ( "FG" ); + + bool blnLocalPC = iniFile.value ( "LocalPCOnly", 1 ).toBool(); + if (blnLocalPC) { + destIP = QHostAddress::LocalHost; + } + else { + QString destAddr = iniFile.value ( "IP-1", 192 ).toString() + "." + iniFile.value ( "IP-2", 168 ).toString() + "." + iniFile.value ( "IP-3", 2 ).toString() + "." + iniFile.value ( "IP-4", 1 ).toString(); + destIP = QHostAddress( destAddr ); + } + destPort = iniFile.value ( "PortNumber", 5550 ).toInt(); + + iniFile.endGroup (); + +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame( double *headpose, double *rawheadpose ) { +int no_bytes; +QHostAddress sender; +quint16 senderPort; + + // + // Copy the Raw measurements directly to the client. + // + FlightData.x = headpose[TX]; + FlightData.y = headpose[Pitch]; + FlightData.z = headpose[TZ]; + FlightData.p = headpose[TY]; + FlightData.h = headpose[Yaw]; + FlightData.r = headpose[Roll]; + FlightData.status = fg_cmd; + + // + // Try to send an UDP-message to the FlightGear + // + +#ifdef SEND_ASCII_DATA + sprintf_s(data, "%.2f %.2f %.2f %.2f %.2f %.2f\n\0", FlightData.x, FlightData.y, FlightData.z, FlightData.p, FlightData.h, FlightData.r); + + if (outSocket != 0) { + no_bytes = outSocket->writeDatagram((const char *) &data, strlen( data ), destIP, destPort); + if ( no_bytes > 0) { + qDebug() << "FGServer::writePendingDatagrams says: bytes send =" << data; + } + else { + qDebug() << "FGServer::writePendingDatagrams says: nothing sent!"; + } + } + +#endif + + #ifdef LOG_OUTPUT + // Use this for some debug-output to file... + QFile datafile(QCoreApplication::applicationDirPath() + "\\FG_output.txt"); + if (datafile.open(QFile::WriteOnly | QFile::Append)) { + QTextStream out(&datafile); + out << "output:\t" << FlightData.x << "\t" << FlightData.y << "\t" << FlightData.z << "\t" << FlightData.p << "\t" << FlightData.h << "\t" << FlightData.r << '\n'; + } + #endif + + #ifndef SEND_ASCII_DATA + //! [1] +// no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), QHostAddress::LocalHost, 5550); + if (outSocket != 0) { + no_bytes = outSocket->writeDatagram((const char *) &FlightData, sizeof( FlightData ), destIP, destPort); + if ( no_bytes > 0) { + // qDebug() << "FGServer::writePendingDatagrams says: bytes send =" << no_bytes << sizeof( double ); + } + else { + qDebug() << "FGServer::writePendingDatagrams says: nothing sent!"; + } + } + #endif + + // + // FlightGear keeps sending data, so we must read that here. + // + if (inSocket != 0) { + while (inSocket->hasPendingDatagrams()) { + + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + + inSocket->readDatagram( (char * ) &cmd, sizeof(cmd), &sender, &senderPort); + + fg_cmd = cmd; // Let's just accept that command for now... + if ( cmd > 0 ) { + qDebug() << "FGServer::sendHeadposeToGame hasPendingDatagrams, cmd = " << cmd; +// headTracker->handleGameCommand ( cmd ); // Send it upstream, for the Tracker to handle + } + + if (!blnConnectionActive) { + blnConnectionActive = true; + } + } + } +} + +// +// Check if the Client DLL exists and load it (to test it), if so. +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol::checkServerInstallationOK() +{ + // Init. the data + FlightData.x = 0.0f; + FlightData.y = 0.0f; + FlightData.z = 0.0f; + FlightData.h = 0.0f; + FlightData.p = 0.0f; + FlightData.r = 0.0f; + FlightData.status = 0; + fg_cmd = 1; + + inSocket = 0; + outSocket = 0; + + // + // Create UDP-sockets. + // + if (inSocket == 0) { + qDebug() << "FGServer::sendHeadposeToGame creating insocket"; + inSocket = new QUdpSocket(); + + // Connect the inSocket to the port, to receive messages + if (!inSocket->bind(QHostAddress::Any, destPort+1)) { + QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton); + delete inSocket; + inSocket = 0; + return false; + } + } + + if (outSocket == 0) { + outSocket = new QUdpSocket(); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Protocol; +} diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.h b/ftnoir_protocol_fg/ftnoir_protocol_fg.h index 1c4484b8..5c2531be 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.h +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.h @@ -1,121 +1,121 @@ -/******************************************************************************** -* 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) 2013 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 . * -* * -* FGServer FGServer is the Class, that communicates headpose-data * -* to FlightGear, using UDP. * -* It is based on the (Linux) example made by Melchior FRANZ. * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FGSERVER_H -#define INCLUDED_FGSERVER_H - -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ui_ftnoir_fgcontrols.h" -#include "fgtypes.h" -#include -#include -#include -#include -#include -#include "facetracknoir/global-settings.h" - -#define FT_PROGRAMID "FT_ProgramID" - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK(); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); -private: - - bool blnConnectionActive; - - // Tracker *headTracker; // For upstream messages... - TFlightGearData FlightData; - QUdpSocket *inSocket; // Receive from FligthGear - QUdpSocket *outSocket; // Send to FligthGear - qint32 cmd; - qint32 fg_cmd; // Command from FlightGear - QHostAddress destIP; // Destination IP-address - int destPort; // Destination port-number - void loadSettings(); - QString getGameName() { - return "FlightGear"; - } -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class FGControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit FGControls(); - virtual ~FGControls(); - void showEvent ( QShowEvent * event ); - - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) { - theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol - } - void unRegisterProtocol() { - theProtocol = NULL; // Reset the pointer - } - -private: - Ui::UICFGControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FTNoIR_Protocol *theProtocol; - -private slots: - void doOK(); - void doCancel(); - void chkLocalPCOnlyChanged(); - void settingChanged() { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear UDP protocol"); } - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/flightgear.png"); } -}; - - -#endif//INCLUDED_FGSERVER_H -//END +/******************************************************************************** +* 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) 2013 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 . * +* * +* FGServer FGServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FGSERVER_H +#define INCLUDED_FGSERVER_H + +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ui_ftnoir_fgcontrols.h" +#include "fgtypes.h" +#include +#include +#include +#include +#include +#include "facetracknoir/global-settings.h" + +#define FT_PROGRAMID "FT_ProgramID" + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK(); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); +private: + + bool blnConnectionActive; + + // Tracker *headTracker; // For upstream messages... + TFlightGearData FlightData; + QUdpSocket *inSocket; // Receive from FligthGear + QUdpSocket *outSocket; // Send to FligthGear + qint32 cmd; + qint32 fg_cmd; // Command from FlightGear + QHostAddress destIP; // Destination IP-address + int destPort; // Destination port-number + void loadSettings(); + QString getGameName() { + return "FlightGear"; + } +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class FGControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit FGControls(); + virtual ~FGControls(); + void showEvent ( QShowEvent * event ); + + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) { + theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol + } + void unRegisterProtocol() { + theProtocol = NULL; // Reset the pointer + } + +private: + Ui::UICFGControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FTNoIR_Protocol *theProtocol; + +private slots: + void doOK(); + void doCancel(); + void chkLocalPCOnlyChanged(); + void settingChanged() { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FlightGear UDP protocol"); } + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/flightgear.png"); } +}; + + +#endif//INCLUDED_FGSERVER_H +//END diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp index b01f529b..2acd3f9c 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp @@ -1,215 +1,215 @@ -/******************************************************************************** -* 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 . * -* * -* FGServer FGServer is the Class, that communicates headpose-data * -* to FlightGear, using UDP. * -* It is based on the (Linux) example made by Melchior FRANZ. * -********************************************************************************/ -#include "ftnoir_protocol_fg.h" -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -FGControls::FGControls() : -QWidget() -{ - ui.setupUi( this ); - - QPoint offsetpos(100, 100); - //if (parent) { - // this->move(parent->pos() + offsetpos); - //} - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.chkLocalPC, SIGNAL(stateChanged(int)), this, SLOT(chkLocalPCOnlyChanged())); - connect(ui.spinIPFirstNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPSecondNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPThirdNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - - theProtocol = NULL; - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -FGControls::~FGControls() { - qDebug() << "~FGControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FGControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void FGControls::doOK() { - save(); - this->close(); -} - -// override show event -void FGControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void FGControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FGControls::loadSettings() { -// qDebug() << "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) - -// qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FG" ); - ui.chkLocalPC->setChecked (iniFile.value ( "LocalPCOnly", 1 ).toBool()); - - ui.spinIPFirstNibble->setValue( iniFile.value ( "IP-1", 192 ).toInt() ); - ui.spinIPSecondNibble->setValue( iniFile.value ( "IP-2", 168 ).toInt() ); - ui.spinIPThirdNibble->setValue( iniFile.value ( "IP-3", 2 ).toInt() ); - ui.spinIPFourthNibble->setValue( iniFile.value ( "IP-4", 1 ).toInt() ); - - ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); - iniFile.endGroup (); - - chkLocalPCOnlyChanged(); - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FGControls::save() { - 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 ( "FG" ); - iniFile.setValue ( "LocalPCOnly", ui.chkLocalPC->isChecked() ); - iniFile.setValue ( "IP-1", ui.spinIPFirstNibble->value() ); - iniFile.setValue ( "IP-2", ui.spinIPSecondNibble->value() ); - iniFile.setValue ( "IP-3", ui.spinIPThirdNibble->value() ); - iniFile.setValue ( "IP-4", ui.spinIPFourthNibble->value() ); - iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Handle change of the checkbox. -// -void FGControls::chkLocalPCOnlyChanged() { - - if ( ui.chkLocalPC->isChecked() ) { - ui.spinIPFirstNibble->setValue( 127 ); - ui.spinIPFirstNibble->setEnabled ( false ); - ui.spinIPSecondNibble->setValue( 0 ); - ui.spinIPSecondNibble->setEnabled ( false ); - ui.spinIPThirdNibble->setValue( 0 ); - ui.spinIPThirdNibble->setEnabled ( false ); - ui.spinIPFourthNibble->setValue( 1 ); - ui.spinIPFourthNibble->setEnabled ( false ); - } - else { - ui.spinIPFirstNibble->setEnabled ( true ); - ui.spinIPSecondNibble->setEnabled ( true ); - ui.spinIPThirdNibble->setEnabled ( true ); - ui.spinIPFourthNibble->setEnabled ( true ); - } - - settingsDirty = true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) -{ - return new FGControls; -} +/******************************************************************************** +* 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 . * +* * +* FGServer FGServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#include "ftnoir_protocol_fg.h" +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +FGControls::FGControls() : +QWidget() +{ + ui.setupUi( this ); + + QPoint offsetpos(100, 100); + //if (parent) { + // this->move(parent->pos() + offsetpos); + //} + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.chkLocalPC, SIGNAL(stateChanged(int)), this, SLOT(chkLocalPCOnlyChanged())); + connect(ui.spinIPFirstNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPSecondNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPThirdNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + + theProtocol = NULL; + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +FGControls::~FGControls() { + qDebug() << "~FGControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FGControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void FGControls::doOK() { + save(); + this->close(); +} + +// override show event +void FGControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FGControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FGControls::loadSettings() { +// qDebug() << "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) + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FG" ); + ui.chkLocalPC->setChecked (iniFile.value ( "LocalPCOnly", 1 ).toBool()); + + ui.spinIPFirstNibble->setValue( iniFile.value ( "IP-1", 192 ).toInt() ); + ui.spinIPSecondNibble->setValue( iniFile.value ( "IP-2", 168 ).toInt() ); + ui.spinIPThirdNibble->setValue( iniFile.value ( "IP-3", 2 ).toInt() ); + ui.spinIPFourthNibble->setValue( iniFile.value ( "IP-4", 1 ).toInt() ); + + ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); + iniFile.endGroup (); + + chkLocalPCOnlyChanged(); + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FGControls::save() { + 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 ( "FG" ); + iniFile.setValue ( "LocalPCOnly", ui.chkLocalPC->isChecked() ); + iniFile.setValue ( "IP-1", ui.spinIPFirstNibble->value() ); + iniFile.setValue ( "IP-2", ui.spinIPSecondNibble->value() ); + iniFile.setValue ( "IP-3", ui.spinIPThirdNibble->value() ); + iniFile.setValue ( "IP-4", ui.spinIPFourthNibble->value() ); + iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Handle change of the checkbox. +// +void FGControls::chkLocalPCOnlyChanged() { + + if ( ui.chkLocalPC->isChecked() ) { + ui.spinIPFirstNibble->setValue( 127 ); + ui.spinIPFirstNibble->setEnabled ( false ); + ui.spinIPSecondNibble->setValue( 0 ); + ui.spinIPSecondNibble->setEnabled ( false ); + ui.spinIPThirdNibble->setValue( 0 ); + ui.spinIPThirdNibble->setEnabled ( false ); + ui.spinIPFourthNibble->setValue( 1 ); + ui.spinIPFourthNibble->setEnabled ( false ); + } + else { + ui.spinIPFirstNibble->setEnabled ( true ); + ui.spinIPSecondNibble->setEnabled ( true ); + ui.spinIPThirdNibble->setEnabled ( true ); + ui.spinIPFourthNibble->setEnabled ( true ); + } + + settingsDirty = true; +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 8d9dcf8f..6c7e7c52 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_fg.h" -#include -#include "facetracknoir/global-settings.h" - -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() -{ - return new FTNoIR_ProtocolDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_fg.h" +#include +#include "facetracknoir/global-settings.h" + +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() +{ + return new FTNoIR_ProtocolDll; +} diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp index e4dbc614..ba053e11 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp @@ -1,205 +1,205 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FSUIPCServer FSUIPCServer is the Class, that communicates headpose-data * -* to games, using the FSUIPC.dll. * -********************************************************************************/ -#include "ftnoir_protocol_fsuipc.h" -#include "facetracknoir/global-settings.h" - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() -{ - loadSettings(); - ProgramName = "Microsoft FS2004"; - - prevPosX = 0.0f; - prevPosY = 0.0f; - prevPosZ = 0.0f; - prevRotX = 0.0f; - prevRotY = 0.0f; - prevRotZ = 0.0f; -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ - // - // Free the DLL - // - 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; - - local_x = x; - if (local_x > max_x) { - local_x = max_x; - } - if (local_x < min_x) { - local_x = min_x; - } - y = ( 16383 * local_x ) / max_x; - - return (int) y; -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { - 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 ( "FSUIPC" ); - LocationOfDLL = iniFile.value ( "LocationOfDLL", FSUIPC_FILENAME ).toString(); - qDebug() << "FSUIPCServer::loadSettings() says: Location of DLL = " << LocationOfDLL; - iniFile.endGroup (); -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { -DWORD result; -TFSState pitch; -TFSState yaw; -TFSState roll; -WORD FSZoom; - -float virtPosX; -float virtPosY; -float virtPosZ; - -float virtRotX; -float virtRotY; -float virtRotZ; - -// qDebug() << "FSUIPCServer::run() says: started!"; - - virtRotX = -headpose[Pitch]; // degrees - virtRotY = headpose[Yaw]; - virtRotZ = headpose[Roll]; - - virtPosX = 0.0f; // cm, X and Y are not working for FS2002/2004! - virtPosY = 0.0f; - virtPosZ = headpose[TZ]; - - // - // Init. the FSUIPC offsets (derived from Free-track...) - // - pitch.Control = 66503; - yaw.Control = 66504; - roll.Control = 66505; - - // - // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. - // - if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || - (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { - // - // Open the connection - // - FSUIPC_Open(SIM_ANY, &result); - - // - // Check the FS-version - // - if (((result == FSUIPC_ERR_OK) || (result == FSUIPC_ERR_OPEN)) && - ((FSUIPC_FS_Version == SIM_FS2K2) || (FSUIPC_FS_Version == SIM_FS2K4))) { -// qDebug() << "FSUIPCServer::run() says: FSUIPC opened succesfully"; - // - // Write the 4! DOF-data to FS. Only rotations and zoom are possible. - // - pitch.Value = scale2AnalogLimits(virtRotX, -180, 180); - FSUIPC_Write(0x3110, 8, &pitch, &result); - - yaw.Value = scale2AnalogLimits(virtRotY, -180, 180); - FSUIPC_Write(0x3110, 8, &yaw, &result); - - roll.Value = scale2AnalogLimits(virtRotZ, -180, 180); - FSUIPC_Write(0x3110, 8, &roll, &result); - - FSZoom = (WORD) (64/50) * virtPosZ + 64; - FSUIPC_Write(0x832E, 2, &FSZoom, &result); - - // - // Write the data, in one go! - // - FSUIPC_Process(&result); - if (result == FSUIPC_ERR_SENDMSG) { - FSUIPC_Close(); //timeout (1 second) so assume FS closed - } - } - } - - prevPosX = virtPosX; - prevPosY = virtPosY; - prevPosZ = virtPosZ; - prevRotX = virtRotX; - prevRotY = virtRotY; - prevRotZ = virtRotZ; -} - -// -// Returns 'true' if all seems OK. -// -bool FTNoIR_Protocol::checkServerInstallationOK() -{ - qDebug() << "checkServerInstallationOK says: Starting Function"; - - // - // Load the DLL. - // - FSUIPCLib.setFileName( LocationOfDLL ); - if (FSUIPCLib.load() != true) { - qDebug() << "checkServerInstallationOK says: Error loading FSUIPC DLL"; - return false; - } - else { - qDebug() << "checkServerInstallationOK says: FSUIPC DLL loaded."; - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// 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 FTNoIR_Protocol* CALLING_CONVENTION GetConstructor(void) -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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-2011 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 . * +* * +* FSUIPCServer FSUIPCServer is the Class, that communicates headpose-data * +* to games, using the FSUIPC.dll. * +********************************************************************************/ +#include "ftnoir_protocol_fsuipc.h" +#include "facetracknoir/global-settings.h" + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() +{ + loadSettings(); + ProgramName = "Microsoft FS2004"; + + prevPosX = 0.0f; + prevPosY = 0.0f; + prevPosZ = 0.0f; + prevRotX = 0.0f; + prevRotY = 0.0f; + prevRotZ = 0.0f; +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ + // + // Free the DLL + // + 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; + + local_x = x; + if (local_x > max_x) { + local_x = max_x; + } + if (local_x < min_x) { + local_x = min_x; + } + y = ( 16383 * local_x ) / max_x; + + return (int) y; +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { + 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 ( "FSUIPC" ); + LocationOfDLL = iniFile.value ( "LocationOfDLL", FSUIPC_FILENAME ).toString(); + qDebug() << "FSUIPCServer::loadSettings() says: Location of DLL = " << LocationOfDLL; + iniFile.endGroup (); +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { +DWORD result; +TFSState pitch; +TFSState yaw; +TFSState roll; +WORD FSZoom; + +float virtPosX; +float virtPosY; +float virtPosZ; + +float virtRotX; +float virtRotY; +float virtRotZ; + +// qDebug() << "FSUIPCServer::run() says: started!"; + + virtRotX = -headpose[Pitch]; // degrees + virtRotY = headpose[Yaw]; + virtRotZ = headpose[Roll]; + + virtPosX = 0.0f; // cm, X and Y are not working for FS2002/2004! + virtPosY = 0.0f; + virtPosZ = headpose[TZ]; + + // + // Init. the FSUIPC offsets (derived from Free-track...) + // + pitch.Control = 66503; + yaw.Control = 66504; + roll.Control = 66505; + + // + // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. + // + if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || + (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { + // + // Open the connection + // + FSUIPC_Open(SIM_ANY, &result); + + // + // Check the FS-version + // + if (((result == FSUIPC_ERR_OK) || (result == FSUIPC_ERR_OPEN)) && + ((FSUIPC_FS_Version == SIM_FS2K2) || (FSUIPC_FS_Version == SIM_FS2K4))) { +// qDebug() << "FSUIPCServer::run() says: FSUIPC opened succesfully"; + // + // Write the 4! DOF-data to FS. Only rotations and zoom are possible. + // + pitch.Value = scale2AnalogLimits(virtRotX, -180, 180); + FSUIPC_Write(0x3110, 8, &pitch, &result); + + yaw.Value = scale2AnalogLimits(virtRotY, -180, 180); + FSUIPC_Write(0x3110, 8, &yaw, &result); + + roll.Value = scale2AnalogLimits(virtRotZ, -180, 180); + FSUIPC_Write(0x3110, 8, &roll, &result); + + FSZoom = (WORD) (64/50) * virtPosZ + 64; + FSUIPC_Write(0x832E, 2, &FSZoom, &result); + + // + // Write the data, in one go! + // + FSUIPC_Process(&result); + if (result == FSUIPC_ERR_SENDMSG) { + FSUIPC_Close(); //timeout (1 second) so assume FS closed + } + } + } + + prevPosX = virtPosX; + prevPosY = virtPosY; + prevPosZ = virtPosZ; + prevRotX = virtRotX; + prevRotY = virtRotY; + prevRotZ = virtRotZ; +} + +// +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol::checkServerInstallationOK() +{ + qDebug() << "checkServerInstallationOK says: Starting Function"; + + // + // Load the DLL. + // + FSUIPCLib.setFileName( LocationOfDLL ); + if (FSUIPCLib.load() != true) { + qDebug() << "checkServerInstallationOK says: Error loading FSUIPC DLL"; + return false; + } + else { + qDebug() << "checkServerInstallationOK says: FSUIPC DLL loaded."; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// 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 FTNoIR_Protocol* CALLING_CONVENTION 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 5da1d2ca..99478a54 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.h @@ -1,131 +1,131 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FSUIPCServer FSUIPCServer is the Class, that communicates headpose-data * -* to games, using the FSUIPC.dll. * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FSUIPCSERVER_H -#define INCLUDED_FSUIPCSERVER_H - -#include "Windows.h" -#include -#include "FSUIPC_User.h" -#include "facetracknoir/global-settings.h" - -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h" -#include "ui_FTNoIR_FSUIPCcontrols.h" -#include -#include -#include -#include -#include -#include -#include - -#define FSUIPC_FILENAME "C:\\Program Files\\Microsoft Games\\Flight Simulator 9\\Modules\\FSUIPC.dll" - -// -// Define the structures necessary for the FSUIPC_Write calls -// -#pragma pack(push,1) // All fields in structure must be byte aligned. -typedef struct -{ - int Control; // Control identifier - int Value; // Value of DOF -} TFSState; -#pragma pack(pop) - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK(); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); - QString getGameName() { - return "Microsoft Flight Simulator X"; - } -private: - // Private properties - QString ProgramName; - QLibrary FSUIPCLib; - QString LocationOfDLL; - float prevPosX, prevPosY, prevPosZ, prevRotX, prevRotY, prevRotZ; - - static int scale2AnalogLimits( float x, float min_x, float max_x ); - void loadSettings(); -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class FSUIPCControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit FSUIPCControls(); - virtual ~FSUIPCControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) { - theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol - } - void unRegisterProtocol() { - theProtocol = NULL; // Reset the pointer - } - -private: - Ui::UICFSUIPCControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FTNoIR_Protocol *theProtocol; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; }; - void getLocationOfDLL(); -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FS2002/FS2004"); }; - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FSUIPC"); }; - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft FS2004 protocol"); }; - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/fs9.png"); }; -}; - - -#endif//INCLUDED_FSUIPCSERVER_H -//END +/******************************************************************************** +* 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-2011 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 . * +* * +* FSUIPCServer FSUIPCServer is the Class, that communicates headpose-data * +* to games, using the FSUIPC.dll. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FSUIPCSERVER_H +#define INCLUDED_FSUIPCSERVER_H + +#include "Windows.h" +#include +#include "FSUIPC_User.h" +#include "facetracknoir/global-settings.h" + +#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h" +#include "ui_FTNoIR_FSUIPCcontrols.h" +#include +#include +#include +#include +#include +#include +#include + +#define FSUIPC_FILENAME "C:\\Program Files\\Microsoft Games\\Flight Simulator 9\\Modules\\FSUIPC.dll" + +// +// Define the structures necessary for the FSUIPC_Write calls +// +#pragma pack(push,1) // All fields in structure must be byte aligned. +typedef struct +{ + int Control; // Control identifier + int Value; // Value of DOF +} TFSState; +#pragma pack(pop) + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK(); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); + QString getGameName() { + return "Microsoft Flight Simulator X"; + } +private: + // Private properties + QString ProgramName; + QLibrary FSUIPCLib; + QString LocationOfDLL; + float prevPosX, prevPosY, prevPosZ, prevRotX, prevRotY, prevRotZ; + + static int scale2AnalogLimits( float x, float min_x, float max_x ); + void loadSettings(); +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class FSUIPCControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit FSUIPCControls(); + virtual ~FSUIPCControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) { + theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol + } + void unRegisterProtocol() { + theProtocol = NULL; // Reset the pointer + } + +private: + Ui::UICFSUIPCControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FTNoIR_Protocol *theProtocol; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; }; + void getLocationOfDLL(); +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FS2002/FS2004"); }; + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FSUIPC"); }; + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft FS2004 protocol"); }; + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/fs9.png"); }; +}; + + +#endif//INCLUDED_FSUIPCSERVER_H +//END diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp index abe9329c..90ed22b2 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp @@ -1,185 +1,185 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_fsuipc.h" -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -FSUIPCControls::FSUIPCControls() : -QWidget() -{ - ui.setupUi( this ); - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.btnFindDLL, SIGNAL(clicked()), this, SLOT(getLocationOfDLL())); - - theProtocol = NULL; - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -FSUIPCControls::~FSUIPCControls() { - qDebug() << "~FSUIPCControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FSUIPCControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void FSUIPCControls::doOK() { - save(); - this->close(); -} - -// override show event -void FSUIPCControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void FSUIPCControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FSUIPCControls::loadSettings() { - - qDebug() << "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) - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FSUIPC" ); - ui.txtLocationOfDLL->setText(iniFile.value ( "LocationOfDLL", FSUIPC_FILENAME ).toString() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FSUIPCControls::save() { - - qDebug() << "save() says: started"; - - 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 ( "FSUIPC" ); - iniFile.setValue ( "LocationOfDLL", ui.txtLocationOfDLL->text() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Show the Dialog to set the DLL's location -// -void FSUIPCControls::getLocationOfDLL() -{ - // - // Get the new filename of the INI-file. - // - QString fileName = QFileDialog::getOpenFileName(this, tr("Locate file"), - ui.txtLocationOfDLL->text(), - tr("FSUIPC DLL file (FSUIPC*.dll);;All Files (*)")); - if (!fileName.isEmpty()) { - ui.txtLocationOfDLL->setText( fileName ); - settingsDirty = true; - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog(void) -{ - return new FSUIPCControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_fsuipc.h" +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +FSUIPCControls::FSUIPCControls() : +QWidget() +{ + ui.setupUi( this ); + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.btnFindDLL, SIGNAL(clicked()), this, SLOT(getLocationOfDLL())); + + theProtocol = NULL; + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +FSUIPCControls::~FSUIPCControls() { + qDebug() << "~FSUIPCControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FSUIPCControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void FSUIPCControls::doOK() { + save(); + this->close(); +} + +// override show event +void FSUIPCControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FSUIPCControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FSUIPCControls::loadSettings() { + + qDebug() << "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) + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FSUIPC" ); + ui.txtLocationOfDLL->setText(iniFile.value ( "LocationOfDLL", FSUIPC_FILENAME ).toString() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FSUIPCControls::save() { + + qDebug() << "save() says: started"; + + 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 ( "FSUIPC" ); + iniFile.setValue ( "LocationOfDLL", ui.txtLocationOfDLL->text() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Show the Dialog to set the DLL's location +// +void FSUIPCControls::getLocationOfDLL() +{ + // + // Get the new filename of the INI-file. + // + QString fileName = QFileDialog::getOpenFileName(this, tr("Locate file"), + ui.txtLocationOfDLL->text(), + tr("FSUIPC DLL file (FSUIPC*.dll);;All Files (*)")); + if (!fileName.isEmpty()) { + ui.txtLocationOfDLL->setText( fileName ); + settingsDirty = true; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 c6ef3e38..b0ca2eee 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_fsuipc.h" -#include -#include "facetracknoir/global-settings.h" - -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(void) -{ - return new FTNoIR_ProtocolDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_fsuipc.h" +#include +#include "facetracknoir/global-settings.h" + +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(void) +{ + return new FTNoIR_ProtocolDll; +} diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp index 6e26c412..597f2a5f 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp @@ -1,283 +1,283 @@ -/******************************************************************************** -* 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) 2013 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 . * -* * -* FTServer FTServer is the Class, that communicates headpose-data * -* to games, using the FreeTrackClient.dll. * -********************************************************************************/ -#include -#include "ftnoir_protocol_ft.h" -#include "ftnoir_csv/csv.h" - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() : - shm(FT_MM_DATA, FREETRACK_MUTEX, sizeof(FTMemMap)) -{ - pMemData = (FTMemMap*) shm.mem; - useTIRViews = false; - useDummyExe = false; - intUsedInterface = 0; - - loadSettings(); - - ProgramName = ""; - intGameID = 0; - - viewsStart = 0; - viewsStop = 0; -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ - - qDebug()<< "~FTNoIR_Protocol: Destructor started."; - - // - // Stop if started - // - if (viewsStop != NULL) { - qDebug()<< "~FTNoIR_Protocol: Stopping TIRViews."; - viewsStop(); - FTIRViewsLib.unload(); - } -} - -// -// Read the game-data from CSV -// - - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { - 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 ( "FT" ); - intUsedInterface = iniFile.value ( "UsedInterface", 0 ).toInt(); - iniFile.endGroup (); - - // - // Use the settings-section from the deprecated fake-TIR protocol, as they are most likely to be found there. - // - iniFile.beginGroup ( "FTIR" ); - useTIRViews = iniFile.value ( "useTIRViews", 0 ).toBool(); - useDummyExe = iniFile.value ( "useDummyExe", 1 ).toBool(); - iniFile.endGroup (); -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { -float virtPosX; -float virtPosY; -float virtPosZ; - -float virtRotX; -float virtRotY; -float virtRotZ; - -float headPosX; -float headPosY; -float headPosZ; - -float headRotX; -float headRotY; -float headRotZ; - - // - // Scale the Raw measurements to the client measurements. - // - headRotX = getRadsFromDegrees(rawheadpose[Pitch]); - headRotY = getRadsFromDegrees(rawheadpose[Yaw]); - headRotZ = getRadsFromDegrees(rawheadpose[Roll]); - headPosX = rawheadpose[TX] * 10; - headPosY = rawheadpose[TY] * 10; - headPosZ = rawheadpose[TZ] * 10; - - virtRotX = getRadsFromDegrees(headpose[Pitch]); - virtRotY = getRadsFromDegrees(headpose[Yaw]); - virtRotZ = getRadsFromDegrees(headpose[Roll]); - virtPosX = headpose[TX] * 10; - virtPosY = headpose[TY] * 10; - virtPosZ = headpose[TZ] * 10; - - 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.X2 = 0; - pMemData->data.X3 = 0; - pMemData->data.X4 = 0; - pMemData->data.Y1 = 0; - pMemData->data.Y2 = 0; - pMemData->data.Y3 = 0; - pMemData->data.Y4 = 0; - - // - // Check if the handle that was sent to the Game, was changed (on x64, this will be done by the ED-API) - // If the "Report Program Name" command arrives (which is a '1', for now), raise the event from here! - // - // - // The game-ID was changed? - // - if (intGameID != pMemData->GameID) - { - QString gamename; - CSV::getGameData(pMemData->GameID, pMemData->table, gamename); - pMemData->GameID2 = pMemData->GameID; - intGameID = pMemData->GameID; - QMutexLocker foo(&this->game_name_mutex); - connected_game = gamename; - } - - pMemData->data.DataID += 1; - - shm.unlock(); -} - -void FTNoIR_Protocol::start_tirviews() { - QString aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; - if ( QFile::exists( aFileName )) { - FTIRViewsLib.setFileName(aFileName); - FTIRViewsLib.load(); - - viewsStart = (importTIRViewsStart) FTIRViewsLib.resolve("TIRViewsStart"); - if (viewsStart == NULL) { - qDebug() << "FTServer::run() says: TIRViewsStart function not found in DLL!"; - } - else { - qDebug() << "FTServer::run() says: TIRViewsStart executed!"; - viewsStart(); - } - - // - // Load the Stop function from TIRViews.dll. Call it when terminating the thread. - // - viewsStop = (importTIRViewsStop) FTIRViewsLib.resolve("TIRViewsStop"); - if (viewsStop == NULL) { - qDebug() << "FTServer::run() says: TIRViewsStop function not found in DLL!"; - } - } -} - -void FTNoIR_Protocol::start_dummy() { - QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe"; - dummyTrackIR.startDetached("\"" + program + "\""); - - 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 - - qDebug() << "checkServerInstallationOK says: Starting Function"; - - // - // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s). - // - aLocation = QCoreApplication::applicationDirPath() + "/"; - - qDebug() << "checkServerInstallationOK says: used interface = " << intUsedInterface; - switch (intUsedInterface) { - case 0: // Use both interfaces - settings.setValue( "Path" , aLocation ); - settingsTIR.setValue( "Path" , aLocation ); - break; - case 1: // Use FreeTrack, disable TrackIR - settings.setValue( "Path" , aLocation ); - settingsTIR.setValue( "Path" , "" ); - break; - case 2: // Use TrackIR, disable FreeTrack - settings.setValue( "Path" , "" ); - settingsTIR.setValue( "Path" , aLocation ); - break; - default: - // should never be reached - break; - } - - // - // TIRViews must be started first, or the NPClient DLL will never be loaded. - // - if (useTIRViews) { - start_tirviews(); - } - - // - // Check if TIRViews or dummy TrackIR.exe is required for this game - // - if (useDummyExe) { - start_dummy(); - } - - if (shm.mem == (void*) 0 || shm.mem == (void*) -1) - return false; - - pMemData->data.DataID = 1; - pMemData->data.CamWidth = 100; - pMemData->data.CamHeight = 250; - pMemData->GameID2 = 0; - memset(pMemData->table, 0, 8); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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) 2013 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 . * +* * +* FTServer FTServer is the Class, that communicates headpose-data * +* to games, using the FreeTrackClient.dll. * +********************************************************************************/ +#include +#include "ftnoir_protocol_ft.h" +#include "ftnoir_csv/csv.h" + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() : + shm(FT_MM_DATA, FREETRACK_MUTEX, sizeof(FTMemMap)) +{ + pMemData = (FTMemMap*) shm.mem; + useTIRViews = false; + useDummyExe = false; + intUsedInterface = 0; + + loadSettings(); + + ProgramName = ""; + intGameID = 0; + + viewsStart = 0; + viewsStop = 0; +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ + + qDebug()<< "~FTNoIR_Protocol: Destructor started."; + + // + // Stop if started + // + if (viewsStop != NULL) { + qDebug()<< "~FTNoIR_Protocol: Stopping TIRViews."; + viewsStop(); + FTIRViewsLib.unload(); + } +} + +// +// Read the game-data from CSV +// + + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { + 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 ( "FT" ); + intUsedInterface = iniFile.value ( "UsedInterface", 0 ).toInt(); + iniFile.endGroup (); + + // + // Use the settings-section from the deprecated fake-TIR protocol, as they are most likely to be found there. + // + iniFile.beginGroup ( "FTIR" ); + useTIRViews = iniFile.value ( "useTIRViews", 0 ).toBool(); + useDummyExe = iniFile.value ( "useDummyExe", 1 ).toBool(); + iniFile.endGroup (); +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { +float virtPosX; +float virtPosY; +float virtPosZ; + +float virtRotX; +float virtRotY; +float virtRotZ; + +float headPosX; +float headPosY; +float headPosZ; + +float headRotX; +float headRotY; +float headRotZ; + + // + // Scale the Raw measurements to the client measurements. + // + headRotX = getRadsFromDegrees(rawheadpose[Pitch]); + headRotY = getRadsFromDegrees(rawheadpose[Yaw]); + headRotZ = getRadsFromDegrees(rawheadpose[Roll]); + headPosX = rawheadpose[TX] * 10; + headPosY = rawheadpose[TY] * 10; + headPosZ = rawheadpose[TZ] * 10; + + virtRotX = getRadsFromDegrees(headpose[Pitch]); + virtRotY = getRadsFromDegrees(headpose[Yaw]); + virtRotZ = getRadsFromDegrees(headpose[Roll]); + virtPosX = headpose[TX] * 10; + virtPosY = headpose[TY] * 10; + virtPosZ = headpose[TZ] * 10; + + 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.X2 = 0; + pMemData->data.X3 = 0; + pMemData->data.X4 = 0; + pMemData->data.Y1 = 0; + pMemData->data.Y2 = 0; + pMemData->data.Y3 = 0; + pMemData->data.Y4 = 0; + + // + // Check if the handle that was sent to the Game, was changed (on x64, this will be done by the ED-API) + // If the "Report Program Name" command arrives (which is a '1', for now), raise the event from here! + // + // + // The game-ID was changed? + // + if (intGameID != pMemData->GameID) + { + QString gamename; + CSV::getGameData(pMemData->GameID, pMemData->table, gamename); + pMemData->GameID2 = pMemData->GameID; + intGameID = pMemData->GameID; + QMutexLocker foo(&this->game_name_mutex); + connected_game = gamename; + } + + pMemData->data.DataID += 1; + + shm.unlock(); +} + +void FTNoIR_Protocol::start_tirviews() { + QString aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; + if ( QFile::exists( aFileName )) { + FTIRViewsLib.setFileName(aFileName); + FTIRViewsLib.load(); + + viewsStart = (importTIRViewsStart) FTIRViewsLib.resolve("TIRViewsStart"); + if (viewsStart == NULL) { + qDebug() << "FTServer::run() says: TIRViewsStart function not found in DLL!"; + } + else { + qDebug() << "FTServer::run() says: TIRViewsStart executed!"; + viewsStart(); + } + + // + // Load the Stop function from TIRViews.dll. Call it when terminating the thread. + // + viewsStop = (importTIRViewsStop) FTIRViewsLib.resolve("TIRViewsStop"); + if (viewsStop == NULL) { + qDebug() << "FTServer::run() says: TIRViewsStop function not found in DLL!"; + } + } +} + +void FTNoIR_Protocol::start_dummy() { + QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe"; + dummyTrackIR.startDetached("\"" + program + "\""); + + 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 + + qDebug() << "checkServerInstallationOK says: Starting Function"; + + // + // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s). + // + aLocation = QCoreApplication::applicationDirPath() + "/"; + + qDebug() << "checkServerInstallationOK says: used interface = " << intUsedInterface; + switch (intUsedInterface) { + case 0: // Use both interfaces + settings.setValue( "Path" , aLocation ); + settingsTIR.setValue( "Path" , aLocation ); + break; + case 1: // Use FreeTrack, disable TrackIR + settings.setValue( "Path" , aLocation ); + settingsTIR.setValue( "Path" , "" ); + break; + case 2: // Use TrackIR, disable FreeTrack + settings.setValue( "Path" , "" ); + settingsTIR.setValue( "Path" , aLocation ); + break; + default: + // should never be reached + break; + } + + // + // TIRViews must be started first, or the NPClient DLL will never be loaded. + // + if (useTIRViews) { + start_tirviews(); + } + + // + // Check if TIRViews or dummy TrackIR.exe is required for this game + // + if (useDummyExe) { + start_dummy(); + } + + if (shm.mem == (void*) 0 || shm.mem == (void*) -1) + return false; + + pMemData->data.DataID = 1; + pMemData->data.CamWidth = 100; + pMemData->data.CamHeight = 250; + pMemData->GameID2 = 0; + memset(pMemData->table, 0, 8); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Protocol; +} diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.h b/ftnoir_protocol_ft/ftnoir_protocol_ft.h index f87c7300..05860907 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.h +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.h @@ -1,141 +1,141 @@ -/******************************************************************************** -* 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 . * -* * -* 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 "ui_ftnoir_ftcontrols.h" -#include "facetracknoir/global-settings.h" -#include "fttypes.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat/compat.h" -//#include "math.h" - -//typedef char *(WINAPI *importProvider)(void); -typedef void (WINAPI *importTIRViewsStart)(void); -typedef void (WINAPI *importTIRViewsStop)(void); - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK( ); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); - QString getGameName() { - QMutexLocker foo(&game_name_mutex); - return connected_game; - } - -private: - importTIRViewsStart viewsStart; // Functions inside TIRViews.dll - importTIRViewsStop viewsStop; - - FTMemMap *pMemData; - QString game_name; - PortableLockedShm shm; - - // Private properties - QString ProgramName; - QLibrary FTIRViewsLib; - QProcess dummyTrackIR; - int intGameID; - int intUsedInterface; // Determine which interface to use (or to hide from the game) - bool useTIRViews; // Needs to be in the Settings dialog - bool useDummyExe; - float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } - void loadSettings(); - void start_tirviews(); - void start_dummy(); - - QString connected_game; - QMutex game_name_mutex; -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class FTControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit FTControls(); - virtual ~FTControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) { - theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol - } - void unRegisterProtocol() { - theProtocol = NULL; // Reset the pointer - } - -private: - Ui::UICFTControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FTNoIR_Protocol *theProtocol; - -private slots: - void selectDLL(); - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; } - void settingChanged(int) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Enhanced FreeTrack protocol"); } - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/freetrack.png"); } -}; - - -#endif//INCLUDED_FTSERVER_H -//END +/******************************************************************************** +* 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 . * +* * +* 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 "ui_ftnoir_ftcontrols.h" +#include "facetracknoir/global-settings.h" +#include "fttypes.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compat/compat.h" +//#include "math.h" + +//typedef char *(WINAPI *importProvider)(void); +typedef void (WINAPI *importTIRViewsStart)(void); +typedef void (WINAPI *importTIRViewsStop)(void); + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK( ); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); + QString getGameName() { + QMutexLocker foo(&game_name_mutex); + return connected_game; + } + +private: + importTIRViewsStart viewsStart; // Functions inside TIRViews.dll + importTIRViewsStop viewsStop; + + FTMemMap *pMemData; + QString game_name; + PortableLockedShm shm; + + // Private properties + QString ProgramName; + QLibrary FTIRViewsLib; + QProcess dummyTrackIR; + int intGameID; + int intUsedInterface; // Determine which interface to use (or to hide from the game) + bool useTIRViews; // Needs to be in the Settings dialog + bool useDummyExe; + float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } + void loadSettings(); + void start_tirviews(); + void start_dummy(); + + QString connected_game; + QMutex game_name_mutex; +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class FTControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit FTControls(); + virtual ~FTControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) { + theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol + } + void unRegisterProtocol() { + theProtocol = NULL; // Reset the pointer + } + +private: + Ui::UICFTControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FTNoIR_Protocol *theProtocol; + +private slots: + void selectDLL(); + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; } + void settingChanged(int) { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Enhanced FreeTrack protocol"); } + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/freetrack.png"); } +}; + + +#endif//INCLUDED_FTSERVER_H +//END diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp index 2442d6b2..810bef50 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp @@ -1,225 +1,225 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_ft.h" -#include -#include - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -FTControls::FTControls() : -QWidget() -{ - QString aFileName; // File Path and Name - - ui.setupUi( this ); - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL())); - connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); - connect(ui.chkStartDummy, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); - connect(ui.cbxSelectInterface, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); - - ui.cbxSelectInterface->addItem("Enable both"); - ui.cbxSelectInterface->addItem("Use FreeTrack, hide TrackIR"); - ui.cbxSelectInterface->addItem("Use TrackIR, hide FreeTrack"); - - theProtocol = NULL; - - // Load the settings from the current .INI-file - loadSettings(); - - - aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; - if ( !QFile::exists( aFileName ) ) { - ui.chkTIRViews->setChecked( false ); - ui.chkTIRViews->setEnabled ( false ); - - // - // Best do this save() last, or it will continually reset the settings... :-( - // - save(); - } - else { - ui.chkTIRViews->setEnabled ( true ); - } - - -} - -// -// Destructor for server-dialog -// -FTControls::~FTControls() { - qDebug() << "~FTControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FTControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void FTControls::doOK() { - save(); - this->close(); -} - -// override show event -void FTControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void FTControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTControls::loadSettings() { - qDebug() << "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) - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FT" ); - ui.cbxSelectInterface->setCurrentIndex( iniFile.value ( "UsedInterface", 0 ).toInt() ); - iniFile.endGroup (); - - iniFile.beginGroup ( "FTIR" ); - ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool()); - ui.chkStartDummy->setChecked (iniFile.value ( "useDummyExe", 1 ).toBool()); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FTControls::save() { - 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 ( "FT" ); - iniFile.setValue ( "UsedInterface", ui.cbxSelectInterface->currentIndex()); - iniFile.endGroup (); - - iniFile.beginGroup ( "FTIR" ); - iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() ); - iniFile.setValue ( "useDummyExe", ui.chkStartDummy->isChecked() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Select a NPClient.dll file, to repair the Location in the Registry. -// Several program distribute their own version of this file. -// -void FTControls::selectDLL() { - QFileDialog::Options options; - QFileDialog::FileMode mode; - - options |= QFileDialog::DontUseNativeDialog; - mode = QFileDialog::ExistingFile; - QString selectedFilter; - 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 - - settingsTIR.setValue( "Path" , aLocation ); - } - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) -{ - return new FTControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_ft.h" +#include +#include + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +FTControls::FTControls() : +QWidget() +{ + QString aFileName; // File Path and Name + + ui.setupUi( this ); + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL())); + connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); + connect(ui.chkStartDummy, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); + connect(ui.cbxSelectInterface, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); + + ui.cbxSelectInterface->addItem("Enable both"); + ui.cbxSelectInterface->addItem("Use FreeTrack, hide TrackIR"); + ui.cbxSelectInterface->addItem("Use TrackIR, hide FreeTrack"); + + theProtocol = NULL; + + // Load the settings from the current .INI-file + loadSettings(); + + + aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; + if ( !QFile::exists( aFileName ) ) { + ui.chkTIRViews->setChecked( false ); + ui.chkTIRViews->setEnabled ( false ); + + // + // Best do this save() last, or it will continually reset the settings... :-( + // + save(); + } + else { + ui.chkTIRViews->setEnabled ( true ); + } + + +} + +// +// Destructor for server-dialog +// +FTControls::~FTControls() { + qDebug() << "~FTControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FTControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void FTControls::doOK() { + save(); + this->close(); +} + +// override show event +void FTControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FTControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTControls::loadSettings() { + qDebug() << "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) + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FT" ); + ui.cbxSelectInterface->setCurrentIndex( iniFile.value ( "UsedInterface", 0 ).toInt() ); + iniFile.endGroup (); + + iniFile.beginGroup ( "FTIR" ); + ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool()); + ui.chkStartDummy->setChecked (iniFile.value ( "useDummyExe", 1 ).toBool()); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FTControls::save() { + 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 ( "FT" ); + iniFile.setValue ( "UsedInterface", ui.cbxSelectInterface->currentIndex()); + iniFile.endGroup (); + + iniFile.beginGroup ( "FTIR" ); + iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() ); + iniFile.setValue ( "useDummyExe", ui.chkStartDummy->isChecked() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Select a NPClient.dll file, to repair the Location in the Registry. +// Several program distribute their own version of this file. +// +void FTControls::selectDLL() { + QFileDialog::Options options; + QFileDialog::FileMode mode; + + options |= QFileDialog::DontUseNativeDialog; + mode = QFileDialog::ExistingFile; + QString selectedFilter; + 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 + + settingsTIR.setValue( "Path" , aLocation ); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 5b6087b5..f4e4a40e 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp @@ -1,46 +1,46 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_ft.h" -#include - -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. -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() -{ - return new FTNoIR_ProtocolDll; +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_ft.h" +#include + +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. +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +{ + return new FTNoIR_ProtocolDll; } \ No newline at end of file diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp index 1fbc0b43..32d11c37 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp @@ -1,118 +1,118 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FTNServer FTNServer is the Class, that communicates headpose-data * -* to another FaceTrackNoIR program, using UDP. * -* It is based on the (Linux) example made by Melchior FRANZ. * -********************************************************************************/ -#include "ftnoir_protocol_ftn.h" -#include -#include "facetracknoir/global-settings.h" - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() -{ - loadSettings(); - outSocket = 0; -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ - if (outSocket != 0) { - outSocket->close(); - delete outSocket; - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { - 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 ( "FTN" ); - - QString destAddr = iniFile.value ( "IP-1", 192 ).toString() + "." + iniFile.value ( "IP-2", 168 ).toString() + "." + iniFile.value ( "IP-3", 2 ).toString() + "." + iniFile.value ( "IP-4", 1 ).toString(); - destIP = QHostAddress( destAddr ); - destPort = iniFile.value ( "PortNumber", 5550 ).toInt(); - - iniFile.endGroup (); -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { - int no_bytes; - double test_data[6]; - // - // Copy the Raw measurements directly to the client. - // - for (int i = 0; i < 6; i++) - test_data[i] = headpose[i]; - // - // Try to send an UDP-message to the receiver - // - - //! [1] - if (outSocket != 0) { - no_bytes = outSocket->writeDatagram((const char *) test_data, sizeof( test_data ), destIP, destPort); - if ( no_bytes > 0) { -// qDebug() << "FTNServer::writePendingDatagrams says: bytes send =" << no_bytes << sizeof( double ); - } - else { - qDebug() << "FTNServer::writePendingDatagrams says: nothing sent!"; - } - } -} - -// -// Check if the Client DLL exists and load it (to test it), if so. -// Returns 'true' if all seems OK. -// -bool FTNoIR_Protocol::checkServerInstallationOK() -{ - if (outSocket == 0) { - outSocket = new QUdpSocket(); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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-2011 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 . * +* * +* FTNServer FTNServer is the Class, that communicates headpose-data * +* to another FaceTrackNoIR program, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#include "ftnoir_protocol_ftn.h" +#include +#include "facetracknoir/global-settings.h" + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() +{ + loadSettings(); + outSocket = 0; +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ + if (outSocket != 0) { + outSocket->close(); + delete outSocket; + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { + 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 ( "FTN" ); + + QString destAddr = iniFile.value ( "IP-1", 192 ).toString() + "." + iniFile.value ( "IP-2", 168 ).toString() + "." + iniFile.value ( "IP-3", 2 ).toString() + "." + iniFile.value ( "IP-4", 1 ).toString(); + destIP = QHostAddress( destAddr ); + destPort = iniFile.value ( "PortNumber", 5550 ).toInt(); + + iniFile.endGroup (); +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { + int no_bytes; + double test_data[6]; + // + // Copy the Raw measurements directly to the client. + // + for (int i = 0; i < 6; i++) + test_data[i] = headpose[i]; + // + // Try to send an UDP-message to the receiver + // + + //! [1] + if (outSocket != 0) { + no_bytes = outSocket->writeDatagram((const char *) test_data, sizeof( test_data ), destIP, destPort); + if ( no_bytes > 0) { +// qDebug() << "FTNServer::writePendingDatagrams says: bytes send =" << no_bytes << sizeof( double ); + } + else { + qDebug() << "FTNServer::writePendingDatagrams says: nothing sent!"; + } + } +} + +// +// Check if the Client DLL exists and load it (to test it), if so. +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol::checkServerInstallationOK() +{ + if (outSocket == 0) { + outSocket = new QUdpSocket(); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Protocol; +} diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h index 1c4b493e..31247d1e 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.h @@ -1,104 +1,104 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FTNServer FTNServer is the Class, that communicates headpose-data * -* to FlightGear, using UDP. * -* It is based on the (Linux) example made by Melchior FRANZ. * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_FTNSERVER_H -#define INCLUDED_FTNSERVER_H - -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ui_ftnoir_ftncontrols.h" -#include -#include -#include -#include -#include -#include "facetracknoir/global-settings.h" - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK(); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); - QString getGameName() { - return "UDP Tracker"; - } - -private: - QUdpSocket *outSocket; // Send to FaceTrackNoIR - QHostAddress destIP; // Destination IP-address - int destPort; // Destination port-number - void loadSettings(); -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class FTNControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit FTNControls(); - virtual ~FTNControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) {} - void unRegisterProtocol() {} - -private: - Ui::UICFTNControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FTN Client"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR Client protocol"); } - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/facetracknoir.png"); } -}; - -#endif//INCLUDED_FTNSERVER_H -//END +/******************************************************************************** +* 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-2011 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 . * +* * +* FTNServer FTNServer is the Class, that communicates headpose-data * +* to FlightGear, using UDP. * +* It is based on the (Linux) example made by Melchior FRANZ. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FTNSERVER_H +#define INCLUDED_FTNSERVER_H + +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ui_ftnoir_ftncontrols.h" +#include +#include +#include +#include +#include +#include "facetracknoir/global-settings.h" + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK(); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); + QString getGameName() { + return "UDP Tracker"; + } + +private: + QUdpSocket *outSocket; // Send to FaceTrackNoIR + QHostAddress destIP; // Destination IP-address + int destPort; // Destination port-number + void loadSettings(); +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class FTNControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit FTNControls(); + virtual ~FTNControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) {} + void unRegisterProtocol() {} + +private: + Ui::UICFTNControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FTN Client"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FaceTrackNoIR Client protocol"); } + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/facetracknoir.png"); } +}; + +#endif//INCLUDED_FTNSERVER_H +//END diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp index 328d866a..c902d6f8 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp @@ -1,180 +1,180 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_ftn.h" -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -FTNControls::FTNControls() : -QWidget() -{ - ui.setupUi( this ); - - QPoint offsetpos(100, 100); - //if (parent) { - // this->move(parent->pos() + offsetpos); - //} - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.spinIPFirstNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPSecondNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPThirdNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -FTNControls::~FTNControls() { - qDebug() << "~FTNControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void FTNControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void FTNControls::doOK() { - save(); - this->close(); -} - -// override show event -void FTNControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void FTNControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNControls::loadSettings() { -// qDebug() << "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) - -// qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FTN" ); - ui.spinIPFirstNibble->setValue( iniFile.value ( "IP-1", 192 ).toInt() ); - ui.spinIPSecondNibble->setValue( iniFile.value ( "IP-2", 168 ).toInt() ); - ui.spinIPThirdNibble->setValue( iniFile.value ( "IP-3", 2 ).toInt() ); - ui.spinIPFourthNibble->setValue( iniFile.value ( "IP-4", 1 ).toInt() ); - - ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void FTNControls::save() { - 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 ( "FTN" ); - iniFile.setValue ( "IP-1", ui.spinIPFirstNibble->value() ); - iniFile.setValue ( "IP-2", ui.spinIPSecondNibble->value() ); - iniFile.setValue ( "IP-3", ui.spinIPThirdNibble->value() ); - iniFile.setValue ( "IP-4", ui.spinIPFourthNibble->value() ); - iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) -{ - return new FTNControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_ftn.h" +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +FTNControls::FTNControls() : +QWidget() +{ + ui.setupUi( this ); + + QPoint offsetpos(100, 100); + //if (parent) { + // this->move(parent->pos() + offsetpos); + //} + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.spinIPFirstNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPSecondNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPThirdNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinIPFourthNibble, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +FTNControls::~FTNControls() { + qDebug() << "~FTNControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void FTNControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void FTNControls::doOK() { + save(); + this->close(); +} + +// override show event +void FTNControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void FTNControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNControls::loadSettings() { +// qDebug() << "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) + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FTN" ); + ui.spinIPFirstNibble->setValue( iniFile.value ( "IP-1", 192 ).toInt() ); + ui.spinIPSecondNibble->setValue( iniFile.value ( "IP-2", 168 ).toInt() ); + ui.spinIPThirdNibble->setValue( iniFile.value ( "IP-3", 2 ).toInt() ); + ui.spinIPFourthNibble->setValue( iniFile.value ( "IP-4", 1 ).toInt() ); + + ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void FTNControls::save() { + 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 ( "FTN" ); + iniFile.setValue ( "IP-1", ui.spinIPFirstNibble->value() ); + iniFile.setValue ( "IP-2", ui.spinIPSecondNibble->value() ); + iniFile.setValue ( "IP-3", ui.spinIPThirdNibble->value() ); + iniFile.setValue ( "IP-4", ui.spinIPFourthNibble->value() ); + iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 c52d6c9e..acd3b990 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_ftn.h" -#include -#include "facetracknoir/global-settings.h" - -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() -{ - return new FTNoIR_ProtocolDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_ftn.h" +#include +#include "facetracknoir/global-settings.h" + +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() +{ + return new FTNoIR_ProtocolDll; +} diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp index 16a501b6..6b013d74 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp @@ -1,101 +1,101 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FTNoIR_Protocol_Mouse The Class, that communicates headpose-data by * -* generating Mouse commands. * -* Many games (like FPS's) support Mouse-look features, * -* but no face-tracking. * -********************************************************************************/ -#include "ftnoir_protocol_mouse.h" -#include "facetracknoir/global-settings.h" - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() -{ - loadSettings(); -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { - 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 ( "Mouse" ); - Mouse_X = (FTN_AngleName) (iniFile.value ( "Mouse_X", 0 ).toInt()); - Mouse_Y = (FTN_AngleName) (iniFile.value ( "Mouse_Y", 0 ).toInt()); - iniFile.endGroup (); -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { - float fMouse_X = 0; - float fMouse_Y = 0; - - if (Mouse_X > 0 && Mouse_X <= 6) - fMouse_X = headpose[Mouse_X-1] / (Mouse_X < 3 ? 100 : 180); - - if (Mouse_Y > 0 && Mouse_Y <= 6) - fMouse_Y = headpose[Mouse_Y-1] / (Mouse_Y < 3 ? 100 : 180); - - RECT desktop; - const HWND hDesktop = GetDesktopWindow(); - if (hDesktop != NULL && GetWindowRect(hDesktop, &desktop)) { - fMouse_X *= desktop.right; - fMouse_Y *= desktop.bottom; - SetCursorPos(fMouse_X + desktop.right/2, fMouse_Y + desktop.bottom/2); - } -} - -// -// Returns 'true' if all seems OK. -// -bool FTNoIR_Protocol::checkServerInstallationOK() -{ - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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-2011 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 . * +* * +* FTNoIR_Protocol_Mouse The Class, that communicates headpose-data by * +* generating Mouse commands. * +* Many games (like FPS's) support Mouse-look features, * +* but no face-tracking. * +********************************************************************************/ +#include "ftnoir_protocol_mouse.h" +#include "facetracknoir/global-settings.h" + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() +{ + loadSettings(); +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { + 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 ( "Mouse" ); + Mouse_X = (FTN_AngleName) (iniFile.value ( "Mouse_X", 0 ).toInt()); + Mouse_Y = (FTN_AngleName) (iniFile.value ( "Mouse_Y", 0 ).toInt()); + iniFile.endGroup (); +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame(double *headpose, double *rawheadpose ) { + float fMouse_X = 0; + float fMouse_Y = 0; + + if (Mouse_X > 0 && Mouse_X <= 6) + fMouse_X = headpose[Mouse_X-1] / (Mouse_X < 3 ? 100 : 180); + + if (Mouse_Y > 0 && Mouse_Y <= 6) + fMouse_Y = headpose[Mouse_Y-1] / (Mouse_Y < 3 ? 100 : 180); + + RECT desktop; + const HWND hDesktop = GetDesktopWindow(); + if (hDesktop != NULL && GetWindowRect(hDesktop, &desktop)) { + fMouse_X *= desktop.right; + fMouse_Y *= desktop.bottom; + SetCursorPos(fMouse_X + desktop.right/2, fMouse_Y + desktop.bottom/2); + } +} + +// +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol::checkServerInstallationOK() +{ + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Protocol; +} diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h index fd0058ea..b537fc4e 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.h @@ -1,128 +1,128 @@ -/******************************************************************************** -* 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-2011 Wim Vriend (Developing) * -* Ron Hendriks (Researching and Testing) * -* * -* 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 . * -* * -* FTNoIR_Protocol_Mouse The Class, that communicates headpose-data by * -* generating Mouse commands. * -* Many games (like FPS's) support Mouse-look features, * -* but no face-tracking. * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_MOUSESERVER_H -#define INCLUDED_MOUSESERVER_H - -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ui_ftnoir_mousecontrols.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "facetracknoir/global-settings.h" - -#define MOUSE_AXIS_MIN 0 -#define MOUSE_AXIS_MAX 65535 - -enum FTN_AngleName { - FTN_YAW = Yaw, - FTN_PITCH = Pitch, - FTN_ROLL = Roll, - FTN_X = TX, - FTN_Y = TY, - FTN_Z = TZ -}; - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK(); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); - -private: - HANDLE h; - INPUT MouseStruct; - - FTN_AngleName Mouse_X; // Map one of the 6DOF's to this Mouse direction - FTN_AngleName Mouse_Y; - FTN_AngleName Mouse_Wheel; - void loadSettings(); - QString getGameName() { - return "Mouse tracker"; - } -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class MOUSEControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit MOUSEControls(); - virtual ~MOUSEControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) { - theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol - } - void unRegisterProtocol() { - theProtocol = NULL; // Reset the pointer - } - -private: - Ui::UICMOUSEControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FTNoIR_Protocol *theProtocol; - -private slots: - void doOK(); - void doCancel(); - void settingChanged( int setting ) { settingsDirty = true; } -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look"); } - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look"); } - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look protocol"); } - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/mouse.png"); } -}; - - -#endif//INCLUDED_MOUSESERVER_H -//END +/******************************************************************************** +* 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-2011 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* 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 . * +* * +* FTNoIR_Protocol_Mouse The Class, that communicates headpose-data by * +* generating Mouse commands. * +* Many games (like FPS's) support Mouse-look features, * +* but no face-tracking. * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_MOUSESERVER_H +#define INCLUDED_MOUSESERVER_H + +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ui_ftnoir_mousecontrols.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "facetracknoir/global-settings.h" + +#define MOUSE_AXIS_MIN 0 +#define MOUSE_AXIS_MAX 65535 + +enum FTN_AngleName { + FTN_YAW = Yaw, + FTN_PITCH = Pitch, + FTN_ROLL = Roll, + FTN_X = TX, + FTN_Y = TY, + FTN_Z = TZ +}; + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK(); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); + +private: + HANDLE h; + INPUT MouseStruct; + + FTN_AngleName Mouse_X; // Map one of the 6DOF's to this Mouse direction + FTN_AngleName Mouse_Y; + FTN_AngleName Mouse_Wheel; + void loadSettings(); + QString getGameName() { + return "Mouse tracker"; + } +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class MOUSEControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit MOUSEControls(); + virtual ~MOUSEControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) { + theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol + } + void unRegisterProtocol() { + theProtocol = NULL; // Reset the pointer + } + +private: + Ui::UICMOUSEControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FTNoIR_Protocol *theProtocol; + +private slots: + void doOK(); + void doCancel(); + void settingChanged( int setting ) { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look"); } + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look"); } + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Mouse Look protocol"); } + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/mouse.png"); } +}; + + +#endif//INCLUDED_MOUSESERVER_H +//END diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp index c2f68bd2..1e03a022 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp @@ -1,181 +1,181 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_mouse.h" -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -MOUSEControls::MOUSEControls() : -QWidget() -{ - ui.setupUi( this ); - ui.cbxSelectMouse_X->addItem("None"); - ui.cbxSelectMouse_X->addItem("X"); - ui.cbxSelectMouse_X->addItem("Y"); - ui.cbxSelectMouse_X->addItem("Z"); - ui.cbxSelectMouse_X->addItem("Yaw"); - ui.cbxSelectMouse_X->addItem("Pitch"); - ui.cbxSelectMouse_X->addItem("Roll"); - - ui.cbxSelectMouse_Y->addItem("None"); - ui.cbxSelectMouse_Y->addItem("X"); - ui.cbxSelectMouse_Y->addItem("Y"); - ui.cbxSelectMouse_Y->addItem("Z"); - ui.cbxSelectMouse_Y->addItem("Yaw"); - ui.cbxSelectMouse_Y->addItem("Pitch"); - ui.cbxSelectMouse_Y->addItem("Roll"); - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.cbxSelectMouse_X, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); - connect(ui.cbxSelectMouse_Y, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); - theProtocol = NULL; - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -MOUSEControls::~MOUSEControls() { - qDebug() << "~MOUSEControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void MOUSEControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void MOUSEControls::doOK() { - save(); - this->close(); -} - -// override show event -void MOUSEControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void MOUSEControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void MOUSEControls::loadSettings() { - qDebug() << "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) - - qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "Mouse" ); - ui.cbxSelectMouse_X->setCurrentIndex(iniFile.value ( "Mouse_X", 0 ).toInt() ); - ui.cbxSelectMouse_Y->setCurrentIndex(iniFile.value ( "Mouse_Y", 0 ).toInt() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void MOUSEControls::save() { - qDebug() << "save() says: started"; - - 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 ( "Mouse" ); - iniFile.setValue ( "Mouse_X", ui.cbxSelectMouse_X->currentIndex() ); - iniFile.setValue ( "Mouse_Y", ui.cbxSelectMouse_Y->currentIndex() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) -{ - return new MOUSEControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_mouse.h" +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +MOUSEControls::MOUSEControls() : +QWidget() +{ + ui.setupUi( this ); + ui.cbxSelectMouse_X->addItem("None"); + ui.cbxSelectMouse_X->addItem("X"); + ui.cbxSelectMouse_X->addItem("Y"); + ui.cbxSelectMouse_X->addItem("Z"); + ui.cbxSelectMouse_X->addItem("Yaw"); + ui.cbxSelectMouse_X->addItem("Pitch"); + ui.cbxSelectMouse_X->addItem("Roll"); + + ui.cbxSelectMouse_Y->addItem("None"); + ui.cbxSelectMouse_Y->addItem("X"); + ui.cbxSelectMouse_Y->addItem("Y"); + ui.cbxSelectMouse_Y->addItem("Z"); + ui.cbxSelectMouse_Y->addItem("Yaw"); + ui.cbxSelectMouse_Y->addItem("Pitch"); + ui.cbxSelectMouse_Y->addItem("Roll"); + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.cbxSelectMouse_X, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); + connect(ui.cbxSelectMouse_Y, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); + theProtocol = NULL; + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +MOUSEControls::~MOUSEControls() { + qDebug() << "~MOUSEControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void MOUSEControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void MOUSEControls::doOK() { + save(); + this->close(); +} + +// override show event +void MOUSEControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void MOUSEControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void MOUSEControls::loadSettings() { + qDebug() << "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) + + qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "Mouse" ); + ui.cbxSelectMouse_X->setCurrentIndex(iniFile.value ( "Mouse_X", 0 ).toInt() ); + ui.cbxSelectMouse_Y->setCurrentIndex(iniFile.value ( "Mouse_Y", 0 ).toInt() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void MOUSEControls::save() { + qDebug() << "save() says: started"; + + 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 ( "Mouse" ); + iniFile.setValue ( "Mouse_X", ui.cbxSelectMouse_X->currentIndex() ); + iniFile.setValue ( "Mouse_Y", ui.cbxSelectMouse_Y->currentIndex() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 f2250735..d142934d 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_mouse.h" -#include -#include "facetracknoir/global-settings.h" - -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() -{ - return new FTNoIR_ProtocolDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_mouse.h" +#include +#include "facetracknoir/global-settings.h" + +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() +{ + return new FTNoIR_ProtocolDll; +} diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp index cae11816..ca07fbf6 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.cpp @@ -1,356 +1,356 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* FTNoIR_Protocol: the Class, that communicates headpose-data * -* to games, using the SimConnect.dll. * -* SimConnect.dll is a so called 'side-by-side' assembly, so it * -* must be treated as such... * -********************************************************************************/ -#include "ftnoir_protocol_sc.h" -#include "facetracknoir/global-settings.h" - -importSimConnect_CameraSetRelative6DOF FTNoIR_Protocol::simconnect_set6DOF; -HANDLE FTNoIR_Protocol::hSimConnect = 0; // Handle to SimConnect - -float FTNoIR_Protocol::virtSCPosX = 0.0f; // Headpose -float FTNoIR_Protocol::virtSCPosY = 0.0f; -float FTNoIR_Protocol::virtSCPosZ = 0.0f; - -float FTNoIR_Protocol::virtSCRotX = 0.0f; -float FTNoIR_Protocol::virtSCRotY = 0.0f; -float FTNoIR_Protocol::virtSCRotZ = 0.0f; - -float FTNoIR_Protocol::prevSCPosX = 0.0f; // previous Headpose -float FTNoIR_Protocol::prevSCPosY = 0.0f; -float FTNoIR_Protocol::prevSCPosZ = 0.0f; - -float FTNoIR_Protocol::prevSCRotX = 0.0f; -float FTNoIR_Protocol::prevSCRotY = 0.0f; -float FTNoIR_Protocol::prevSCRotZ = 0.0f; - -static QLibrary SCClientLib; - -/** constructor **/ -FTNoIR_Protocol::FTNoIR_Protocol() -{ - ProgramName = "Microsoft FSX"; - blnSimConnectActive = false; - hSimConnect = 0; -} - -/** destructor **/ -FTNoIR_Protocol::~FTNoIR_Protocol() -{ - qDebug() << "~FTNoIR_Protocol says: inside" << FTNoIR_Protocol::hSimConnect; - - if (hSimConnect != 0) { - qDebug() << "~FTNoIR_Protocol says: before simconnect_close"; - if (SUCCEEDED( simconnect_close( FTNoIR_Protocol::hSimConnect ) ) ) { - qDebug() << "~FTNoIR_Protocol says: close SUCCEEDED"; - } - } -// SCClientLib.unload(); Generates crash when tracker is ended... -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void FTNoIR_Protocol::loadSettings() { -// None yet... -} - -// -// Update Headpose in Game. -// -void FTNoIR_Protocol::sendHeadposeToGame( double *headpose, double *rawheadpose ) { -PDWORD_PTR MsgResult = 0; - - - virtSCRotX = -headpose[Pitch]; // degrees - virtSCRotY = -headpose[Yaw]; - virtSCRotZ = headpose[Roll]; - - virtSCPosX = headpose[TX]/100.f; // cm to meters - virtSCPosY = headpose[TY]/100.f; - virtSCPosZ = -headpose[TZ]/100.f; - - // - // It's only useful to send data, if the connection was made. - // - if (!blnSimConnectActive) { - if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) { - qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: SimConnect active!"; - - //set up the events we want to listen for - 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); - ////hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "VK_COMMA", EVENT_INIT); - ////hr = SimConnect_SetInputGroupState(hSimConnect, INPUT0, SIMCONNECT_STATE_ON); - - blnSimConnectActive = true; - } - } - else { - // - // Write the 6DOF-data to FSX -// // -// // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. -// // -// if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || -// (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { -//// if (S_OK == simconnect_set6DOF(hSimConnect, virtPosX, virtPosY, virtPosZ, virtRotX, virtRotZ, virtRotY)) { -//// qDebug() << "FTNoIR_Protocol::run() says: SimConnect data written!"; -//// } -// } -// -// prevPosX = virtPosX; -// prevPosY = virtPosY; -// prevPosZ = virtPosZ; -// prevRotX = virtRotX; -// prevRotY = virtRotY; -// prevRotZ = virtRotZ; - - if (SUCCEEDED(simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, NULL))) { - qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: Dispatching"; - } - else { - qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: Error Dispatching!"; - } - } -} - -class ActivationContext { -public: - ActivationContext(const int resid) { - hactctx = INVALID_HANDLE_VALUE; - actctx_cookie = NULL; - ACTCTXA actx = {0}; - actx.cbSize = sizeof(ACTCTXA); - actx.lpResourceName = MAKEINTRESOURCEA(resid); - actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; - QString path = QCoreApplication::applicationDirPath() + "/opentrack-proto-simconnect.dll"; - QByteArray name = QFile::encodeName(path); - actx.lpSource = name.constData(); - hactctx = CreateActCtxA(&actx); - actctx_cookie = 0; - if (hactctx != INVALID_HANDLE_VALUE) { - if (!ActivateActCtx(hactctx, &actctx_cookie)) { - qDebug() << "SC: can't set win32 activation context" << GetLastError(); - ReleaseActCtx(hactctx); - hactctx = INVALID_HANDLE_VALUE; - } - } else { - qDebug() << "SC: can't create win32 activation context"; - } - } - ~ActivationContext() { - if (hactctx != INVALID_HANDLE_VALUE) - { - DeactivateActCtx(0, actctx_cookie); - ReleaseActCtx(hactctx); - } - } -private: - ULONG_PTR actctx_cookie; - HANDLE hactctx; -}; - -// -// Returns 'true' if all seems OK. -// -bool FTNoIR_Protocol::checkServerInstallationOK() -{ - if (!SCClientLib.isLoaded()) - { - qDebug() << "SCCheckClientDLL says: Starting Function"; - - SCClientLib.setFileName("SimConnect.DLL"); - - ActivationContext ctx(142); - - if (!SCClientLib.load()) { - qDebug() << "SC load" << SCClientLib.errorString(); - return false; - } - } else { - qDebug() << "SimConnect already loaded"; - } - - // - // Get the functions from the DLL. - // - simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); - if (simconnect_open == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_Open function not found in DLL!"; - return false; - } - simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); - if (simconnect_set6DOF == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; - return false; - } - simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); - if (simconnect_close == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_Close function not found in DLL!"; - return false; - } - - //return true; - - simconnect_calldispatch = (importSimConnect_CallDispatch) SCClientLib.resolve("SimConnect_CallDispatch"); - if (simconnect_calldispatch == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_CallDispatch function not found in DLL!"; - return false; - } - - simconnect_subscribetosystemevent = (importSimConnect_SubscribeToSystemEvent) SCClientLib.resolve("SimConnect_SubscribeToSystemEvent"); - if (simconnect_subscribetosystemevent == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_SubscribeToSystemEvent function not found in DLL!"; - return false; - } - - simconnect_mapclienteventtosimevent = (importSimConnect_MapClientEventToSimEvent) SCClientLib.resolve("SimConnect_MapClientEventToSimEvent"); - if (simconnect_subscribetosystemevent == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_MapClientEventToSimEvent function not found in DLL!"; - return false; - } - - simconnect_addclienteventtonotificationgroup = (importSimConnect_AddClientEventToNotificationGroup) SCClientLib.resolve("SimConnect_AddClientEventToNotificationGroup"); - if (simconnect_subscribetosystemevent == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_AddClientEventToNotificationGroup function not found in DLL!"; - return false; - } - - simconnect_setnotificationgrouppriority = (importSimConnect_SetNotificationGroupPriority) SCClientLib.resolve("SimConnect_SetNotificationGroupPriority"); - if (simconnect_subscribetosystemevent == NULL) { - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_SetNotificationGroupPriority function not found in DLL!"; - return false; - } - - qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect functions resolved in DLL!"; - - return true; -} - -void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) -{ -// HRESULT hr; - - switch(pData->dwID) - { - case SIMCONNECT_RECV_ID_EVENT: - { - SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData; - - qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: SimConnect active!"; - //switch(evt->uEventID) - //{ - // //case EVENT_CAMERA_RIGHT: - - // // cameraBank = normalize180( cameraBank + 5.0f); - - // // hr = SimConnect_CameraSetRelative6DOF(hSimConnect, 0.0f, 0.0f, 0.0f, - // // SIMCONNECT_CAMERA_IGNORE_FIELD,SIMCONNECT_CAMERA_IGNORE_FIELD, cameraBank); - - // // printf("\nCamera Bank = %f", cameraBank); - // // break; - - // //case EVENT_CAMERA_LEFT: - // // - // // cameraBank = normalize180( cameraBank - 5.0f); - - // // hr = SimConnect_CameraSetRelative6DOF(hSimConnect, 0.0f, 0.0f, 0.0f, - // // SIMCONNECT_CAMERA_IGNORE_FIELD,SIMCONNECT_CAMERA_IGNORE_FIELD, cameraBank); - // // - // // printf("\nCamera Bank = %f", cameraBank); - // // break; - - // //default: - // // break; - //} - //break; - } - case SIMCONNECT_RECV_ID_EVENT_FRAME: - { -// qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: Frame event!"; - if ((prevSCPosX != virtSCPosX) || (prevSCPosY != virtSCPosY) || (prevSCPosZ != virtSCPosZ) || - (prevSCRotX != virtSCRotX) || (prevSCRotY != virtSCRotY) || (prevSCRotZ != virtSCRotZ)) { - if (S_OK == simconnect_set6DOF(hSimConnect, virtSCPosX, virtSCPosY, virtSCPosZ, virtSCRotX, virtSCRotZ, virtSCRotY)) { - // qDebug() << "FTNoIR_Protocol::run() says: SimConnect data written!"; - } - } - prevSCPosX = virtSCPosX; - prevSCPosY = virtSCPosY; - prevSCPosZ = virtSCPosZ; - prevSCRotX = virtSCRotX; - prevSCRotY = virtSCRotY; - prevSCRotZ = virtSCRotZ; - } - - case SIMCONNECT_RECV_ID_EXCEPTION: - { - SIMCONNECT_RECV_EXCEPTION *except = (SIMCONNECT_RECV_EXCEPTION*)pData; - - switch (except->dwException) - { - case SIMCONNECT_EXCEPTION_ERROR: - printf("\nCamera error"); - break; - - default: - printf("\nException"); - break; - } - break; - } - - case SIMCONNECT_RECV_ID_QUIT: - { - qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: Quit event!"; -// quit = 1; - break; - } - - default: - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// 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 IProtocol* CALLING_CONVENTION GetConstructor() -{ - return new FTNoIR_Protocol; -} +/******************************************************************************** +* 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-2011 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 . * +* * +* FTNoIR_Protocol: the Class, that communicates headpose-data * +* to games, using the SimConnect.dll. * +* SimConnect.dll is a so called 'side-by-side' assembly, so it * +* must be treated as such... * +********************************************************************************/ +#include "ftnoir_protocol_sc.h" +#include "facetracknoir/global-settings.h" + +importSimConnect_CameraSetRelative6DOF FTNoIR_Protocol::simconnect_set6DOF; +HANDLE FTNoIR_Protocol::hSimConnect = 0; // Handle to SimConnect + +float FTNoIR_Protocol::virtSCPosX = 0.0f; // Headpose +float FTNoIR_Protocol::virtSCPosY = 0.0f; +float FTNoIR_Protocol::virtSCPosZ = 0.0f; + +float FTNoIR_Protocol::virtSCRotX = 0.0f; +float FTNoIR_Protocol::virtSCRotY = 0.0f; +float FTNoIR_Protocol::virtSCRotZ = 0.0f; + +float FTNoIR_Protocol::prevSCPosX = 0.0f; // previous Headpose +float FTNoIR_Protocol::prevSCPosY = 0.0f; +float FTNoIR_Protocol::prevSCPosZ = 0.0f; + +float FTNoIR_Protocol::prevSCRotX = 0.0f; +float FTNoIR_Protocol::prevSCRotY = 0.0f; +float FTNoIR_Protocol::prevSCRotZ = 0.0f; + +static QLibrary SCClientLib; + +/** constructor **/ +FTNoIR_Protocol::FTNoIR_Protocol() +{ + ProgramName = "Microsoft FSX"; + blnSimConnectActive = false; + hSimConnect = 0; +} + +/** destructor **/ +FTNoIR_Protocol::~FTNoIR_Protocol() +{ + qDebug() << "~FTNoIR_Protocol says: inside" << FTNoIR_Protocol::hSimConnect; + + if (hSimConnect != 0) { + qDebug() << "~FTNoIR_Protocol says: before simconnect_close"; + if (SUCCEEDED( simconnect_close( FTNoIR_Protocol::hSimConnect ) ) ) { + qDebug() << "~FTNoIR_Protocol says: close SUCCEEDED"; + } + } +// SCClientLib.unload(); Generates crash when tracker is ended... +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void FTNoIR_Protocol::loadSettings() { +// None yet... +} + +// +// Update Headpose in Game. +// +void FTNoIR_Protocol::sendHeadposeToGame( double *headpose, double *rawheadpose ) { +PDWORD_PTR MsgResult = 0; + + + virtSCRotX = -headpose[Pitch]; // degrees + virtSCRotY = -headpose[Yaw]; + virtSCRotZ = headpose[Roll]; + + virtSCPosX = headpose[TX]/100.f; // cm to meters + virtSCPosY = headpose[TY]/100.f; + virtSCPosZ = -headpose[TZ]/100.f; + + // + // It's only useful to send data, if the connection was made. + // + if (!blnSimConnectActive) { + if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) { + qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: SimConnect active!"; + + //set up the events we want to listen for + 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); + ////hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "VK_COMMA", EVENT_INIT); + ////hr = SimConnect_SetInputGroupState(hSimConnect, INPUT0, SIMCONNECT_STATE_ON); + + blnSimConnectActive = true; + } + } + else { + // + // Write the 6DOF-data to FSX +// // +// // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. +// // +// if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || +// (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { +//// if (S_OK == simconnect_set6DOF(hSimConnect, virtPosX, virtPosY, virtPosZ, virtRotX, virtRotZ, virtRotY)) { +//// qDebug() << "FTNoIR_Protocol::run() says: SimConnect data written!"; +//// } +// } +// +// prevPosX = virtPosX; +// prevPosY = virtPosY; +// prevPosZ = virtPosZ; +// prevRotX = virtRotX; +// prevRotY = virtRotY; +// prevRotZ = virtRotZ; + + if (SUCCEEDED(simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, NULL))) { + qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: Dispatching"; + } + else { + qDebug() << "FTNoIR_Protocol::sendHeadposeToGame() says: Error Dispatching!"; + } + } +} + +class ActivationContext { +public: + ActivationContext(const int resid) { + hactctx = INVALID_HANDLE_VALUE; + actctx_cookie = NULL; + ACTCTXA actx = {0}; + actx.cbSize = sizeof(ACTCTXA); + actx.lpResourceName = MAKEINTRESOURCEA(resid); + actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; + QString path = QCoreApplication::applicationDirPath() + "/opentrack-proto-simconnect.dll"; + QByteArray name = QFile::encodeName(path); + actx.lpSource = name.constData(); + hactctx = CreateActCtxA(&actx); + actctx_cookie = 0; + if (hactctx != INVALID_HANDLE_VALUE) { + if (!ActivateActCtx(hactctx, &actctx_cookie)) { + qDebug() << "SC: can't set win32 activation context" << GetLastError(); + ReleaseActCtx(hactctx); + hactctx = INVALID_HANDLE_VALUE; + } + } else { + qDebug() << "SC: can't create win32 activation context"; + } + } + ~ActivationContext() { + if (hactctx != INVALID_HANDLE_VALUE) + { + DeactivateActCtx(0, actctx_cookie); + ReleaseActCtx(hactctx); + } + } +private: + ULONG_PTR actctx_cookie; + HANDLE hactctx; +}; + +// +// Returns 'true' if all seems OK. +// +bool FTNoIR_Protocol::checkServerInstallationOK() +{ + if (!SCClientLib.isLoaded()) + { + qDebug() << "SCCheckClientDLL says: Starting Function"; + + SCClientLib.setFileName("SimConnect.DLL"); + + ActivationContext ctx(142); + + if (!SCClientLib.load()) { + qDebug() << "SC load" << SCClientLib.errorString(); + return false; + } + } else { + qDebug() << "SimConnect already loaded"; + } + + // + // Get the functions from the DLL. + // + simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); + if (simconnect_open == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_Open function not found in DLL!"; + return false; + } + simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); + if (simconnect_set6DOF == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; + return false; + } + simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); + if (simconnect_close == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_Close function not found in DLL!"; + return false; + } + + //return true; + + simconnect_calldispatch = (importSimConnect_CallDispatch) SCClientLib.resolve("SimConnect_CallDispatch"); + if (simconnect_calldispatch == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_CallDispatch function not found in DLL!"; + return false; + } + + simconnect_subscribetosystemevent = (importSimConnect_SubscribeToSystemEvent) SCClientLib.resolve("SimConnect_SubscribeToSystemEvent"); + if (simconnect_subscribetosystemevent == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_SubscribeToSystemEvent function not found in DLL!"; + return false; + } + + simconnect_mapclienteventtosimevent = (importSimConnect_MapClientEventToSimEvent) SCClientLib.resolve("SimConnect_MapClientEventToSimEvent"); + if (simconnect_subscribetosystemevent == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_MapClientEventToSimEvent function not found in DLL!"; + return false; + } + + simconnect_addclienteventtonotificationgroup = (importSimConnect_AddClientEventToNotificationGroup) SCClientLib.resolve("SimConnect_AddClientEventToNotificationGroup"); + if (simconnect_subscribetosystemevent == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_AddClientEventToNotificationGroup function not found in DLL!"; + return false; + } + + simconnect_setnotificationgrouppriority = (importSimConnect_SetNotificationGroupPriority) SCClientLib.resolve("SimConnect_SetNotificationGroupPriority"); + if (simconnect_subscribetosystemevent == NULL) { + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect_SetNotificationGroupPriority function not found in DLL!"; + return false; + } + + qDebug() << "FTNoIR_Protocol::checkServerInstallationOK() says: SimConnect functions resolved in DLL!"; + + return true; +} + +void CALLBACK FTNoIR_Protocol::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) +{ +// HRESULT hr; + + switch(pData->dwID) + { + case SIMCONNECT_RECV_ID_EVENT: + { + SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData; + + qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: SimConnect active!"; + //switch(evt->uEventID) + //{ + // //case EVENT_CAMERA_RIGHT: + + // // cameraBank = normalize180( cameraBank + 5.0f); + + // // hr = SimConnect_CameraSetRelative6DOF(hSimConnect, 0.0f, 0.0f, 0.0f, + // // SIMCONNECT_CAMERA_IGNORE_FIELD,SIMCONNECT_CAMERA_IGNORE_FIELD, cameraBank); + + // // printf("\nCamera Bank = %f", cameraBank); + // // break; + + // //case EVENT_CAMERA_LEFT: + // // + // // cameraBank = normalize180( cameraBank - 5.0f); + + // // hr = SimConnect_CameraSetRelative6DOF(hSimConnect, 0.0f, 0.0f, 0.0f, + // // SIMCONNECT_CAMERA_IGNORE_FIELD,SIMCONNECT_CAMERA_IGNORE_FIELD, cameraBank); + // // + // // printf("\nCamera Bank = %f", cameraBank); + // // break; + + // //default: + // // break; + //} + //break; + } + case SIMCONNECT_RECV_ID_EVENT_FRAME: + { +// qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: Frame event!"; + if ((prevSCPosX != virtSCPosX) || (prevSCPosY != virtSCPosY) || (prevSCPosZ != virtSCPosZ) || + (prevSCRotX != virtSCRotX) || (prevSCRotY != virtSCRotY) || (prevSCRotZ != virtSCRotZ)) { + if (S_OK == simconnect_set6DOF(hSimConnect, virtSCPosX, virtSCPosY, virtSCPosZ, virtSCRotX, virtSCRotZ, virtSCRotY)) { + // qDebug() << "FTNoIR_Protocol::run() says: SimConnect data written!"; + } + } + prevSCPosX = virtSCPosX; + prevSCPosY = virtSCPosY; + prevSCPosZ = virtSCPosZ; + prevSCRotX = virtSCRotX; + prevSCRotY = virtSCRotY; + prevSCRotZ = virtSCRotZ; + } + + case SIMCONNECT_RECV_ID_EXCEPTION: + { + SIMCONNECT_RECV_EXCEPTION *except = (SIMCONNECT_RECV_EXCEPTION*)pData; + + switch (except->dwException) + { + case SIMCONNECT_EXCEPTION_ERROR: + printf("\nCamera error"); + break; + + default: + printf("\nException"); + break; + } + break; + } + + case SIMCONNECT_RECV_ID_QUIT: + { + qDebug() << "FTNoIR_Protocol::processNextSimconnectEvent() says: Quit event!"; +// quit = 1; + break; + } + + default: + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 IProtocol* CALLING_CONVENTION GetConstructor() +{ + return new FTNoIR_Protocol; +} diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc.h b/ftnoir_protocol_sc/ftnoir_protocol_sc.h index c22c36c7..b3596722 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc.h +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc.h @@ -1,176 +1,176 @@ -/******************************************************************************** -* 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-2011 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 . * -* * -* SCServer SCServer is the Class, that communicates headpose-data * -* to games, using the SimConnect.dll. * -* SimConnect.dll is a so called 'side-by-side' assembly, so it * -* must be treated as such... * -********************************************************************************/ -#pragma once -#ifndef INCLUDED_SCSERVER_H -#define INCLUDED_SCSERVER_H -#include "facetracknoir/global-settings.h" -// -// Prevent the SimConnect manifest from being merged in the application-manifest -// This is necessary to run FaceTrackNoIR on a PC without FSX -// -#define SIMCONNECT_H_NOMANIFEST -#define _WIN32_WINNT 0x0502 - -#include -#include - -#include <..\ftnoir_protocol_base\ftnoir_protocol_base.h> -#include -#include -#include -#include -#include -#include -#include -//#include "math.h" - -typedef HRESULT (WINAPI *importSimConnect_Open)(HANDLE * phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex); -typedef HRESULT (WINAPI *importSimConnect_Close)(HANDLE hSimConnect); -typedef HRESULT (WINAPI *importSimConnect_CameraSetRelative6DOF)(HANDLE hSimConnect, float fDeltaX, float fDeltaY, float fDeltaZ, float fPitchDeg, float fBankDeg, float fHeadingDeg); -typedef HRESULT (WINAPI *importSimConnect_CallDispatch)(HANDLE hSimConnect, DispatchProc pfcnDispatch, void * pContext); -typedef HRESULT (WINAPI *importSimConnect_SubscribeToSystemEvent)(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * SystemEventName); -typedef HRESULT (WINAPI *importSimConnect_MapClientEventToSimEvent)(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * EventName); -typedef HRESULT (WINAPI *importSimConnect_AddClientEventToNotificationGroup)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_CLIENT_EVENT_ID EventID, BOOL bMaskable); -typedef HRESULT (WINAPI *importSimConnect_SetNotificationGroupPriority)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, DWORD uPriority); - -#define SC_CLIENT_FILENAME "SimConnect.dll" - -enum GROUP_ID -{ - GROUP0=0, -}; - -enum EVENT_ID -{ - EVENT_PING=0, - EVENT_INIT, -}; - -enum INPUT_ID -{ - INPUT0=0, -}; - -class FTNoIR_Protocol : public IProtocol -{ -public: - FTNoIR_Protocol(); - ~FTNoIR_Protocol(); - bool checkServerInstallationOK(); - void sendHeadposeToGame( double *headpose, double *rawheadpose ); - QString getGameName() { - return "FS2004/FSX"; - } - -private: - // Private properties - QString ProgramName; - - static float virtSCPosX; - static float virtSCPosY; - static float virtSCPosZ; - - static float virtSCRotX; - static float virtSCRotY; - static float virtSCRotZ; - - static float prevSCPosX; - static float prevSCPosY; - static float prevSCPosZ; - - static float prevSCRotX; - static float prevSCRotY; - static float prevSCRotZ; - - bool blnSimConnectActive; - - importSimConnect_Open simconnect_open; // SimConnect function(s) in DLL - importSimConnect_Close simconnect_close; - static importSimConnect_CameraSetRelative6DOF simconnect_set6DOF; - importSimConnect_CallDispatch simconnect_calldispatch; - importSimConnect_SubscribeToSystemEvent simconnect_subscribetosystemevent; - importSimConnect_MapClientEventToSimEvent simconnect_mapclienteventtosimevent; - importSimConnect_AddClientEventToNotificationGroup simconnect_addclienteventtonotificationgroup; - importSimConnect_SetNotificationGroupPriority simconnect_setnotificationgrouppriority; - - static HANDLE hSimConnect; // Handle to SimConnect - static void CALLBACK processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext); - void loadSettings(); -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class SCControls: public QWidget, public IProtocolDialog -{ - Q_OBJECT -public: - - explicit SCControls(); - virtual ~SCControls(); - void showEvent ( QShowEvent * event ); - void Initialize(QWidget *parent); - void registerProtocol(IProtocol *protocol) { - theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol - } - void unRegisterProtocol() { - theProtocol = NULL; // Reset the pointer - } - -private: - Ui::UICSCControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - FTNoIR_Protocol *theProtocol; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; }; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol -//******************************************************************************************************* -class FTNoIR_ProtocolDll : public Metadata -{ -public: - FTNoIR_ProtocolDll(); - ~FTNoIR_ProtocolDll(); - - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FSX SimConnect"); }; - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("SimConnect"); }; - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft SimConnect protocol"); }; - - void getIcon(QIcon *icon) { *icon = QIcon(":/images/fsx.png"); }; -}; - -#endif//INCLUDED_SCSERVER_H -//END +/******************************************************************************** +* 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-2011 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 . * +* * +* SCServer SCServer is the Class, that communicates headpose-data * +* to games, using the SimConnect.dll. * +* SimConnect.dll is a so called 'side-by-side' assembly, so it * +* must be treated as such... * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_SCSERVER_H +#define INCLUDED_SCSERVER_H +#include "facetracknoir/global-settings.h" +// +// Prevent the SimConnect manifest from being merged in the application-manifest +// This is necessary to run FaceTrackNoIR on a PC without FSX +// +#define SIMCONNECT_H_NOMANIFEST +#define _WIN32_WINNT 0x0502 + +#include +#include + +#include <..\ftnoir_protocol_base\ftnoir_protocol_base.h> +#include +#include +#include +#include +#include +#include +#include +//#include "math.h" + +typedef HRESULT (WINAPI *importSimConnect_Open)(HANDLE * phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex); +typedef HRESULT (WINAPI *importSimConnect_Close)(HANDLE hSimConnect); +typedef HRESULT (WINAPI *importSimConnect_CameraSetRelative6DOF)(HANDLE hSimConnect, float fDeltaX, float fDeltaY, float fDeltaZ, float fPitchDeg, float fBankDeg, float fHeadingDeg); +typedef HRESULT (WINAPI *importSimConnect_CallDispatch)(HANDLE hSimConnect, DispatchProc pfcnDispatch, void * pContext); +typedef HRESULT (WINAPI *importSimConnect_SubscribeToSystemEvent)(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * SystemEventName); +typedef HRESULT (WINAPI *importSimConnect_MapClientEventToSimEvent)(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * EventName); +typedef HRESULT (WINAPI *importSimConnect_AddClientEventToNotificationGroup)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_CLIENT_EVENT_ID EventID, BOOL bMaskable); +typedef HRESULT (WINAPI *importSimConnect_SetNotificationGroupPriority)(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, DWORD uPriority); + +#define SC_CLIENT_FILENAME "SimConnect.dll" + +enum GROUP_ID +{ + GROUP0=0, +}; + +enum EVENT_ID +{ + EVENT_PING=0, + EVENT_INIT, +}; + +enum INPUT_ID +{ + INPUT0=0, +}; + +class FTNoIR_Protocol : public IProtocol +{ +public: + FTNoIR_Protocol(); + ~FTNoIR_Protocol(); + bool checkServerInstallationOK(); + void sendHeadposeToGame( double *headpose, double *rawheadpose ); + QString getGameName() { + return "FS2004/FSX"; + } + +private: + // Private properties + QString ProgramName; + + static float virtSCPosX; + static float virtSCPosY; + static float virtSCPosZ; + + static float virtSCRotX; + static float virtSCRotY; + static float virtSCRotZ; + + static float prevSCPosX; + static float prevSCPosY; + static float prevSCPosZ; + + static float prevSCRotX; + static float prevSCRotY; + static float prevSCRotZ; + + bool blnSimConnectActive; + + importSimConnect_Open simconnect_open; // SimConnect function(s) in DLL + importSimConnect_Close simconnect_close; + static importSimConnect_CameraSetRelative6DOF simconnect_set6DOF; + importSimConnect_CallDispatch simconnect_calldispatch; + importSimConnect_SubscribeToSystemEvent simconnect_subscribetosystemevent; + importSimConnect_MapClientEventToSimEvent simconnect_mapclienteventtosimevent; + importSimConnect_AddClientEventToNotificationGroup simconnect_addclienteventtonotificationgroup; + importSimConnect_SetNotificationGroupPriority simconnect_setnotificationgrouppriority; + + static HANDLE hSimConnect; // Handle to SimConnect + static void CALLBACK processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext); + void loadSettings(); +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class SCControls: public QWidget, public IProtocolDialog +{ + Q_OBJECT +public: + + explicit SCControls(); + virtual ~SCControls(); + void showEvent ( QShowEvent * event ); + void Initialize(QWidget *parent); + void registerProtocol(IProtocol *protocol) { + theProtocol = (FTNoIR_Protocol *) protocol; // Accept the pointer to the Protocol + } + void unRegisterProtocol() { + theProtocol = NULL; // Reset the pointer + } + +private: + Ui::UICSCControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + FTNoIR_Protocol *theProtocol; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; }; +}; + +//******************************************************************************************************* +// FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol +//******************************************************************************************************* +class FTNoIR_ProtocolDll : public Metadata +{ +public: + FTNoIR_ProtocolDll(); + ~FTNoIR_ProtocolDll(); + + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FSX SimConnect"); }; + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("SimConnect"); }; + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Microsoft SimConnect protocol"); }; + + void getIcon(QIcon *icon) { *icon = QIcon(":/images/fsx.png"); }; +}; + +#endif//INCLUDED_SCSERVER_H +//END diff --git a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp index 41e990dd..c2ddb72a 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dialog.cpp @@ -1,145 +1,145 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_sc.h" -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -SCControls::SCControls() : -QWidget() -{ - ui.setupUi( this ); - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - //connect(ui.cbxSelectPPJoyNumber, SIGNAL(currentIndexChanged(int)), this, SLOT(virtualJoystickSelected( int ))); - - theProtocol = NULL; - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -SCControls::~SCControls() { - qDebug() << "~SCControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void SCControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void SCControls::doOK() { - save(); - this->close(); -} - -// override show event -void SCControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void SCControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void SCControls::loadSettings() { - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void SCControls::save() { - - settingsDirty = false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Protocol-settings dialog object. - -// Export both decorated and undecorated names. -// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") - -extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION GetDialog( ) -{ - return new SCControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_sc.h" +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +SCControls::SCControls() : +QWidget() +{ + ui.setupUi( this ); + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + //connect(ui.cbxSelectPPJoyNumber, SIGNAL(currentIndexChanged(int)), this, SLOT(virtualJoystickSelected( int ))); + + theProtocol = NULL; + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +SCControls::~SCControls() { + qDebug() << "~SCControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void SCControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void SCControls::doOK() { + save(); + this->close(); +} + +// override show event +void SCControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void SCControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void SCControls::loadSettings() { + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void SCControls::save() { + + settingsDirty = false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Protocol-settings dialog object. + +// Export both decorated and undecorated names. +// GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") + +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialog* CALLING_CONVENTION 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 102c7c57..fce8753a 100644 --- a/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp +++ b/ftnoir_protocol_sc/ftnoir_protocol_sc_dll.cpp @@ -1,49 +1,49 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_protocol_SC.h" -#include -#include "facetracknoir/global-settings.h" - -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() -{ - return new FTNoIR_ProtocolDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_protocol_SC.h" +#include +#include "facetracknoir/global-settings.h" + +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() +{ + return new FTNoIR_ProtocolDll; +} diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h index 7c2ab442..4d968e59 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base.h @@ -1,81 +1,81 @@ -/******************************************************************************** -* 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 . * -* This class implements a tracker-base * -*********************************************************************************/ -/* - Modifications (last one on top): - 20122109 - C14: Replaced Release with virtual destructor - 20120009 - WVR: Removed AutoClosePtr (seemed like it didn't work OK) - 20110415 - WVR: Added overloaded operator - and -= -*/ -#ifndef FTNOIR_TRACKER_BASE_H -#define FTNOIR_TRACKER_BASE_H - -#include "ftnoir_tracker_base_global.h" -#include "ftnoir_tracker_types.h" -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -# define EXTERN_C extern "C" -#else -# define EXTERN_C -#endif // __cplusplus - -//////////////////////////////////////////////////////////////////////////////// -// 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() {} - virtual void StartTracker( QFrame* frame ) = 0; - virtual bool GiveHeadPoseData(double *data) = 0; - - virtual void WaitForExit() = 0; - virtual void NotifyCenter() {} -}; - -typedef ITracker* ITrackerPtr; - -//////////////////////////////////////////////////////////////////////////////// -// 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 Initialize(QWidget *parent) = 0; - virtual void registerTracker(ITracker *tracker) = 0; - virtual void unRegisterTracker() = 0; -}; - -#endif // FTNOIR_TRACKER_BASE_H +/******************************************************************************** +* 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 . * +* This class implements a tracker-base * +*********************************************************************************/ +/* + Modifications (last one on top): + 20122109 - C14: Replaced Release with virtual destructor + 20120009 - WVR: Removed AutoClosePtr (seemed like it didn't work OK) + 20110415 - WVR: Added overloaded operator - and -= +*/ +#ifndef FTNOIR_TRACKER_BASE_H +#define FTNOIR_TRACKER_BASE_H + +#include "ftnoir_tracker_base_global.h" +#include "ftnoir_tracker_types.h" +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif // __cplusplus + +//////////////////////////////////////////////////////////////////////////////// +// 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() {} + virtual void StartTracker( QFrame* frame ) = 0; + virtual bool GiveHeadPoseData(double *data) = 0; + + virtual void WaitForExit() = 0; + virtual void NotifyCenter() {} +}; + +typedef ITracker* ITrackerPtr; + +//////////////////////////////////////////////////////////////////////////////// +// 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 Initialize(QWidget *parent) = 0; + 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 index a449c282..af9899c5 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base_global.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base_global.h @@ -1,12 +1,12 @@ -#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H -#define FTNOIR_TRACKER_BASE_GLOBAL_H - -#include - -#ifdef FTNOIR_TRACKER_BASE_LIB -# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT -#else -# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -#endif - -#endif // FTNOIR_TRACKER_BASE_GLOBAL_H +#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H +#define FTNOIR_TRACKER_BASE_GLOBAL_H + +#include + +#ifdef FTNOIR_TRACKER_BASE_LIB +# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT +#else +# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#endif + +#endif // FTNOIR_TRACKER_BASE_GLOBAL_H diff --git a/ftnoir_tracker_base/ftnoir_tracker_sm_types.h b/ftnoir_tracker_base/ftnoir_tracker_sm_types.h index 1faf893f..526f8cdc 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_sm_types.h +++ b/ftnoir_tracker_base/ftnoir_tracker_sm_types.h @@ -1,36 +1,36 @@ -// -// Definitions for the Shared Memory to send the data to FaceTrackNoIR -// -#define SM_MM_DATA "SM_SharedMem" -#define SM_FACEAPI "SM_FaceAPI" -#define SM_MUTEX "SM_Mutex" - -#include "faceapi/stdafx.h" -#include - -struct TFaceData { - int DataID; - smEngineHeadPoseData new_pose; -}; -typedef TFaceData * PFaceData; - -struct SMMemMap { - int command; // Command from FaceTrackNoIR - int status; // Status from faceAPI - TFaceData data; - HANDLE handle; - int state; - int par_val_int; // Value of parameter, indicated by 'command' - int par_val_float; - int initial_filter_level; // Internal faceAPI Filter level - int handshake; -}; -typedef SMMemMap * PSMMemMap; - -enum FTNoIR_Tracker_Command { - FT_SM_START = 10, - FT_SM_STOP = 20, - FT_SM_SHOW_CAM = 30, - FT_SM_SET_PAR_FILTER = 50, - FT_SM_EXIT = 100 -}; +// +// Definitions for the Shared Memory to send the data to FaceTrackNoIR +// +#define SM_MM_DATA "SM_SharedMem" +#define SM_FACEAPI "SM_FaceAPI" +#define SM_MUTEX "SM_Mutex" + +#include "faceapi/stdafx.h" +#include + +struct TFaceData { + int DataID; + smEngineHeadPoseData new_pose; +}; +typedef TFaceData * PFaceData; + +struct SMMemMap { + int command; // Command from FaceTrackNoIR + int status; // Status from faceAPI + TFaceData data; + HANDLE handle; + int state; + int par_val_int; // Value of parameter, indicated by 'command' + int par_val_float; + int initial_filter_level; // Internal faceAPI Filter level + int handshake; +}; +typedef SMMemMap * PSMMemMap; + +enum FTNoIR_Tracker_Command { + FT_SM_START = 10, + FT_SM_STOP = 20, + FT_SM_SHOW_CAM = 30, + FT_SM_SET_PAR_FILTER = 50, + FT_SM_EXIT = 100 +}; diff --git a/ftnoir_tracker_base/ftnoir_tracker_types.h b/ftnoir_tracker_base/ftnoir_tracker_types.h index 8bf12990..591728a6 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_types.h +++ b/ftnoir_tracker_base/ftnoir_tracker_types.h @@ -1,37 +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 . * -* This class implements a tracker-base * -*********************************************************************************/ -/* - Modifications (last one on top): - 20120924 - C14: Moved T6DOF to separate file (not pulic interface) - 20110415 - WVR: Added overloaded operator - and -= -*/ -#ifndef FTNOIR_TRACKER_TYPES_H -#define FTNOIR_TRACKER_TYPES_H - - -enum Axis { - TX = 0, TY, TZ, Yaw, Pitch, Roll}; - -#endif // FTNOIR_TRACKER_TYPES_H +/******************************************************************************** +* 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 . * +* This class implements a tracker-base * +*********************************************************************************/ +/* + Modifications (last one on top): + 20120924 - C14: Moved T6DOF to separate file (not pulic interface) + 20110415 - WVR: Added overloaded operator - and -= +*/ +#ifndef FTNOIR_TRACKER_TYPES_H +#define FTNOIR_TRACKER_TYPES_H + + +enum Axis { + TX = 0, TY, TZ, Yaw, Pitch, Roll}; + +#endif // FTNOIR_TRACKER_TYPES_H diff --git a/ftnoir_tracker_pt/camera.cpp b/ftnoir_tracker_pt/camera.cpp index fe39b436..46dd20c5 100644 --- a/ftnoir_tracker_pt/camera.cpp +++ b/ftnoir_tracker_pt/camera.cpp @@ -1,213 +1,213 @@ -/* 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 "camera.h" -#include - -using namespace cv; - -// ---------------------------------------------------------------------------- -void Camera::set_index(int index) -{ - if (desired_index != index) - { - desired_index = index; - _set_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(); - } -} - -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; -} - -// ---------------------------------------------------------------------------- -void CVCamera::start() -{ - cap = new VideoCapture(desired_index); -// extract camera info - 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); -} - -void CVCamera::stop() -{ - if (cap) { - cap->release(); - delete cap; - cap = NULL; - } - active = false; -} - -bool CVCamera::_get_frame(Mat* frame) -{ - bool ret = cap->read(*frame); - //if (ret) - // flip(tmp, *frame, 0); - return ret; -} - -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); - } -} - -#if 0 -// ---------------------------------------------------------------------------- -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_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 +/* 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 "camera.h" +#include + +using namespace cv; + +// ---------------------------------------------------------------------------- +void Camera::set_index(int index) +{ + if (desired_index != index) + { + desired_index = index; + _set_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(); + } +} + +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; +} + +// ---------------------------------------------------------------------------- +void CVCamera::start() +{ + cap = new VideoCapture(desired_index); +// extract camera info + 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); +} + +void CVCamera::stop() +{ + if (cap) { + cap->release(); + delete cap; + cap = NULL; + } + active = false; +} + +bool CVCamera::_get_frame(Mat* frame) +{ + bool ret = cap->read(*frame); + //if (ret) + // flip(tmp, *frame, 0); + return ret; +} + +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); + } +} + +#if 0 +// ---------------------------------------------------------------------------- +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_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 diff --git a/ftnoir_tracker_pt/camera.h b/ftnoir_tracker_pt/camera.h index 6fec12da..5f1f56b0 100644 --- a/ftnoir_tracker_pt/camera.h +++ b/ftnoir_tracker_pt/camera.h @@ -1,119 +1,119 @@ -/* 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 -#include -//#include "videoInput/videoInput.h" - -// ---------------------------------------------------------------------------- -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 -class Camera -{ -public: - Camera() : desired_index(0), active_index(-1), active(false), dt_valid(0), dt_mean(0) {} - virtual ~Camera() {} - - // start/stop capturing - virtual void start() = 0; - virtual void stop() = 0; - void restart() { stop(); start(); } - - void set_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 - virtual void _set_index() = 0; - virtual void _set_f() = 0; - virtual void _set_fps() = 0; - virtual void _set_res() = 0; - - int desired_index; - int active_index; - bool active; - float dt_valid; - float dt_mean; - CamInfo cam_info; - CamInfo cam_desired; -}; - - -// ---------------------------------------------------------------------------- -// OpenCV camera - -class CVCamera : public Camera -{ -public: - CVCamera() : cap(NULL) {} - ~CVCamera() { stop(); } - - void start(); - void stop(); - -protected: - bool _get_frame(cv::Mat* frame); - void _set_index(); - void _set_f(); - void _set_fps(); - void _set_res(); - - cv::VideoCapture* cap; -}; - - -// ---------------------------------------------------------------------------- -// videoInput camera -#if 0 -class VICamera : public Camera -{ -public: - VICamera(); - ~VICamera() { stop(); } - - void start(); - void stop(); - -protected: - bool _get_frame(cv::Mat* frame); - void _set_index(); - void _set_f(); - void _set_fps(); - void _set_res(); - - videoInput VI; - cv::Mat new_frame; - unsigned char* frame_buffer; -}; -#endif - -#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 +#include +//#include "videoInput/videoInput.h" + +// ---------------------------------------------------------------------------- +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 +class Camera +{ +public: + Camera() : desired_index(0), active_index(-1), active(false), dt_valid(0), dt_mean(0) {} + virtual ~Camera() {} + + // start/stop capturing + virtual void start() = 0; + virtual void stop() = 0; + void restart() { stop(); start(); } + + void set_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 + virtual void _set_index() = 0; + virtual void _set_f() = 0; + virtual void _set_fps() = 0; + virtual void _set_res() = 0; + + int desired_index; + int active_index; + bool active; + float dt_valid; + float dt_mean; + CamInfo cam_info; + CamInfo cam_desired; +}; + + +// ---------------------------------------------------------------------------- +// OpenCV camera + +class CVCamera : public Camera +{ +public: + CVCamera() : cap(NULL) {} + ~CVCamera() { stop(); } + + void start(); + void stop(); + +protected: + bool _get_frame(cv::Mat* frame); + void _set_index(); + void _set_f(); + void _set_fps(); + void _set_res(); + + cv::VideoCapture* cap; +}; + + +// ---------------------------------------------------------------------------- +// videoInput camera +#if 0 +class VICamera : public Camera +{ +public: + VICamera(); + ~VICamera() { stop(); } + + void start(); + void stop(); + +protected: + bool _get_frame(cv::Mat* frame); + void _set_index(); + void _set_f(); + void _set_fps(); + void _set_res(); + + videoInput VI; + cv::Mat new_frame; + unsigned char* frame_buffer; +}; +#endif + +#endif //CAMERA_H diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp index 99b2f680..48702d19 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp @@ -1,261 +1,261 @@ -/* 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 -#include -#include -#include -#include -#include "facetracknoir/global-settings.h" - -using namespace std; -using namespace cv; - -//#define PT_PERF_LOG //log performance - -//----------------------------------------------------------------------------- -Tracker::Tracker() - : tracking_valid(false), frame_count(0), commands(0), video_widget(NULL), fresh(false) -{ - should_quit = false; - qDebug()<<"Tracker::Tracker"; - TrackerSettings settings; - settings.load_ini(); - apply(settings); -} - -Tracker::~Tracker() -{ - qDebug()<<"Tracker::~Tracker"; - set_command(ABORT); - wait(); - if (video_widget) delete video_widget; -} - -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(); - float dt; - bool new_frame; - forever - { - { - QMutexLocker lock(&mutex); - if (should_quit) - break; - - if (commands & ABORT) break; - if (commands & PAUSE) continue; - commands = 0; - - dt = time.elapsed() / 1000.0; - time.restart(); - - new_frame = camera.get_frame(dt, &frame); - if (new_frame && !frame.empty()) - { - const std::vector& points = point_extractor.extract_points(frame, dt, draw_frame); - tracking_valid = point_tracker.track(points, camera.get_info().f, dt); - frame_count++; - fresh = true; - } -#ifdef PT_PERF_LOG - log_stream<<"dt: "<(new PointModel(settings.M01, settings.M02)); - point_tracker.dynamic_pose_resolution = settings.dyn_pose_res; - sleep_time = settings.sleep_time; - point_tracker.dt_reset = settings.reset_time / 1000.0; - draw_frame = settings.video_widget; - cam_pitch = settings.cam_pitch; - - bEnableRoll = settings.bEnableRoll; - bEnablePitch = settings.bEnablePitch; - bEnableYaw = settings.bEnableYaw; - bEnableX = settings.bEnableX; - bEnableY = settings.bEnableY; - bEnableZ = settings.bEnableZ; - - t_MH = settings.t_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_CH_0 = X_CM_0 * X_MH; -} - -void Tracker::refreshVideo() -{ - if (video_widget && fresh) - { - Mat frame_copy; - std::auto_ptr< vector > points; - { - //QMutexLocker lock(&mutex); - if (!draw_frame || frame.empty()) return; - - // copy the frame and points from the tracker thread - frame_copy = frame.clone(); - points = std::auto_ptr< vector >(new vector(point_extractor.get_points())); - } - //QMutexLocker lck(&mutex); - video_widget->update_image(frame_copy, points); - } -} - -void Tracker::StartTracker(QFrame* videoframe) -{ - const int VIDEO_FRAME_WIDTH = videoframe->width(); - const int VIDEO_FRAME_HEIGHT = videoframe->height(); - TrackerSettings settings; - settings.load_ini(); - apply(settings); - qDebug("Tracker::Initialize"); - // setup video frame - video_widget = new VideoWidget(videoframe); - QHBoxLayout* layout = new QHBoxLayout(); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(video_widget); - if (videoframe->layout()) delete videoframe->layout(); - videoframe->setLayout(layout); - video_widget->resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT); - videoframe->show(); - connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget())); - timer.start(40); - camera.start(); - start(); - reset_command(PAUSE); -} - -void Tracker::paint_widget() { - if (fresh) { - fresh = false; - video_widget->update(); - } -} - -bool Tracker::GiveHeadPoseData(double *data) -{ - const double rad2deg = 180.0/3.14159265; - const double deg2rad = 1.0/rad2deg; - { - QMutexLocker lock(&mutex); - - if (!tracking_valid) return false; - - FrameTrafo X_CM = point_tracker.get_pose(); - FrameTrafo X_MH(Matx33f::eye(), t_MH); - FrameTrafo X_CH = X_CM * X_MH; - - Matx33f R = X_CH.R * X_CH_0.R.t(); - Vec3f t = X_CH.t - X_CH_0.t; - - // correct for camera pitch - Matx33f R_CP( 1, 0, 0, - 0, cos(deg2rad*cam_pitch), sin(deg2rad*cam_pitch), - 0, -sin(deg2rad*cam_pitch), cos(deg2rad*cam_pitch)); - R = R_CP * R * R_CP.t(); - t = R_CP * t; - - // get translation(s) - if (bEnableX) { - data[TX] = t[0] / 10.0; // convert to cm - } - if (bEnableY) { - data[TY] = t[1] / 10.0; - } - if (bEnableZ) { - data[TZ] = t[2] / 10.0; - } - - // translate rotation matrix from opengl (G) to roll-pitch-yaw (R) frame - // -z -> x, y -> z, x -> -y - Matx33f R_RG( 0, 0,-1, - -1, 0, 0, - 0, 1, 0); - R = R_RG * R * R_RG.t(); - - // extract rotation angles - double alpha, beta, gamma; - //beta = atan2( -R(2,0), sqrt(R(0,0)*R(0,0) + R(1,0)*R(1,0)) ); - 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 (bEnableYaw) { - data[Yaw] = rad2deg * alpha; - } - if (bEnablePitch) { - data[Pitch] = rad2deg * beta; - } - if (bEnableRoll) { - data[Roll] = rad2deg * gamma; - } - } - return true; -} - -//----------------------------------------------------------------------------- -//#pragma comment(linker, "/export:GetTracker=_GetTracker@0") - -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() -{ - 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 +#include +#include +#include +#include +#include "facetracknoir/global-settings.h" + +using namespace std; +using namespace cv; + +//#define PT_PERF_LOG //log performance + +//----------------------------------------------------------------------------- +Tracker::Tracker() + : tracking_valid(false), frame_count(0), commands(0), video_widget(NULL), fresh(false) +{ + should_quit = false; + qDebug()<<"Tracker::Tracker"; + TrackerSettings settings; + settings.load_ini(); + apply(settings); +} + +Tracker::~Tracker() +{ + qDebug()<<"Tracker::~Tracker"; + set_command(ABORT); + wait(); + if (video_widget) delete video_widget; +} + +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(); + float dt; + bool new_frame; + forever + { + { + QMutexLocker lock(&mutex); + if (should_quit) + break; + + if (commands & ABORT) break; + if (commands & PAUSE) continue; + commands = 0; + + dt = time.elapsed() / 1000.0; + time.restart(); + + new_frame = camera.get_frame(dt, &frame); + if (new_frame && !frame.empty()) + { + const std::vector& points = point_extractor.extract_points(frame, dt, draw_frame); + tracking_valid = point_tracker.track(points, camera.get_info().f, dt); + frame_count++; + fresh = true; + } +#ifdef PT_PERF_LOG + log_stream<<"dt: "<(new PointModel(settings.M01, settings.M02)); + point_tracker.dynamic_pose_resolution = settings.dyn_pose_res; + sleep_time = settings.sleep_time; + point_tracker.dt_reset = settings.reset_time / 1000.0; + draw_frame = settings.video_widget; + cam_pitch = settings.cam_pitch; + + bEnableRoll = settings.bEnableRoll; + bEnablePitch = settings.bEnablePitch; + bEnableYaw = settings.bEnableYaw; + bEnableX = settings.bEnableX; + bEnableY = settings.bEnableY; + bEnableZ = settings.bEnableZ; + + t_MH = settings.t_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_CH_0 = X_CM_0 * X_MH; +} + +void Tracker::refreshVideo() +{ + if (video_widget && fresh) + { + Mat frame_copy; + std::auto_ptr< vector > points; + { + //QMutexLocker lock(&mutex); + if (!draw_frame || frame.empty()) return; + + // copy the frame and points from the tracker thread + frame_copy = frame.clone(); + points = std::auto_ptr< vector >(new vector(point_extractor.get_points())); + } + //QMutexLocker lck(&mutex); + video_widget->update_image(frame_copy, points); + } +} + +void Tracker::StartTracker(QFrame* videoframe) +{ + const int VIDEO_FRAME_WIDTH = videoframe->width(); + const int VIDEO_FRAME_HEIGHT = videoframe->height(); + TrackerSettings settings; + settings.load_ini(); + apply(settings); + qDebug("Tracker::Initialize"); + // setup video frame + video_widget = new VideoWidget(videoframe); + QHBoxLayout* layout = new QHBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(video_widget); + if (videoframe->layout()) delete videoframe->layout(); + videoframe->setLayout(layout); + video_widget->resize(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT); + videoframe->show(); + connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget())); + timer.start(40); + camera.start(); + start(); + reset_command(PAUSE); +} + +void Tracker::paint_widget() { + if (fresh) { + fresh = false; + video_widget->update(); + } +} + +bool Tracker::GiveHeadPoseData(double *data) +{ + const double rad2deg = 180.0/3.14159265; + const double deg2rad = 1.0/rad2deg; + { + QMutexLocker lock(&mutex); + + if (!tracking_valid) return false; + + FrameTrafo X_CM = point_tracker.get_pose(); + FrameTrafo X_MH(Matx33f::eye(), t_MH); + FrameTrafo X_CH = X_CM * X_MH; + + Matx33f R = X_CH.R * X_CH_0.R.t(); + Vec3f t = X_CH.t - X_CH_0.t; + + // correct for camera pitch + Matx33f R_CP( 1, 0, 0, + 0, cos(deg2rad*cam_pitch), sin(deg2rad*cam_pitch), + 0, -sin(deg2rad*cam_pitch), cos(deg2rad*cam_pitch)); + R = R_CP * R * R_CP.t(); + t = R_CP * t; + + // get translation(s) + if (bEnableX) { + data[TX] = t[0] / 10.0; // convert to cm + } + if (bEnableY) { + data[TY] = t[1] / 10.0; + } + if (bEnableZ) { + data[TZ] = t[2] / 10.0; + } + + // translate rotation matrix from opengl (G) to roll-pitch-yaw (R) frame + // -z -> x, y -> z, x -> -y + Matx33f R_RG( 0, 0,-1, + -1, 0, 0, + 0, 1, 0); + R = R_RG * R * R_RG.t(); + + // extract rotation angles + double alpha, beta, gamma; + //beta = atan2( -R(2,0), sqrt(R(0,0)*R(0,0) + R(1,0)*R(1,0)) ); + 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 (bEnableYaw) { + data[Yaw] = rad2deg * alpha; + } + if (bEnablePitch) { + data[Pitch] = rad2deg * beta; + } + if (bEnableRoll) { + data[Roll] = rad2deg * gamma; + } + } + return true; +} + +//----------------------------------------------------------------------------- +//#pragma comment(linker, "/export:GetTracker=_GetTracker@0") + +extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() +{ + return new Tracker; +} diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.h b/ftnoir_tracker_pt/ftnoir_tracker_pt.h index 0c45c6b6..3825fce7 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.h @@ -1,96 +1,96 @@ -/* 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 - -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ftnoir_tracker_pt_settings.h" -#include "camera.h" -#include "point_extractor.h" -#include "point_tracker.h" -#include "video_widget.h" -#include "timer.h" - -#include -#include -#include -#include -#include -#include - -//----------------------------------------------------------------------------- -class Tracker : public QThread, public ITracker -{ - Q_OBJECT -public: - Tracker(); - ~Tracker(); - - // ITracker interface - void StartTracker(QFrame* videoFrame); - bool GiveHeadPoseData(double *data); - - void refreshVideo(); - - void apply(const TrackerSettings& settings); - void center(); - void reset(); // reset the trackers internal state variables - void run(); - void WaitForExit() { - should_quit = true; - wait(); - } - - 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: - FrameTrafo X_CH_0; // for centering - cv::Mat frame; // the output frame for display - - enum Command { - ABORT = 1<<0, - PAUSE = 1<<1 - }; - void set_command(Command command); - void reset_command(Command command); - - CVCamera camera; - PointExtractor point_extractor; - PointTracker point_tracker; - bool tracking_valid; - - cv::Vec3f t_MH; - int cam_pitch; - - bool draw_frame; - int sleep_time; - - bool bEnableRoll; - bool bEnablePitch; - bool bEnableYaw; - bool bEnableX; - bool bEnableY; - bool bEnableZ; - - long frame_count; - volatile int commands; - - VideoWidget* video_widget; - Timer time; - QMutex mutex; - volatile bool should_quit; - volatile bool fresh; - QTimer timer; - -protected slots: - void paint_widget(); -}; - -#endif // FTNOIR_TRACKER_PT_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_H +#define FTNOIR_TRACKER_PT_H + +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_tracker_pt_settings.h" +#include "camera.h" +#include "point_extractor.h" +#include "point_tracker.h" +#include "video_widget.h" +#include "timer.h" + +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +class Tracker : public QThread, public ITracker +{ + Q_OBJECT +public: + Tracker(); + ~Tracker(); + + // ITracker interface + void StartTracker(QFrame* videoFrame); + bool GiveHeadPoseData(double *data); + + void refreshVideo(); + + void apply(const TrackerSettings& settings); + void center(); + void reset(); // reset the trackers internal state variables + void run(); + void WaitForExit() { + should_quit = true; + wait(); + } + + 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: + FrameTrafo X_CH_0; // for centering + cv::Mat frame; // the output frame for display + + enum Command { + ABORT = 1<<0, + PAUSE = 1<<1 + }; + void set_command(Command command); + void reset_command(Command command); + + CVCamera camera; + PointExtractor point_extractor; + PointTracker point_tracker; + bool tracking_valid; + + cv::Vec3f t_MH; + int cam_pitch; + + bool draw_frame; + int sleep_time; + + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; + + long frame_count; + volatile int commands; + + VideoWidget* video_widget; + Timer time; + QMutex mutex; + volatile bool should_quit; + volatile bool fresh; + QTimer timer; + +protected slots: + void paint_widget(); +}; + +#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 index 4837f4a9..f222085e 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp @@ -1,337 +1,337 @@ -/* 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 -#include -#include "facetracknoir/global-settings.h" - -//----------------------------------------------------------------------------- -TrackerDialog::TrackerDialog() - : settings_dirty(false), tracker(NULL), trans_calib_running(false), timer(this) -{ - qDebug()<<"TrackerDialog::TrackerDialog"; - setAttribute(Qt::WA_DeleteOnClose, false); - - ui.setupUi( this ); - - settings.load_ini(); - dialog_settings.load_ini(); - - // initialize ui values - ui.videowidget_check->setChecked(settings.video_widget); - ui.dynpose_check->setChecked(settings.dyn_pose_res); - ui.sleep_spin->setValue(settings.sleep_time); - ui.reset_spin->setValue(settings.reset_time); - ui.camindex_spin->setValue(settings.cam_index); - ui.f_dspin->setValue(settings.cam_f); - ui.res_x_spin->setValue(settings.cam_res_x); - ui.res_y_spin->setValue(settings.cam_res_y); - ui.fps_spin->setValue(settings.cam_fps); - ui.campitch_spin->setValue(settings.cam_pitch); - ui.threshold_slider->setValue(settings.threshold); - - ui.chkEnableRoll->setChecked(settings.bEnableRoll); - ui.chkEnablePitch->setChecked(settings.bEnablePitch); - ui.chkEnableYaw->setChecked(settings.bEnableYaw); - ui.chkEnableX->setChecked(settings.bEnableX); - ui.chkEnableY->setChecked(settings.bEnableY); - ui.chkEnableZ->setChecked(settings.bEnableZ); - - ui.mindiam_spin->setValue(settings.min_point_size); - ui.maxdiam_spin->setValue(settings.max_point_size); - ui.model_tabs->setCurrentIndex(dialog_settings.active_model_panel); - ui.clip_bheight_spin->setValue(dialog_settings.clip_by); - ui.clip_blength_spin->setValue(dialog_settings.clip_bz); - ui.clip_theight_spin->setValue(dialog_settings.clip_ty); - ui.clip_tlength_spin->setValue(dialog_settings.clip_tz); - ui.cap_width_spin->setValue(dialog_settings.cap_x); - ui.cap_height_spin->setValue(dialog_settings.cap_y); - ui.cap_length_spin->setValue(dialog_settings.cap_z); - ui.m1x_spin->setValue(dialog_settings.M01x); - ui.m1y_spin->setValue(dialog_settings.M01y); - ui.m1z_spin->setValue(dialog_settings.M01z); - ui.m2x_spin->setValue(dialog_settings.M02x); - ui.m2y_spin->setValue(dialog_settings.M02y); - ui.m2z_spin->setValue(dialog_settings.M02z); - ui.tx_spin->setValue(settings.t_MH[0]); - ui.ty_spin->setValue(settings.t_MH[1]); - ui.tz_spin->setValue(settings.t_MH[2]); - - // connect Qt signals and slots - connect( ui.videowidget_check,SIGNAL(toggled(bool)), this,SLOT(set_video_widget(bool)) ); - connect( ui.dynpose_check,SIGNAL(toggled(bool)), this,SLOT(set_dyn_pose_res(bool)) ); - connect( ui.sleep_spin,SIGNAL(valueChanged(int)), this,SLOT(set_sleep_time(int)) ); - connect( ui.reset_spin,SIGNAL(valueChanged(int)), this,SLOT(set_reset_time(int)) ); - connect( ui.camindex_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_index(int)) ); - connect( ui.f_dspin,SIGNAL(valueChanged(double)), this,SLOT(set_cam_f(double)) ); - connect( ui.res_x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_res_x(int)) ); - connect( ui.res_y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_res_y(int)) ); - connect( ui.fps_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_fps(int)) ); - connect( ui.campitch_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_pitch(int)) ); - connect( ui.threshold_slider,SIGNAL(sliderMoved(int)), this,SLOT(set_threshold(int)) ); - - connect( ui.chkEnableRoll,SIGNAL(toggled(bool)), this,SLOT(set_ena_roll(bool)) ); - connect( ui.chkEnablePitch,SIGNAL(toggled(bool)), this,SLOT(set_ena_pitch(bool)) ); - connect( ui.chkEnableYaw,SIGNAL(toggled(bool)), this,SLOT(set_ena_yaw(bool)) ); - connect( ui.chkEnableX,SIGNAL(toggled(bool)), this,SLOT(set_ena_x(bool)) ); - connect( ui.chkEnableY,SIGNAL(toggled(bool)), this,SLOT(set_ena_y(bool)) ); - connect( ui.chkEnableZ,SIGNAL(toggled(bool)), this,SLOT(set_ena_z(bool)) ); - - connect( ui.mindiam_spin,SIGNAL(valueChanged(int)), this,SLOT(set_min_point_size(int)) ); - connect( ui.maxdiam_spin,SIGNAL(valueChanged(int)), this,SLOT(set_max_point_size(int)) ); - connect( ui.model_tabs,SIGNAL(currentChanged(int)), this,SLOT(set_model(int)) ); - connect( ui.clip_theight_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_t_height(int)) ); - connect( ui.clip_tlength_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_t_length(int)) ); - connect( ui.clip_bheight_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_b_height(int)) ); - connect( ui.clip_blength_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_b_length(int)) ); - connect( ui.cap_width_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_width(int)) ); - connect( ui.cap_height_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_height(int)) ); - connect( ui.cap_length_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_length(int)) ); - connect( ui.m1x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1x(int)) ); - connect( ui.m1y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1y(int)) ); - connect( ui.m1z_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1z(int)) ); - connect( ui.m2x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2x(int)) ); - connect( ui.m2y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2y(int)) ); - connect( ui.m2z_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2z(int)) ); - connect( ui.tx_spin,SIGNAL(valueChanged(int)), this,SLOT(set_tx(int)) ); - connect( ui.ty_spin,SIGNAL(valueChanged(int)), this,SLOT(set_ty(int)) ); - connect( ui.tz_spin,SIGNAL(valueChanged(int)), this,SLOT(set_tz(int)) ); - - connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) ); - - connect(ui.reset_button, SIGNAL(clicked()), this, SLOT(doReset())); - //connect(ui.center_button, SIGNAL(clicked()), this, SLOT(doCenter())); - - connect(ui.ok_button, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.cancel_button, SIGNAL(clicked()), this, SLOT(doCancel())); - - connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info())); - timer.start(100); -} - -TrackerDialog::~TrackerDialog() -{ - qDebug()<<"TrackerDialog::~TrackerDialog"; -} - -void TrackerDialog::set_clip() -{ - settings.M01[0] = 0; - settings.M01[1] = dialog_settings.clip_ty; - settings.M01[2] = -dialog_settings.clip_tz; - settings.M02[0] = 0; - settings.M02[1] = -dialog_settings.clip_by; - settings.M02[2] = -dialog_settings.clip_bz; - - settings_changed(); -} - -void TrackerDialog::set_cap() -{ - settings.M01[0] = -dialog_settings.cap_x; - settings.M01[1] = -dialog_settings.cap_y; - settings.M01[2] = -dialog_settings.cap_z; - settings.M02[0] = dialog_settings.cap_x; - settings.M02[1] = -dialog_settings.cap_y; - settings.M02[2] = -dialog_settings.cap_z; - - settings_changed(); -} - -void TrackerDialog::set_custom() -{ - settings.M01[0] = dialog_settings.M01x; - settings.M01[1] = dialog_settings.M01y; - settings.M01[2] = dialog_settings.M01z; - settings.M02[0] = dialog_settings.M02x; - settings.M02[1] = dialog_settings.M02y; - settings.M02[2] = dialog_settings.M02z; - - settings_changed(); -} - -void TrackerDialog::set_model(int val) -{ - dialog_settings.active_model_panel = val; - - switch (val) { - - case TrackerDialogSettings::MODEL_CLIP: - set_clip(); - break; - - case TrackerDialogSettings::MODEL_CAP: - set_cap(); - break; - - case TrackerDialogSettings::MODEL_CUSTOM: - set_custom(); - break; - - default: - break; - } -} - -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; - settings.t_MH = trans_calib.get_estimate(); - 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(); - //qDebug()<<"TrackerDialog:: Current translation estimate: "<setValue(t_MH[0]); - ui.ty_spin->setValue(t_MH[1]); - ui.tz_spin->setValue(t_MH[2]); - } -} - -void TrackerDialog::settings_changed() -{ - settings_dirty = true; - if (tracker) tracker->apply(settings); -} - -void TrackerDialog::doCenter() -{ - if (tracker) tracker->center(); -} - -void TrackerDialog::doReset() -{ - if (tracker) tracker->reset(); -} - -void TrackerDialog::doOK() -{ - settings.save_ini(); - dialog_settings.save_ini(); - close(); -} - -void TrackerDialog::doCancel() -{ - if (settings_dirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - switch (ret) { - case QMessageBox::Save: - settings.save_ini(); - dialog_settings.save_ini(); - close(); - break; - case QMessageBox::Discard: - close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - close(); - } -} - -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); - ui.caminfo_label_2->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); - ui.pointinfo_label_2->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.caminfo_label_2->setText(to_print); - ui.pointinfo_label->setText(to_print); - ui.pointinfo_label_2->setText(to_print); - } -} - - -//----------------------------------------------------------------------------- -// ITrackerDialog interface -void TrackerDialog::Initialize(QWidget *parent) -{ - QPoint offsetpos(200, 200); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -void TrackerDialog::registerTracker(ITracker *t) -{ - qDebug()<<"TrackerDialog:: Tracker registered"; - tracker = static_cast(t); - if (isVisible() && settings_dirty) tracker->apply(settings); - 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; - ui.tcalib_button->setEnabled(false); - //ui.center_button->setEnabled(false); - ui.reset_button->setEnabled(false); -} - -//----------------------------------------------------------------------------- -//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") - -extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) -{ - return new TrackerDialog; -} +/* 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 +#include +#include "facetracknoir/global-settings.h" + +//----------------------------------------------------------------------------- +TrackerDialog::TrackerDialog() + : settings_dirty(false), tracker(NULL), trans_calib_running(false), timer(this) +{ + qDebug()<<"TrackerDialog::TrackerDialog"; + setAttribute(Qt::WA_DeleteOnClose, false); + + ui.setupUi( this ); + + settings.load_ini(); + dialog_settings.load_ini(); + + // initialize ui values + ui.videowidget_check->setChecked(settings.video_widget); + ui.dynpose_check->setChecked(settings.dyn_pose_res); + ui.sleep_spin->setValue(settings.sleep_time); + ui.reset_spin->setValue(settings.reset_time); + ui.camindex_spin->setValue(settings.cam_index); + ui.f_dspin->setValue(settings.cam_f); + ui.res_x_spin->setValue(settings.cam_res_x); + ui.res_y_spin->setValue(settings.cam_res_y); + ui.fps_spin->setValue(settings.cam_fps); + ui.campitch_spin->setValue(settings.cam_pitch); + ui.threshold_slider->setValue(settings.threshold); + + ui.chkEnableRoll->setChecked(settings.bEnableRoll); + ui.chkEnablePitch->setChecked(settings.bEnablePitch); + ui.chkEnableYaw->setChecked(settings.bEnableYaw); + ui.chkEnableX->setChecked(settings.bEnableX); + ui.chkEnableY->setChecked(settings.bEnableY); + ui.chkEnableZ->setChecked(settings.bEnableZ); + + ui.mindiam_spin->setValue(settings.min_point_size); + ui.maxdiam_spin->setValue(settings.max_point_size); + ui.model_tabs->setCurrentIndex(dialog_settings.active_model_panel); + ui.clip_bheight_spin->setValue(dialog_settings.clip_by); + ui.clip_blength_spin->setValue(dialog_settings.clip_bz); + ui.clip_theight_spin->setValue(dialog_settings.clip_ty); + ui.clip_tlength_spin->setValue(dialog_settings.clip_tz); + ui.cap_width_spin->setValue(dialog_settings.cap_x); + ui.cap_height_spin->setValue(dialog_settings.cap_y); + ui.cap_length_spin->setValue(dialog_settings.cap_z); + ui.m1x_spin->setValue(dialog_settings.M01x); + ui.m1y_spin->setValue(dialog_settings.M01y); + ui.m1z_spin->setValue(dialog_settings.M01z); + ui.m2x_spin->setValue(dialog_settings.M02x); + ui.m2y_spin->setValue(dialog_settings.M02y); + ui.m2z_spin->setValue(dialog_settings.M02z); + ui.tx_spin->setValue(settings.t_MH[0]); + ui.ty_spin->setValue(settings.t_MH[1]); + ui.tz_spin->setValue(settings.t_MH[2]); + + // connect Qt signals and slots + connect( ui.videowidget_check,SIGNAL(toggled(bool)), this,SLOT(set_video_widget(bool)) ); + connect( ui.dynpose_check,SIGNAL(toggled(bool)), this,SLOT(set_dyn_pose_res(bool)) ); + connect( ui.sleep_spin,SIGNAL(valueChanged(int)), this,SLOT(set_sleep_time(int)) ); + connect( ui.reset_spin,SIGNAL(valueChanged(int)), this,SLOT(set_reset_time(int)) ); + connect( ui.camindex_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_index(int)) ); + connect( ui.f_dspin,SIGNAL(valueChanged(double)), this,SLOT(set_cam_f(double)) ); + connect( ui.res_x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_res_x(int)) ); + connect( ui.res_y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_res_y(int)) ); + connect( ui.fps_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_fps(int)) ); + connect( ui.campitch_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cam_pitch(int)) ); + connect( ui.threshold_slider,SIGNAL(sliderMoved(int)), this,SLOT(set_threshold(int)) ); + + connect( ui.chkEnableRoll,SIGNAL(toggled(bool)), this,SLOT(set_ena_roll(bool)) ); + connect( ui.chkEnablePitch,SIGNAL(toggled(bool)), this,SLOT(set_ena_pitch(bool)) ); + connect( ui.chkEnableYaw,SIGNAL(toggled(bool)), this,SLOT(set_ena_yaw(bool)) ); + connect( ui.chkEnableX,SIGNAL(toggled(bool)), this,SLOT(set_ena_x(bool)) ); + connect( ui.chkEnableY,SIGNAL(toggled(bool)), this,SLOT(set_ena_y(bool)) ); + connect( ui.chkEnableZ,SIGNAL(toggled(bool)), this,SLOT(set_ena_z(bool)) ); + + connect( ui.mindiam_spin,SIGNAL(valueChanged(int)), this,SLOT(set_min_point_size(int)) ); + connect( ui.maxdiam_spin,SIGNAL(valueChanged(int)), this,SLOT(set_max_point_size(int)) ); + connect( ui.model_tabs,SIGNAL(currentChanged(int)), this,SLOT(set_model(int)) ); + connect( ui.clip_theight_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_t_height(int)) ); + connect( ui.clip_tlength_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_t_length(int)) ); + connect( ui.clip_bheight_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_b_height(int)) ); + connect( ui.clip_blength_spin,SIGNAL(valueChanged(int)), this,SLOT(set_clip_b_length(int)) ); + connect( ui.cap_width_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_width(int)) ); + connect( ui.cap_height_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_height(int)) ); + connect( ui.cap_length_spin,SIGNAL(valueChanged(int)), this,SLOT(set_cap_length(int)) ); + connect( ui.m1x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1x(int)) ); + connect( ui.m1y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1y(int)) ); + connect( ui.m1z_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m1z(int)) ); + connect( ui.m2x_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2x(int)) ); + connect( ui.m2y_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2y(int)) ); + connect( ui.m2z_spin,SIGNAL(valueChanged(int)), this,SLOT(set_m2z(int)) ); + connect( ui.tx_spin,SIGNAL(valueChanged(int)), this,SLOT(set_tx(int)) ); + connect( ui.ty_spin,SIGNAL(valueChanged(int)), this,SLOT(set_ty(int)) ); + connect( ui.tz_spin,SIGNAL(valueChanged(int)), this,SLOT(set_tz(int)) ); + + connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) ); + + connect(ui.reset_button, SIGNAL(clicked()), this, SLOT(doReset())); + //connect(ui.center_button, SIGNAL(clicked()), this, SLOT(doCenter())); + + connect(ui.ok_button, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.cancel_button, SIGNAL(clicked()), this, SLOT(doCancel())); + + connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info())); + timer.start(100); +} + +TrackerDialog::~TrackerDialog() +{ + qDebug()<<"TrackerDialog::~TrackerDialog"; +} + +void TrackerDialog::set_clip() +{ + settings.M01[0] = 0; + settings.M01[1] = dialog_settings.clip_ty; + settings.M01[2] = -dialog_settings.clip_tz; + settings.M02[0] = 0; + settings.M02[1] = -dialog_settings.clip_by; + settings.M02[2] = -dialog_settings.clip_bz; + + settings_changed(); +} + +void TrackerDialog::set_cap() +{ + settings.M01[0] = -dialog_settings.cap_x; + settings.M01[1] = -dialog_settings.cap_y; + settings.M01[2] = -dialog_settings.cap_z; + settings.M02[0] = dialog_settings.cap_x; + settings.M02[1] = -dialog_settings.cap_y; + settings.M02[2] = -dialog_settings.cap_z; + + settings_changed(); +} + +void TrackerDialog::set_custom() +{ + settings.M01[0] = dialog_settings.M01x; + settings.M01[1] = dialog_settings.M01y; + settings.M01[2] = dialog_settings.M01z; + settings.M02[0] = dialog_settings.M02x; + settings.M02[1] = dialog_settings.M02y; + settings.M02[2] = dialog_settings.M02z; + + settings_changed(); +} + +void TrackerDialog::set_model(int val) +{ + dialog_settings.active_model_panel = val; + + switch (val) { + + case TrackerDialogSettings::MODEL_CLIP: + set_clip(); + break; + + case TrackerDialogSettings::MODEL_CAP: + set_cap(); + break; + + case TrackerDialogSettings::MODEL_CUSTOM: + set_custom(); + break; + + default: + break; + } +} + +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; + settings.t_MH = trans_calib.get_estimate(); + 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(); + //qDebug()<<"TrackerDialog:: Current translation estimate: "<setValue(t_MH[0]); + ui.ty_spin->setValue(t_MH[1]); + ui.tz_spin->setValue(t_MH[2]); + } +} + +void TrackerDialog::settings_changed() +{ + settings_dirty = true; + if (tracker) tracker->apply(settings); +} + +void TrackerDialog::doCenter() +{ + if (tracker) tracker->center(); +} + +void TrackerDialog::doReset() +{ + if (tracker) tracker->reset(); +} + +void TrackerDialog::doOK() +{ + settings.save_ini(); + dialog_settings.save_ini(); + close(); +} + +void TrackerDialog::doCancel() +{ + if (settings_dirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + switch (ret) { + case QMessageBox::Save: + settings.save_ini(); + dialog_settings.save_ini(); + close(); + break; + case QMessageBox::Discard: + close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + close(); + } +} + +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); + ui.caminfo_label_2->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); + ui.pointinfo_label_2->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.caminfo_label_2->setText(to_print); + ui.pointinfo_label->setText(to_print); + ui.pointinfo_label_2->setText(to_print); + } +} + + +//----------------------------------------------------------------------------- +// ITrackerDialog interface +void TrackerDialog::Initialize(QWidget *parent) +{ + QPoint offsetpos(200, 200); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +void TrackerDialog::registerTracker(ITracker *t) +{ + qDebug()<<"TrackerDialog:: Tracker registered"; + tracker = static_cast(t); + if (isVisible() && settings_dirty) tracker->apply(settings); + 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; + ui.tcalib_button->setEnabled(false); + //ui.center_button->setEnabled(false); + ui.reset_button->setEnabled(false); +} + +//----------------------------------------------------------------------------- +//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") + +extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION 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 ada331e5..f13fe13e 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h @@ -1,102 +1,102 @@ -/* 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 - -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ftnoir_tracker_pt_settings.h" -#include "ftnoir_tracker_pt.h" -#include "ui_ftnoir_pt_controls.h" -#include "trans_calib.h" - -#include - -//----------------------------------------------------------------------------- -class TrackerDialog : public QWidget, public ITrackerDialog -{ - Q_OBJECT -public: - TrackerDialog(); - ~TrackerDialog(); - - // ITrackerDialog interface - void Initialize(QWidget *parent); - void registerTracker(ITracker *tracker); - void unRegisterTracker(); - - void trans_calib_step(); - -protected slots: - // ugly qt stuff - void set_video_widget(bool val) { settings.video_widget = val; settings_changed(); } - void set_dyn_pose_res(bool val) { settings.dyn_pose_res = val; settings_changed(); } - void set_sleep_time(int val) { settings.sleep_time = val; settings_changed(); } - void set_reset_time(int val) { settings.reset_time = val; settings_changed(); } - void set_cam_index(int val) { settings.cam_index = val; settings_changed(); } - void set_cam_f(double val) { settings.cam_f = val; settings_changed(); } - void set_cam_res_x(int val) { settings.cam_res_x = val; settings_changed(); } - void set_cam_res_y(int val) { settings.cam_res_y = val; settings_changed(); } - void set_cam_fps(int val) { settings.cam_fps = val; settings_changed(); } - void set_cam_pitch(int val) { settings.cam_pitch = val; settings_changed(); } - void set_min_point_size(int val) { settings.min_point_size = val; settings_changed(); } - void set_max_point_size(int val) { settings.max_point_size = val; settings_changed(); } - void set_threshold(int val) { settings.threshold = val; settings_changed(); } - void set_ena_roll(bool val) { settings.bEnableRoll = val; settings_changed(); } - void set_ena_pitch(bool val) { settings.bEnablePitch = val; settings_changed(); } - void set_ena_yaw(bool val) { settings.bEnableYaw = val; settings_changed(); } - void set_ena_x(bool val) { settings.bEnableX = val; settings_changed(); } - void set_ena_y(bool val) { settings.bEnableY = val; settings_changed(); } - void set_ena_z(bool val) { settings.bEnableZ = val; settings_changed(); } - - void set_clip_t_height(int val) { dialog_settings.clip_ty = val; set_clip(); } - void set_clip_t_length(int val) { dialog_settings.clip_tz = val; set_clip(); } - void set_clip_b_height(int val) { dialog_settings.clip_by = val; set_clip(); } - void set_clip_b_length(int val) { dialog_settings.clip_bz = val; set_clip(); } - void set_cap_width(int val) { dialog_settings.cap_x = val; set_cap(); } - void set_cap_height(int val) { dialog_settings.cap_y = val; set_cap(); } - void set_cap_length(int val) { dialog_settings.cap_z = val; set_cap(); } - void set_m1x(int val) { dialog_settings.M01x = val; set_custom(); } - void set_m1y(int val) { dialog_settings.M01y = val; set_custom(); } - void set_m1z(int val) { dialog_settings.M01z = val; set_custom(); } - void set_m2x(int val) { dialog_settings.M02x = val; set_custom(); } - void set_m2y(int val) { dialog_settings.M02y = val; set_custom(); } - void set_m2z(int val) { dialog_settings.M02z = val; set_custom(); } - void set_tx(int val) { settings.t_MH[0] = val; settings_changed(); } - void set_ty(int val) { settings.t_MH[1] = val; settings_changed(); } - void set_tz(int val) { settings.t_MH[2] = val; settings_changed(); } - void set_model(int model_id); - - void doCenter(); - void doReset(); - - void doOK(); - void doCancel(); - - void startstop_trans_calib(bool start); - - void poll_tracker_info(); - -protected: - void set_clip(); - void set_cap(); - void set_custom(); - - void settings_changed(); - - TrackerSettings settings; - TrackerDialogSettings dialog_settings; - bool settings_dirty; - - Tracker* tracker; - TranslationCalibrator trans_calib; - bool trans_calib_running; - QTimer timer; - 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 + +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ftnoir_tracker_pt_settings.h" +#include "ftnoir_tracker_pt.h" +#include "ui_ftnoir_pt_controls.h" +#include "trans_calib.h" + +#include + +//----------------------------------------------------------------------------- +class TrackerDialog : public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + TrackerDialog(); + ~TrackerDialog(); + + // ITrackerDialog interface + void Initialize(QWidget *parent); + void registerTracker(ITracker *tracker); + void unRegisterTracker(); + + void trans_calib_step(); + +protected slots: + // ugly qt stuff + void set_video_widget(bool val) { settings.video_widget = val; settings_changed(); } + void set_dyn_pose_res(bool val) { settings.dyn_pose_res = val; settings_changed(); } + void set_sleep_time(int val) { settings.sleep_time = val; settings_changed(); } + void set_reset_time(int val) { settings.reset_time = val; settings_changed(); } + void set_cam_index(int val) { settings.cam_index = val; settings_changed(); } + void set_cam_f(double val) { settings.cam_f = val; settings_changed(); } + void set_cam_res_x(int val) { settings.cam_res_x = val; settings_changed(); } + void set_cam_res_y(int val) { settings.cam_res_y = val; settings_changed(); } + void set_cam_fps(int val) { settings.cam_fps = val; settings_changed(); } + void set_cam_pitch(int val) { settings.cam_pitch = val; settings_changed(); } + void set_min_point_size(int val) { settings.min_point_size = val; settings_changed(); } + void set_max_point_size(int val) { settings.max_point_size = val; settings_changed(); } + void set_threshold(int val) { settings.threshold = val; settings_changed(); } + void set_ena_roll(bool val) { settings.bEnableRoll = val; settings_changed(); } + void set_ena_pitch(bool val) { settings.bEnablePitch = val; settings_changed(); } + void set_ena_yaw(bool val) { settings.bEnableYaw = val; settings_changed(); } + void set_ena_x(bool val) { settings.bEnableX = val; settings_changed(); } + void set_ena_y(bool val) { settings.bEnableY = val; settings_changed(); } + void set_ena_z(bool val) { settings.bEnableZ = val; settings_changed(); } + + void set_clip_t_height(int val) { dialog_settings.clip_ty = val; set_clip(); } + void set_clip_t_length(int val) { dialog_settings.clip_tz = val; set_clip(); } + void set_clip_b_height(int val) { dialog_settings.clip_by = val; set_clip(); } + void set_clip_b_length(int val) { dialog_settings.clip_bz = val; set_clip(); } + void set_cap_width(int val) { dialog_settings.cap_x = val; set_cap(); } + void set_cap_height(int val) { dialog_settings.cap_y = val; set_cap(); } + void set_cap_length(int val) { dialog_settings.cap_z = val; set_cap(); } + void set_m1x(int val) { dialog_settings.M01x = val; set_custom(); } + void set_m1y(int val) { dialog_settings.M01y = val; set_custom(); } + void set_m1z(int val) { dialog_settings.M01z = val; set_custom(); } + void set_m2x(int val) { dialog_settings.M02x = val; set_custom(); } + void set_m2y(int val) { dialog_settings.M02y = val; set_custom(); } + void set_m2z(int val) { dialog_settings.M02z = val; set_custom(); } + void set_tx(int val) { settings.t_MH[0] = val; settings_changed(); } + void set_ty(int val) { settings.t_MH[1] = val; settings_changed(); } + void set_tz(int val) { settings.t_MH[2] = val; settings_changed(); } + void set_model(int model_id); + + void doCenter(); + void doReset(); + + void doOK(); + void doCancel(); + + void startstop_trans_calib(bool start); + + void poll_tracker_info(); + +protected: + void set_clip(); + void set_cap(); + void set_custom(); + + void settings_changed(); + + TrackerSettings settings; + TrackerDialogSettings dialog_settings; + bool settings_dirty; + + Tracker* tracker; + TranslationCalibrator trans_calib; + bool trans_calib_running; + QTimer timer; + 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 22c4a33d..1c486382 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.cpp @@ -1,40 +1,40 @@ -/* 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 -#include "facetracknoir/global-settings.h" - -//----------------------------------------------------------------------------- -void TrackerDll::getFullName(QString *strToBeFilled) -{ - *strToBeFilled = "PointTracker 1.0"; -} - -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/icon.png"); -} - - -//----------------------------------------------------------------------------- -//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") - -extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() -{ - 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 +#include "facetracknoir/global-settings.h" + +//----------------------------------------------------------------------------- +void TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = "PointTracker 1.0"; +} + +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/icon.png"); +} + + +//----------------------------------------------------------------------------- +//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") + +extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +{ + return new TrackerDll; +} diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h index dde0bc9f..4dc94173 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dll.h @@ -1,18 +1,18 @@ -/* 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_base/ftnoir_tracker_base.h" -#include "facetracknoir/global-settings.h" - -//----------------------------------------------------------------------------- -class TrackerDll : public Metadata -{ - 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. + */ + +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "facetracknoir/global-settings.h" + +//----------------------------------------------------------------------------- +class TrackerDll : public Metadata +{ + 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.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp index 3164b291..b0249813 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp @@ -1,150 +1,150 @@ -/* 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 -#include - -//----------------------------------------------------------------------------- -void TrackerSettings::load_ini() -{ - qDebug("TrackerSettings::load_ini()"); - - 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( "PointTracker" ); - - cam_index = iniFile.value("CameraId", 0).toInt(); - cam_f = iniFile.value("CameraF", 1).toFloat(); - cam_res_x = iniFile.value("CameraResX", 640).toInt(); - cam_res_y = iniFile.value("CameraResY", 480).toInt(); - cam_fps = iniFile.value("CameraFPS", 30).toInt(); - cam_pitch = iniFile.value("CameraPitch", 0).toInt(); - threshold = iniFile.value("PointExtractThreshold", 128).toInt(); - min_point_size = iniFile.value("PointExtractMinSize", 2).toInt(); - max_point_size = iniFile.value("PointExtractMaxSize", 50).toInt(); - M01[0] = iniFile.value("PointModelM01x", 0).toFloat(); - M01[1] = iniFile.value("PointModelM01y", 40).toFloat(); - M01[2] = iniFile.value("PointModelM01z", -30).toFloat(); - M02[0] = iniFile.value("PointModelM02x", 0).toFloat(); - M02[1] = iniFile.value("PointModelM02y", -70).toFloat(); - M02[2] = iniFile.value("PointModelM02z", -80).toFloat(); - t_MH[0] = iniFile.value("tMHx", 0).toFloat(); - t_MH[1] = iniFile.value("tMHy", 0).toFloat(); - t_MH[2] = iniFile.value("tMHz", 0).toFloat(); - dyn_pose_res = iniFile.value("DynamicPoseResolution", true).toBool(); - video_widget = iniFile.value("VideoWidget", true).toBool(); - sleep_time = iniFile.value("SleepTime", 10).toInt(); - reset_time = iniFile.value("ResetTime", 1000).toInt(); - - bEnableRoll = iniFile.value( "EnableRoll", 1 ).toBool(); - bEnablePitch = iniFile.value( "EnablePitch", 1 ).toBool(); - bEnableYaw = iniFile.value( "EnableYaw", 1 ).toBool(); - bEnableX = iniFile.value( "EnableX", 1 ).toBool(); - bEnableY = iniFile.value( "EnableY", 1 ).toBool(); - bEnableZ = iniFile.value( "EnableZ", 1 ).toBool(); - - iniFile.endGroup(); -} - -void TrackerSettings::save_ini() const -{ - qDebug("TrackerSettings::save_ini()"); - - 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 ( "PointTracker" ); - - iniFile.setValue("CameraId", cam_index); - iniFile.setValue("CameraF", cam_f); - iniFile.setValue("CameraResX", cam_res_x); - iniFile.setValue("CameraResY", cam_res_y); - iniFile.setValue("CameraFPS", cam_fps); - iniFile.setValue("CameraPitch", cam_pitch); - iniFile.setValue("PointExtractThreshold", threshold); - iniFile.setValue("PointExtractMinSize", min_point_size); - iniFile.setValue("PointExtractMaxSize", max_point_size); - iniFile.setValue("PointModelM01x", M01[0]); - iniFile.setValue("PointModelM01y", M01[1]); - iniFile.setValue("PointModelM01z", M01[2]); - iniFile.setValue("PointModelM02x", M02[0]); - iniFile.setValue("PointModelM02y", M02[1]); - iniFile.setValue("PointModelM02z", M02[2]); - iniFile.setValue("tMHx", t_MH[0]); - iniFile.setValue("tMHy", t_MH[1]); - iniFile.setValue("tMHz", t_MH[2]); - iniFile.setValue("DynamicPoseResolution", dyn_pose_res); - iniFile.setValue("VideoWidget", video_widget); - iniFile.setValue("SleepTime", sleep_time); - iniFile.setValue("ResetTime", reset_time); - - iniFile.setValue( "EnableRoll", bEnableRoll ); - iniFile.setValue( "EnablePitch", bEnablePitch ); - iniFile.setValue( "EnableYaw", bEnableYaw ); - iniFile.setValue( "EnableX", bEnableX ); - iniFile.setValue( "EnableY", bEnableY ); - iniFile.setValue( "EnableZ", bEnableZ ); - - iniFile.endGroup(); -} - -//----------------------------------------------------------------------------- -void TrackerDialogSettings::load_ini() -{ - qDebug("TrackerDialogSettings::load_ini()"); - - 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( "PointTrackerDialog" ); - - active_model_panel = iniFile.value("ActiveModelPanel", MODEL_CLIP).toInt(); - M01x = iniFile.value("CustomM01x", 0).toInt(); - M01y = iniFile.value("CustomM01y", 40).toInt(); - M01z = iniFile.value("CustomM01z", -30).toInt(); - M02x = iniFile.value("CustomM02x", 0).toInt(); - M02y = iniFile.value("CustomM02y", -70).toInt(); - M02z = iniFile.value("CustomM02z", -80).toInt(); - clip_ty = iniFile.value("ClipTopHeight", 40).toInt(); - clip_tz = iniFile.value("ClipTopLength", 30).toInt(); - clip_by = iniFile.value("ClipBottomHeight", 70).toInt(); - clip_bz = iniFile.value("ClipBottomLength", 80).toInt(); - cap_x = iniFile.value("CapHalfWidth", 40).toInt(); - cap_y = iniFile.value("CapHeight", 60).toInt(); - cap_z = iniFile.value("CapLength", 100).toInt(); -} - -void TrackerDialogSettings::save_ini() const -{ - qDebug("TrackerDialogSettings::save_ini()"); - - 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 ( "PointTrackerDialog" ); - - iniFile.setValue("ActiveModelPanel", active_model_panel); - iniFile.setValue("CustomM01x", M01x); - iniFile.setValue("CustomM01y", M01y); - iniFile.setValue("CustomM01z", M01z); - iniFile.setValue("CustomM02x", M02x); - iniFile.setValue("CustomM02y", M02y); - iniFile.setValue("CustomM02z", M02z); - iniFile.setValue("ClipTopHeight", clip_ty); - iniFile.setValue("ClipTopLength", clip_tz); - iniFile.setValue("ClipBottomHeight", clip_by); - iniFile.setValue("ClipBottomLength", clip_bz); - iniFile.setValue("CapHalfWidth", cap_x); - iniFile.setValue("CapHeight", cap_y); - iniFile.setValue("CapLength", cap_z); +/* 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 +#include + +//----------------------------------------------------------------------------- +void TrackerSettings::load_ini() +{ + qDebug("TrackerSettings::load_ini()"); + + 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( "PointTracker" ); + + cam_index = iniFile.value("CameraId", 0).toInt(); + cam_f = iniFile.value("CameraF", 1).toFloat(); + cam_res_x = iniFile.value("CameraResX", 640).toInt(); + cam_res_y = iniFile.value("CameraResY", 480).toInt(); + cam_fps = iniFile.value("CameraFPS", 30).toInt(); + cam_pitch = iniFile.value("CameraPitch", 0).toInt(); + threshold = iniFile.value("PointExtractThreshold", 128).toInt(); + min_point_size = iniFile.value("PointExtractMinSize", 2).toInt(); + max_point_size = iniFile.value("PointExtractMaxSize", 50).toInt(); + M01[0] = iniFile.value("PointModelM01x", 0).toFloat(); + M01[1] = iniFile.value("PointModelM01y", 40).toFloat(); + M01[2] = iniFile.value("PointModelM01z", -30).toFloat(); + M02[0] = iniFile.value("PointModelM02x", 0).toFloat(); + M02[1] = iniFile.value("PointModelM02y", -70).toFloat(); + M02[2] = iniFile.value("PointModelM02z", -80).toFloat(); + t_MH[0] = iniFile.value("tMHx", 0).toFloat(); + t_MH[1] = iniFile.value("tMHy", 0).toFloat(); + t_MH[2] = iniFile.value("tMHz", 0).toFloat(); + dyn_pose_res = iniFile.value("DynamicPoseResolution", true).toBool(); + video_widget = iniFile.value("VideoWidget", true).toBool(); + sleep_time = iniFile.value("SleepTime", 10).toInt(); + reset_time = iniFile.value("ResetTime", 1000).toInt(); + + bEnableRoll = iniFile.value( "EnableRoll", 1 ).toBool(); + bEnablePitch = iniFile.value( "EnablePitch", 1 ).toBool(); + bEnableYaw = iniFile.value( "EnableYaw", 1 ).toBool(); + bEnableX = iniFile.value( "EnableX", 1 ).toBool(); + bEnableY = iniFile.value( "EnableY", 1 ).toBool(); + bEnableZ = iniFile.value( "EnableZ", 1 ).toBool(); + + iniFile.endGroup(); +} + +void TrackerSettings::save_ini() const +{ + qDebug("TrackerSettings::save_ini()"); + + 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 ( "PointTracker" ); + + iniFile.setValue("CameraId", cam_index); + iniFile.setValue("CameraF", cam_f); + iniFile.setValue("CameraResX", cam_res_x); + iniFile.setValue("CameraResY", cam_res_y); + iniFile.setValue("CameraFPS", cam_fps); + iniFile.setValue("CameraPitch", cam_pitch); + iniFile.setValue("PointExtractThreshold", threshold); + iniFile.setValue("PointExtractMinSize", min_point_size); + iniFile.setValue("PointExtractMaxSize", max_point_size); + iniFile.setValue("PointModelM01x", M01[0]); + iniFile.setValue("PointModelM01y", M01[1]); + iniFile.setValue("PointModelM01z", M01[2]); + iniFile.setValue("PointModelM02x", M02[0]); + iniFile.setValue("PointModelM02y", M02[1]); + iniFile.setValue("PointModelM02z", M02[2]); + iniFile.setValue("tMHx", t_MH[0]); + iniFile.setValue("tMHy", t_MH[1]); + iniFile.setValue("tMHz", t_MH[2]); + iniFile.setValue("DynamicPoseResolution", dyn_pose_res); + iniFile.setValue("VideoWidget", video_widget); + iniFile.setValue("SleepTime", sleep_time); + iniFile.setValue("ResetTime", reset_time); + + iniFile.setValue( "EnableRoll", bEnableRoll ); + iniFile.setValue( "EnablePitch", bEnablePitch ); + iniFile.setValue( "EnableYaw", bEnableYaw ); + iniFile.setValue( "EnableX", bEnableX ); + iniFile.setValue( "EnableY", bEnableY ); + iniFile.setValue( "EnableZ", bEnableZ ); + + iniFile.endGroup(); +} + +//----------------------------------------------------------------------------- +void TrackerDialogSettings::load_ini() +{ + qDebug("TrackerDialogSettings::load_ini()"); + + 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( "PointTrackerDialog" ); + + active_model_panel = iniFile.value("ActiveModelPanel", MODEL_CLIP).toInt(); + M01x = iniFile.value("CustomM01x", 0).toInt(); + M01y = iniFile.value("CustomM01y", 40).toInt(); + M01z = iniFile.value("CustomM01z", -30).toInt(); + M02x = iniFile.value("CustomM02x", 0).toInt(); + M02y = iniFile.value("CustomM02y", -70).toInt(); + M02z = iniFile.value("CustomM02z", -80).toInt(); + clip_ty = iniFile.value("ClipTopHeight", 40).toInt(); + clip_tz = iniFile.value("ClipTopLength", 30).toInt(); + clip_by = iniFile.value("ClipBottomHeight", 70).toInt(); + clip_bz = iniFile.value("ClipBottomLength", 80).toInt(); + cap_x = iniFile.value("CapHalfWidth", 40).toInt(); + cap_y = iniFile.value("CapHeight", 60).toInt(); + cap_z = iniFile.value("CapLength", 100).toInt(); +} + +void TrackerDialogSettings::save_ini() const +{ + qDebug("TrackerDialogSettings::save_ini()"); + + 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 ( "PointTrackerDialog" ); + + iniFile.setValue("ActiveModelPanel", active_model_panel); + iniFile.setValue("CustomM01x", M01x); + iniFile.setValue("CustomM01y", M01y); + iniFile.setValue("CustomM01z", M01z); + iniFile.setValue("CustomM02x", M02x); + iniFile.setValue("CustomM02y", M02y); + iniFile.setValue("CustomM02z", M02z); + iniFile.setValue("ClipTopHeight", clip_ty); + iniFile.setValue("ClipTopLength", clip_tz); + iniFile.setValue("ClipBottomHeight", clip_by); + iniFile.setValue("ClipBottomLength", clip_bz); + iniFile.setValue("CapHalfWidth", cap_x); + iniFile.setValue("CapHeight", cap_y); + iniFile.setValue("CapLength", cap_z); } \ No newline at end of file diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h index 88162c86..a1523898 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h @@ -1,84 +1,84 @@ -/* 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 -#include "point_tracker.h" - - -//----------------------------------------------------------------------------- -struct TrackerSettings -{ - // camera - int cam_index; - float cam_f; - int cam_res_x; - int cam_res_y; - int cam_fps; - int cam_pitch; - - // point extraction - int threshold; - int min_point_size; - int max_point_size; - - // point tracking - cv::Vec3f M01; - cv::Vec3f M02; - bool dyn_pose_res; - - // head to model translation - cv::Vec3f t_MH; - - int sleep_time; // in ms - int reset_time; // in ms - bool video_widget; - - bool bEnableRoll; - bool bEnablePitch; - bool bEnableYaw; - bool bEnableX; - bool bEnableY; - bool bEnableZ; - - void load_ini(); - void save_ini() const; -}; - - -//----------------------------------------------------------------------------- -struct TrackerDialogSettings -{ - enum - { - MODEL_CLIP, - MODEL_CAP, - MODEL_CUSTOM - }; - int active_model_panel; - - int M01x; - int M01y; - int M01z; - int M02x; - int M02y; - int M02z; - int clip_ty; - int clip_tz; - int clip_by; - int clip_bz; - int cap_x; - int cap_y; - int cap_z; - - void load_ini(); - void save_ini() const; -}; - +/* 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 +#include "point_tracker.h" + + +//----------------------------------------------------------------------------- +struct TrackerSettings +{ + // camera + int cam_index; + float cam_f; + int cam_res_x; + int cam_res_y; + int cam_fps; + int cam_pitch; + + // point extraction + int threshold; + int min_point_size; + int max_point_size; + + // point tracking + cv::Vec3f M01; + cv::Vec3f M02; + bool dyn_pose_res; + + // head to model translation + cv::Vec3f t_MH; + + int sleep_time; // in ms + int reset_time; // in ms + bool video_widget; + + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; + + void load_ini(); + void save_ini() const; +}; + + +//----------------------------------------------------------------------------- +struct TrackerDialogSettings +{ + enum + { + MODEL_CLIP, + MODEL_CAP, + MODEL_CUSTOM + }; + int active_model_panel; + + int M01x; + int M01y; + int M01z; + int M02x; + int M02y; + int M02z; + int clip_ty; + int clip_tz; + int clip_by; + int clip_bz; + int cap_x; + int cap_y; + int cap_z; + + void load_ini(); + void save_ini() const; +}; + #endif //FTNOIR_TRACKER_PT_SETTINGS_H \ No newline at end of file diff --git a/ftnoir_tracker_pt/point_extractor.cpp b/ftnoir_tracker_pt/point_extractor.cpp index 61e86bec..09be967a 100644 --- a/ftnoir_tracker_pt/point_extractor.cpp +++ b/ftnoir_tracker_pt/point_extractor.cpp @@ -1,96 +1,96 @@ -/* 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 - -using namespace cv; -using namespace std; - -// ---------------------------------------------------------------------------- -const vector& PointExtractor::extract_points(Mat frame, float dt, bool draw_output) -{ - const int W = frame.cols; - const int H = frame.rows; - - // clear old points - points.clear(); - - // convert to grayscale - Mat frame_grey; - cvtColor(frame, frame_grey, COLOR_BGR2GRAY); - - // convert to binary - Mat frame_bin; - threshold(frame_grey, frame_bin, threshold_val, 255, THRESH_BINARY); - - unsigned int region_size_min = 3.14*min_size*min_size; - unsigned int region_size_max = 3.14*max_size*max_size; - - int blob_index = 1; - for (int y=0; y(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(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(i,j) != blob_index-1) continue; - float val = frame_grey.at(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) - 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; - points.push_back(c); - - if (blob_index >= 255) break; - } - if (blob_index >= 255) break; - } - - // draw output image - if (draw_output) { - frame.setTo(Scalar(255,0,0), frame_bin); - } - - 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 + +using namespace cv; +using namespace std; + +// ---------------------------------------------------------------------------- +const vector& PointExtractor::extract_points(Mat frame, float dt, bool draw_output) +{ + const int W = frame.cols; + const int H = frame.rows; + + // clear old points + points.clear(); + + // convert to grayscale + Mat frame_grey; + cvtColor(frame, frame_grey, COLOR_BGR2GRAY); + + // convert to binary + Mat frame_bin; + threshold(frame_grey, frame_bin, threshold_val, 255, THRESH_BINARY); + + unsigned int region_size_min = 3.14*min_size*min_size; + unsigned int region_size_max = 3.14*max_size*max_size; + + int blob_index = 1; + for (int y=0; y(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(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(i,j) != blob_index-1) continue; + float val = frame_grey.at(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) + 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; + points.push_back(c); + + if (blob_index >= 255) break; + } + if (blob_index >= 255) break; + } + + // draw output image + if (draw_output) { + frame.setTo(Scalar(255,0,0), frame_bin); + } + + return points; +} diff --git a/ftnoir_tracker_pt/point_extractor.h b/ftnoir_tracker_pt/point_extractor.h index b142d2bb..9a6f7f2c 100644 --- a/ftnoir_tracker_pt/point_extractor.h +++ b/ftnoir_tracker_pt/point_extractor.h @@ -1,31 +1,31 @@ -/* 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 - -// ---------------------------------------------------------------------------- -// 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& extract_points(cv::Mat frame, float dt, bool draw_output); - const std::vector& get_points() { return points; } - - int threshold_val; - int min_size, max_size; - -protected: - std::vector points; -}; - -#endif //POINTEXTRACTOR_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 POINTEXTRACTOR_H +#define POINTEXTRACTOR_H + +#include + +// ---------------------------------------------------------------------------- +// 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& extract_points(cv::Mat frame, float dt, bool draw_output); + const std::vector& get_points() { return points; } + + int threshold_val; + int min_size, max_size; + +protected: + std::vector points; +}; + +#endif //POINTEXTRACTOR_H diff --git a/ftnoir_tracker_pt/point_tracker.cpp b/ftnoir_tracker_pt/point_tracker.cpp index c08d6d83..210ed2eb 100644 --- a/ftnoir_tracker_pt/point_tracker.cpp +++ b/ftnoir_tracker_pt/point_tracker.cpp @@ -1,352 +1,352 @@ -/* 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 -#include -#include - -#include - -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(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 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); -} - -static bool d_vals_sort(const pair a, const pair b) -{ - return a.first < b.first; -} - -void PointModel::get_d_order(const std::vector& points, int d_order[]) const -{ - // get sort indices with respect to d scalar product - vector< pair > d_vals; - for (int i = 0; i<(int)points.size(); ++i) - d_vals.push_back(pair(d.dot(points[i]), i)); - - sort(d_vals.begin(), d_vals.end(), d_vals_sort); - - for (int i = 0; i<(int)points.size(); ++i) - d_order[i] = d_vals[i].second; -} - - -// ---------------------------------------------------------------------------- -PointTracker::PointTracker() : dynamic_pose_resolution(true), dt_reset(1), init_phase(true), dt_valid(0), v_t(0,0,0), v_r(0,0,0) -{ - 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& 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_reset "<& 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; id_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; iM01)/Z0; - epsilon_2 = k.dot(point_model->M02)/Z0; - - // vector of scalar products and - 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: "< +#include +#include + +#include + +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(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 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); +} + +static bool d_vals_sort(const pair a, const pair b) +{ + return a.first < b.first; +} + +void PointModel::get_d_order(const std::vector& points, int d_order[]) const +{ + // get sort indices with respect to d scalar product + vector< pair > d_vals; + for (int i = 0; i<(int)points.size(); ++i) + d_vals.push_back(pair(d.dot(points[i]), i)); + + sort(d_vals.begin(), d_vals.end(), d_vals_sort); + + for (int i = 0; i<(int)points.size(); ++i) + d_order[i] = d_vals[i].second; +} + + +// ---------------------------------------------------------------------------- +PointTracker::PointTracker() : dynamic_pose_resolution(true), dt_reset(1), init_phase(true), dt_valid(0), v_t(0,0,0), v_r(0,0,0) +{ + 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& 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_reset "<& 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; id_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; iM01)/Z0; + epsilon_2 = k.dot(point_model->M02)/Z0; + + // vector of scalar products and + 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: "< -#include -#include - -// ---------------------------------------------------------------------------- -// Afine 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 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; // discrimant 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& 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& points, float f, float dt); - std::auto_ptr 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& 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 +/* 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 +#include +#include + +// ---------------------------------------------------------------------------- +// Afine 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 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; // discrimant 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& 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& points, float f, float dt); + std::auto_ptr 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& 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 diff --git a/ftnoir_tracker_pt/resource.h b/ftnoir_tracker_pt/resource.h index c14e94ad..4ca527a3 100644 --- a/ftnoir_tracker_pt/resource.h +++ b/ftnoir_tracker_pt/resource.h @@ -1,14 +1,14 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by FTNoIR_Tracker_PT.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FTNoIR_Tracker_PT.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/ftnoir_tracker_pt/timer.cpp b/ftnoir_tracker_pt/timer.cpp index 9e6ca8b8..07379853 100644 --- a/ftnoir_tracker_pt/timer.cpp +++ b/ftnoir_tracker_pt/timer.cpp @@ -1,65 +1,65 @@ -/* 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 "timer.h" - -#include - -// ---------------------------------------------------------------------------- -Timer::Timer() -: startTime(0), endTime(0), running(false) -{ -#ifdef WIN32 - QueryPerformanceFrequency(&frequency); - startCount.QuadPart = 0; - endCount.QuadPart = 0; -#else - startCount.tv_sec = startCount.tv_usec = 0; - endCount.tv_sec = endCount.tv_usec = 0; -#endif -} - - -void Timer::start() -{ -#ifdef WIN32 - QueryPerformanceCounter(&startCount); -#else - gettimeofday(&startCount, NULL); -#endif - running = true; -} - - -void Timer::stop() -{ -#ifdef WIN32 - QueryPerformanceCounter(&endCount); -#else - gettimeofday(&endCount, NULL); -#endif - running = false; -} - - -double Timer::elapsed() -{ -#ifdef WIN32 - if (running) - QueryPerformanceCounter(&endCount); - - startTime = startCount.QuadPart * (1e3 / frequency.QuadPart); - endTime = endCount.QuadPart * (1e3 / frequency.QuadPart); -#else - (void) gettimeofday(&endCount, NULL); - - startTime = (startCount.tv_sec * 1e3) + startCount.tv_usec; - endTime = (endCount.tv_sec * 1e3) + endCount.tv_usec; -#endif - - return endTime - startTime; +/* 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 "timer.h" + +#include + +// ---------------------------------------------------------------------------- +Timer::Timer() +: startTime(0), endTime(0), running(false) +{ +#ifdef WIN32 + QueryPerformanceFrequency(&frequency); + startCount.QuadPart = 0; + endCount.QuadPart = 0; +#else + startCount.tv_sec = startCount.tv_usec = 0; + endCount.tv_sec = endCount.tv_usec = 0; +#endif +} + + +void Timer::start() +{ +#ifdef WIN32 + QueryPerformanceCounter(&startCount); +#else + gettimeofday(&startCount, NULL); +#endif + running = true; +} + + +void Timer::stop() +{ +#ifdef WIN32 + QueryPerformanceCounter(&endCount); +#else + gettimeofday(&endCount, NULL); +#endif + running = false; +} + + +double Timer::elapsed() +{ +#ifdef WIN32 + if (running) + QueryPerformanceCounter(&endCount); + + startTime = startCount.QuadPart * (1e3 / frequency.QuadPart); + endTime = endCount.QuadPart * (1e3 / frequency.QuadPart); +#else + (void) gettimeofday(&endCount, NULL); + + startTime = (startCount.tv_sec * 1e3) + startCount.tv_usec; + endTime = (endCount.tv_sec * 1e3) + endCount.tv_usec; +#endif + + return endTime - startTime; } \ No newline at end of file diff --git a/ftnoir_tracker_pt/timer.h b/ftnoir_tracker_pt/timer.h index 2aaf725a..1c2c3559 100644 --- a/ftnoir_tracker_pt/timer.h +++ b/ftnoir_tracker_pt/timer.h @@ -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. - */ - -#ifndef PT_TIMER_H -#define PT_TIMER_H - -#ifdef WIN32 // Windows system specific -#include -#else // Unix based system specific -#include -#endif - -// ---------------------------------------------------------------------------- -// high resolution timer based on http://www.songho.ca/misc/timer/timer.html -class Timer -{ -public: - Timer(); - - void start(); - void stop(); - void restart() { start(); } // for Qt compatibility - double elapsed(); // get elapsed time in ms - -protected: - double startTime; // starting time in ms - double endTime; // ending time in ms - bool running; - -#ifdef WIN32 - LARGE_INTEGER frequency; // ticks per second - LARGE_INTEGER startCount; - LARGE_INTEGER endCount; -#else - timeval startCount; - timeval endCount; -#endif -}; - +/* 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 PT_TIMER_H +#define PT_TIMER_H + +#ifdef WIN32 // Windows system specific +#include +#else // Unix based system specific +#include +#endif + +// ---------------------------------------------------------------------------- +// high resolution timer based on http://www.songho.ca/misc/timer/timer.html +class Timer +{ +public: + Timer(); + + void start(); + void stop(); + void restart() { start(); } // for Qt compatibility + double elapsed(); // get elapsed time in ms + +protected: + double startTime; // starting time in ms + double endTime; // ending time in ms + bool running; + +#ifdef WIN32 + LARGE_INTEGER frequency; // ticks per second + LARGE_INTEGER startCount; + LARGE_INTEGER endCount; +#else + timeval startCount; + timeval endCount; +#endif +}; + #endif //PT_TIMER_H \ No newline at end of file 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 H_k_T = Matx::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 H_k_T = Matx::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 index 4024d011..6288546a 100644 --- a/ftnoir_tracker_pt/trans_calib.h +++ b/ftnoir_tracker_pt/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 - -//----------------------------------------------------------------------------- -// 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) -}; - +/* 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 + +//----------------------------------------------------------------------------- +// 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 diff --git a/ftnoir_tracker_pt/video_widget.cpp b/ftnoir_tracker_pt/video_widget.cpp index a13542ba..2b554aba 100644 --- a/ftnoir_tracker_pt/video_widget.cpp +++ b/ftnoir_tracker_pt/video_widget.cpp @@ -1,52 +1,52 @@ -/* 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 "video_widget.h" - -#include - -using namespace cv; -using namespace std; - -void VideoWidget::update_image(Mat frame, std::auto_ptr< vector >) -{ - QMutexLocker foo(&mtx); - - if (frame.channels() != 3 && frame.channels() != 1) - return; - - int width = frame.cols, height = frame.rows; - unsigned char* src = frame.data; - - QImage qframe(width, height, QImage::Format_RGB888); - if (frame.channels() == 3) - { - uchar* data = qframe.bits(); - const int pitch = qframe.bytesPerLine(); - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - const int pos = 3 * (y*width + x); - data[y * pitch + x * 3 + 0] = src[pos + 2]; - data[y * pitch + x * 3 + 1] = src[pos + 1]; - data[y * pitch + x * 3 + 2] = src[pos + 0]; - } - } else { - uchar* data = qframe.bits(); - const int pitch = qframe.bytesPerLine(); - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - const int pos = (y*width + x); - data[y * pitch + x * 3 + 0] = src[pos]; - data[y * pitch + x * 3 + 1] = src[pos]; - data[y * pitch + x * 3 + 2] = src[pos]; - } - } - qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); - pixmap = QPixmap::fromImage(qframe); -} +/* 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 "video_widget.h" + +#include + +using namespace cv; +using namespace std; + +void VideoWidget::update_image(Mat frame, std::auto_ptr< vector >) +{ + QMutexLocker foo(&mtx); + + if (frame.channels() != 3 && frame.channels() != 1) + return; + + int width = frame.cols, height = frame.rows; + unsigned char* src = frame.data; + + QImage qframe(width, height, QImage::Format_RGB888); + if (frame.channels() == 3) + { + uchar* data = qframe.bits(); + const int pitch = qframe.bytesPerLine(); + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + const int pos = 3 * (y*width + x); + data[y * pitch + x * 3 + 0] = src[pos + 2]; + data[y * pitch + x * 3 + 1] = src[pos + 1]; + data[y * pitch + x * 3 + 2] = src[pos + 0]; + } + } else { + uchar* data = qframe.bits(); + const int pitch = qframe.bytesPerLine(); + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + const int pos = (y*width + x); + data[y * pitch + x * 3 + 0] = src[pos]; + data[y * pitch + x * 3 + 1] = src[pos]; + data[y * pitch + x * 3 + 2] = src[pos]; + } + } + qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); + pixmap = QPixmap::fromImage(qframe); +} diff --git a/ftnoir_tracker_pt/video_widget.h b/ftnoir_tracker_pt/video_widget.h index 66959fde..3051919b 100644 --- a/ftnoir_tracker_pt/video_widget.h +++ b/ftnoir_tracker_pt/video_widget.h @@ -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. - */ - -#ifndef VIDEOWIDGET_H -#define VIDEOWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// ---------------------------------------------------------------------------- -class VideoWidget : public QWidget -{ - Q_OBJECT - -public: - VideoWidget(QWidget *parent) : QWidget(parent), mtx() { - } - void update_image(cv::Mat frame, std::auto_ptr< std::vector >); -protected slots: - void paintEvent( QPaintEvent* e ) { - QMutexLocker foo(&mtx); - QPainter painter(this); - painter.drawPixmap(e->rect(), pixmap, e->rect()); - } - -private: - QMutex mtx; - QPixmap pixmap; -}; - -#endif // VIDEOWIDGET_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 VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +class VideoWidget : public QWidget +{ + Q_OBJECT + +public: + VideoWidget(QWidget *parent) : QWidget(parent), mtx() { + } + void update_image(cv::Mat frame, std::auto_ptr< std::vector >); +protected slots: + void paintEvent( QPaintEvent* e ) { + QMutexLocker foo(&mtx); + QPainter painter(this); + painter.drawPixmap(e->rect(), pixmap, e->rect()); + } + +private: + QMutex mtx; + QPixmap pixmap; +}; + +#endif // VIDEOWIDGET_H diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp index 74e1d3d2..06c8b206 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp @@ -1,173 +1,173 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_sm.h" -#include -#include "facetracknoir/global-settings.h" - -FTNoIR_Tracker::FTNoIR_Tracker() : lck_shm(SM_MM_DATA, SM_MUTEX, sizeof(SMMemMap)) -{ - pMemData = (SMMemMap*) lck_shm.mem; -} - -FTNoIR_Tracker::~FTNoIR_Tracker() -{ - qDebug() << "~FTNoIR_Tracker says: cleaning up"; - - bEnableRoll = true; - bEnablePitch = true; - bEnableYaw = true; - bEnableX = true; - bEnableY = true; - bEnableZ = true; -} - -void FTNoIR_Tracker::StartTracker(QFrame *videoframe ) -{ - qDebug() << "FTNoIR_Tracker::Initialize says: Starting "; - - loadSettings(); - - if ( pMemData != NULL ) { - 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 - } - } - - // - // Start FTNoIR_FaceAPI_EXE.exe. The exe contains all faceAPI-stuff and is non-Qt... - // - // XXX TODO isolate it into separate directory - faceAPI = new QProcess(); - faceAPI->setWorkingDirectory(QCoreApplication::applicationDirPath() + "/faceapi"); - faceAPI->start("\"" + QCoreApplication::applicationDirPath() + "/faceapi/opentrack-faceapi-wrapper" + "\""); - // Show the video widget - qDebug() << "FTNoIR_Tracker::Initialize says: videoframe = " << videoframe; - - if (videoframe != NULL) { - videoframe->show(); - } - if ( pMemData != NULL ) { - pMemData->command = FT_SM_START; // Start command - } -} - -void FTNoIR_Tracker::WaitForExit() -{ - - qDebug() << "FTNoIR_Tracker::StopTracker says: Starting "; - // stops the faceapi engine - if ( pMemData != NULL ) { -// if (exit == true) { - pMemData->command = FT_SM_EXIT; - //} - //else { - // pMemData->command = FT_SM_STOP; // Issue 'stop' command - //} - } -} - -bool FTNoIR_Tracker::GiveHeadPoseData(double *data) -{ - // - // Check if the pointer is OK and wait for the Mutex. - // - lck_shm.lock(); - - // - // Copy the measurements to FaceTrackNoIR. - // - if (bEnableX) { - data[TX] = pMemData->data.new_pose.head_pos.x * 100.0f; // From meters to centimeters - } - if (bEnableY) { - data[TY] = pMemData->data.new_pose.head_pos.y * 100.0f; - } - if (bEnableZ) { - data[TZ] = pMemData->data.new_pose.head_pos.z * 100.0f; - } - if (bEnableYaw) { - data[Yaw] = pMemData->data.new_pose.head_rot.y_rads * 57.295781f; // From rads to degrees - } - if (bEnablePitch) { - data[Pitch] = pMemData->data.new_pose.head_rot.x_rads * 57.295781f; - } - if (bEnableRoll) { - data[Roll] = pMemData->data.new_pose.head_rot.z_rads * 57.295781f; - } - - // - // Reset the handshake, to let faceAPI know we're still here! - // - pMemData->handshake = 0; - lck_shm.unlock(); - - return ( pMemData->data.new_pose.confidence > 0 ); -} - -// -// 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) - - qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "SMTracker" ); - if (pMemData) { - pMemData->initial_filter_level = iniFile.value ( "FilterLevel", 1 ).toInt(); - } - - bEnableRoll = iniFile.value ( "EnableRoll", 1 ).toBool(); - bEnablePitch = iniFile.value ( "EnablePitch", 1 ).toBool(); - bEnableYaw = iniFile.value ( "EnableYaw", 1 ).toBool(); - bEnableX = iniFile.value ( "EnableX", 1 ).toBool(); - bEnableY = iniFile.value ( "EnableY", 1 ).toBool(); - bEnableZ = iniFile.value ( "EnableZ", 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; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_sm.h" +#include +#include "facetracknoir/global-settings.h" + +FTNoIR_Tracker::FTNoIR_Tracker() : lck_shm(SM_MM_DATA, SM_MUTEX, sizeof(SMMemMap)) +{ + pMemData = (SMMemMap*) lck_shm.mem; +} + +FTNoIR_Tracker::~FTNoIR_Tracker() +{ + qDebug() << "~FTNoIR_Tracker says: cleaning up"; + + bEnableRoll = true; + bEnablePitch = true; + bEnableYaw = true; + bEnableX = true; + bEnableY = true; + bEnableZ = true; +} + +void FTNoIR_Tracker::StartTracker(QFrame *videoframe ) +{ + qDebug() << "FTNoIR_Tracker::Initialize says: Starting "; + + loadSettings(); + + if ( pMemData != NULL ) { + 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 + } + } + + // + // Start FTNoIR_FaceAPI_EXE.exe. The exe contains all faceAPI-stuff and is non-Qt... + // + // XXX TODO isolate it into separate directory + faceAPI = new QProcess(); + faceAPI->setWorkingDirectory(QCoreApplication::applicationDirPath() + "/faceapi"); + faceAPI->start("\"" + QCoreApplication::applicationDirPath() + "/faceapi/opentrack-faceapi-wrapper" + "\""); + // Show the video widget + qDebug() << "FTNoIR_Tracker::Initialize says: videoframe = " << videoframe; + + if (videoframe != NULL) { + videoframe->show(); + } + if ( pMemData != NULL ) { + pMemData->command = FT_SM_START; // Start command + } +} + +void FTNoIR_Tracker::WaitForExit() +{ + + qDebug() << "FTNoIR_Tracker::StopTracker says: Starting "; + // stops the faceapi engine + if ( pMemData != NULL ) { +// if (exit == true) { + pMemData->command = FT_SM_EXIT; + //} + //else { + // pMemData->command = FT_SM_STOP; // Issue 'stop' command + //} + } +} + +bool FTNoIR_Tracker::GiveHeadPoseData(double *data) +{ + // + // Check if the pointer is OK and wait for the Mutex. + // + lck_shm.lock(); + + // + // Copy the measurements to FaceTrackNoIR. + // + if (bEnableX) { + data[TX] = pMemData->data.new_pose.head_pos.x * 100.0f; // From meters to centimeters + } + if (bEnableY) { + data[TY] = pMemData->data.new_pose.head_pos.y * 100.0f; + } + if (bEnableZ) { + data[TZ] = pMemData->data.new_pose.head_pos.z * 100.0f; + } + if (bEnableYaw) { + data[Yaw] = pMemData->data.new_pose.head_rot.y_rads * 57.295781f; // From rads to degrees + } + if (bEnablePitch) { + data[Pitch] = pMemData->data.new_pose.head_rot.x_rads * 57.295781f; + } + if (bEnableRoll) { + data[Roll] = pMemData->data.new_pose.head_rot.z_rads * 57.295781f; + } + + // + // Reset the handshake, to let faceAPI know we're still here! + // + pMemData->handshake = 0; + lck_shm.unlock(); + + return ( pMemData->data.new_pose.confidence > 0 ); +} + +// +// 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) + + qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "SMTracker" ); + if (pMemData) { + pMemData->initial_filter_level = iniFile.value ( "FilterLevel", 1 ).toInt(); + } + + bEnableRoll = iniFile.value ( "EnableRoll", 1 ).toBool(); + bEnablePitch = iniFile.value ( "EnablePitch", 1 ).toBool(); + bEnableYaw = iniFile.value ( "EnableYaw", 1 ).toBool(); + bEnableX = iniFile.value ( "EnableX", 1 ).toBool(); + bEnableY = iniFile.value ( "EnableY", 1 ).toBool(); + bEnableZ = iniFile.value ( "EnableZ", 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; +} diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp index f515dedc..332a619e 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp @@ -1,282 +1,282 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_sm.h" -#include -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// faceAPI Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -TrackerControls::TrackerControls() : - QWidget(), - shm(SM_MM_DATA, SM_MUTEX, sizeof(TFaceData)) -{ - pMemData = (SMMemMap*) shm.mem; - - ui.setupUi( this ); - - theTracker = NULL; - prev_state = -1; - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.btnEngineStart, SIGNAL(clicked()), this, SLOT(doStartEngine())); - connect(ui.btnEngineStop, SIGNAL(clicked()), this, SLOT(doStopEngine())); - connect(ui.btnSave, SIGNAL(clicked()), this, SLOT(save())); - - ui.cbxFilterSetting->addItem("None"); - ui.cbxFilterSetting->addItem("Normal"); - ui.cbxFilterSetting->addItem("High"); - connect(ui.cbxFilterSetting, SIGNAL(currentIndexChanged(int)), this, SLOT(doSetFilter( int ))); - connect(ui.btnCameraSettings, SIGNAL(clicked()), this, SLOT(doShowCam())); - - //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.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))); -} - -// -// Destructor for server-dialog -// -TrackerControls::~TrackerControls() { - qDebug() << "~TrackerControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void TrackerControls::Initialize(QWidget *parent) { - - QPoint offsetpos(200, 200); - if (parent) { - this->move(parent->pos() + offsetpos); - } - - // Load the settings from the current .INI-file - loadSettings(); - - show(); -} - -// -// OK clicked on server-dialog -// -void TrackerControls::doOK() { - save(); - this->close(); -} - -// override show event -void TrackerControls::showEvent ( QShowEvent * event ) { - prev_state = -1; - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void TrackerControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - -// -// Load the current Settings from the currently 'active' INI-file. -// -void TrackerControls::loadSettings() { - -// qDebug() << "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) - -// qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "SMTracker" ); - ui.cbxFilterSetting->setCurrentIndex(iniFile.value ( "FilterLevel", 1 ).toInt()); - - ui.chkEnableRoll->setChecked(iniFile.value ( "EnableRoll", 1 ).toBool()); - ui.chkEnablePitch->setChecked(iniFile.value ( "EnablePitch", 1 ).toBool()); - ui.chkEnableYaw->setChecked(iniFile.value ( "EnableYaw", 1 ).toBool()); - ui.chkEnableX->setChecked(iniFile.value ( "EnableX", 1 ).toBool()); - ui.chkEnableY->setChecked(iniFile.value ( "EnableY", 1 ).toBool()); - ui.chkEnableZ->setChecked(iniFile.value ( "EnableZ", 1 ).toBool()); - - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void TrackerControls::save() { - - 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 ( "SMTracker" ); - iniFile.setValue ( "FilterLevel", ui.cbxFilterSetting->currentIndex() ); - - iniFile.setValue ( "EnableRoll", ui.chkEnableRoll->isChecked() ); - iniFile.setValue ( "EnablePitch", ui.chkEnablePitch->isChecked() ); - iniFile.setValue ( "EnableYaw", ui.chkEnableYaw->isChecked() ); - iniFile.setValue ( "EnableX", ui.chkEnableX->isChecked() ); - iniFile.setValue ( "EnableY", ui.chkEnableY->isChecked() ); - iniFile.setValue ( "EnableZ", ui.chkEnableZ->isChecked() ); - - iniFile.endGroup (); - - // - // If the Tracker is active, let it load the new Settings. - // - if (theTracker) { - theTracker->loadSettings(); - } - - settingsDirty = false; -} - -// Show the current engine-settings etc. -// -void TrackerControls::doTimUpdate() -{ - int state = pMemData->state; - if ( state != prev_state) { - emit stateChanged(state); - prev_state = state; - } -} - -// -// Show the current engine-settings etc. -// -void TrackerControls::showSettings( int newState ) -{ - qDebug() << "TrackerControls::showSettings says: Starting Function"; - switch (newState) - { - case SM_API_ENGINE_STATE_TERMINATED: - ui._engine_state_label->setText("TERMINATED"); - break; - case SM_API_ENGINE_STATE_INVALID: - ui._engine_state_label->setText("INVALID"); - break; - case SM_API_ENGINE_STATE_IDLE: - ui._engine_state_label->setText("IDLE"); - break; - case SM_API_ENGINE_STATE_HT_INITIALIZING: - ui._engine_state_label->setText("INITIALIZING"); - break; - case SM_API_ENGINE_STATE_HT_TRACKING: - ui._engine_state_label->setText("TRACKING"); - break; - case SM_API_ENGINE_STATE_HT_SEARCHING: - ui._engine_state_label->setText("SEARCHING"); - break; - default: - ui._engine_state_label->setText("Unknown State!"); - break; - } - - ui.cbxFilterSetting->setEnabled( (newState == SM_API_ENGINE_STATE_IDLE) ); -} - -// -// Send a command without parameter-value to the tracking Engine. -// -void TrackerControls::doCommand(int command) -{ - shm.lock(); - pMemData->command = command; - shm.unlock(); -} - -// -// Send a command with integer parameter-value to the tracking Engine. -// -void TrackerControls::doCommand(int command, int value) -{ - shm.lock(); - pMemData->command = command; // Send command - pMemData->par_val_int = value; - shm.unlock(); -} - -//////////////////////////////////////////////////////////////////////////////// -// 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() -{ - return new TrackerControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_sm.h" +#include +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// faceAPI Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +TrackerControls::TrackerControls() : + QWidget(), + shm(SM_MM_DATA, SM_MUTEX, sizeof(TFaceData)) +{ + pMemData = (SMMemMap*) shm.mem; + + ui.setupUi( this ); + + theTracker = NULL; + prev_state = -1; + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.btnEngineStart, SIGNAL(clicked()), this, SLOT(doStartEngine())); + connect(ui.btnEngineStop, SIGNAL(clicked()), this, SLOT(doStopEngine())); + connect(ui.btnSave, SIGNAL(clicked()), this, SLOT(save())); + + ui.cbxFilterSetting->addItem("None"); + ui.cbxFilterSetting->addItem("Normal"); + ui.cbxFilterSetting->addItem("High"); + connect(ui.cbxFilterSetting, SIGNAL(currentIndexChanged(int)), this, SLOT(doSetFilter( int ))); + connect(ui.btnCameraSettings, SIGNAL(clicked()), this, SLOT(doShowCam())); + + //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.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))); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { + qDebug() << "~TrackerControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void TrackerControls::Initialize(QWidget *parent) { + + QPoint offsetpos(200, 200); + if (parent) { + this->move(parent->pos() + offsetpos); + } + + // Load the settings from the current .INI-file + loadSettings(); + + show(); +} + +// +// OK clicked on server-dialog +// +void TrackerControls::doOK() { + save(); + this->close(); +} + +// override show event +void TrackerControls::showEvent ( QShowEvent * event ) { + prev_state = -1; + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void TrackerControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +// +// Load the current Settings from the currently 'active' INI-file. +// +void TrackerControls::loadSettings() { + +// qDebug() << "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) + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "SMTracker" ); + ui.cbxFilterSetting->setCurrentIndex(iniFile.value ( "FilterLevel", 1 ).toInt()); + + ui.chkEnableRoll->setChecked(iniFile.value ( "EnableRoll", 1 ).toBool()); + ui.chkEnablePitch->setChecked(iniFile.value ( "EnablePitch", 1 ).toBool()); + ui.chkEnableYaw->setChecked(iniFile.value ( "EnableYaw", 1 ).toBool()); + ui.chkEnableX->setChecked(iniFile.value ( "EnableX", 1 ).toBool()); + ui.chkEnableY->setChecked(iniFile.value ( "EnableY", 1 ).toBool()); + ui.chkEnableZ->setChecked(iniFile.value ( "EnableZ", 1 ).toBool()); + + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void TrackerControls::save() { + + 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 ( "SMTracker" ); + iniFile.setValue ( "FilterLevel", ui.cbxFilterSetting->currentIndex() ); + + iniFile.setValue ( "EnableRoll", ui.chkEnableRoll->isChecked() ); + iniFile.setValue ( "EnablePitch", ui.chkEnablePitch->isChecked() ); + iniFile.setValue ( "EnableYaw", ui.chkEnableYaw->isChecked() ); + iniFile.setValue ( "EnableX", ui.chkEnableX->isChecked() ); + iniFile.setValue ( "EnableY", ui.chkEnableY->isChecked() ); + iniFile.setValue ( "EnableZ", ui.chkEnableZ->isChecked() ); + + iniFile.endGroup (); + + // + // If the Tracker is active, let it load the new Settings. + // + if (theTracker) { + theTracker->loadSettings(); + } + + settingsDirty = false; +} + +// Show the current engine-settings etc. +// +void TrackerControls::doTimUpdate() +{ + int state = pMemData->state; + if ( state != prev_state) { + emit stateChanged(state); + prev_state = state; + } +} + +// +// Show the current engine-settings etc. +// +void TrackerControls::showSettings( int newState ) +{ + qDebug() << "TrackerControls::showSettings says: Starting Function"; + switch (newState) + { + case SM_API_ENGINE_STATE_TERMINATED: + ui._engine_state_label->setText("TERMINATED"); + break; + case SM_API_ENGINE_STATE_INVALID: + ui._engine_state_label->setText("INVALID"); + break; + case SM_API_ENGINE_STATE_IDLE: + ui._engine_state_label->setText("IDLE"); + break; + case SM_API_ENGINE_STATE_HT_INITIALIZING: + ui._engine_state_label->setText("INITIALIZING"); + break; + case SM_API_ENGINE_STATE_HT_TRACKING: + ui._engine_state_label->setText("TRACKING"); + break; + case SM_API_ENGINE_STATE_HT_SEARCHING: + ui._engine_state_label->setText("SEARCHING"); + break; + default: + ui._engine_state_label->setText("Unknown State!"); + break; + } + + ui.cbxFilterSetting->setEnabled( (newState == SM_API_ENGINE_STATE_IDLE) ); +} + +// +// Send a command without parameter-value to the tracking Engine. +// +void TrackerControls::doCommand(int command) +{ + shm.lock(); + pMemData->command = command; + shm.unlock(); +} + +// +// Send a command with integer parameter-value to the tracking Engine. +// +void TrackerControls::doCommand(int command, int value) +{ + shm.lock(); + pMemData->command = command; // Send command + pMemData->par_val_int = value; + shm.unlock(); +} + +//////////////////////////////////////////////////////////////////////////////// +// 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() +{ + return new TrackerControls; +} diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp index a878a468..b1ab1d75 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dll.cpp @@ -1,72 +1,72 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_sm.h" -#include -#include "facetracknoir/global-settings.h" - -FTNoIR_TrackerDll::FTNoIR_TrackerDll() { - //populate the description strings - trackerFullName = "faceAPI V3.2.6"; - trackerShortName = "faceAPI"; - trackerDescription = "SeeingMachines faceAPI V3.2.6"; -} - -FTNoIR_TrackerDll::~FTNoIR_TrackerDll() -{ - -} -void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) -{ - *strToBeFilled = trackerFullName; -}; - -void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) -{ - *strToBeFilled = trackerShortName; -}; - -void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) -{ - *strToBeFilled = trackerDescription; -}; - -void FTNoIR_TrackerDll::getIcon(QIcon *icon) -{ - *icon = QIcon(":/images/sm.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() -{ - return new FTNoIR_TrackerDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_sm.h" +#include +#include "facetracknoir/global-settings.h" + +FTNoIR_TrackerDll::FTNoIR_TrackerDll() { + //populate the description strings + trackerFullName = "faceAPI V3.2.6"; + trackerShortName = "faceAPI"; + trackerDescription = "SeeingMachines faceAPI V3.2.6"; +} + +FTNoIR_TrackerDll::~FTNoIR_TrackerDll() +{ + +} +void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +}; + +void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +}; + +void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +}; + +void FTNoIR_TrackerDll::getIcon(QIcon *icon) +{ + *icon = QIcon(":/images/sm.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() +{ + return new FTNoIR_TrackerDll; +} diff --git a/ftnoir_tracker_sm/ftnoir_tracker_sm.h b/ftnoir_tracker_sm/ftnoir_tracker_sm.h index 33cfb9ef..5d692ea0 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_sm.h +++ b/ftnoir_tracker_sm/ftnoir_tracker_sm.h @@ -1,156 +1,156 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" -#include "..\ftnoir_tracker_base\ftnoir_tracker_sm_types.h" -#include "ui_FTNoIR_SM_controls.h" - -#include -#include -#include -#include "Windows.h" -#include "math.h" -#include "facetracknoir/global-settings.h" -#include "compat/compat.h" -#include - -using namespace std; - -class FTNoIR_Tracker : public ITracker -{ -public: - FTNoIR_Tracker(); - ~FTNoIR_Tracker(); - - void StartTracker( QFrame* parent_window ); - void StopTracker( bool exit ); - bool GiveHeadPoseData(double *data); // Returns true if confidence is good - void WaitForExit(); - - void loadSettings(); - -private: - // - // global variables - // - PortableLockedShm lck_shm; - SMMemMap *pMemData; - QProcess *faceAPI; - - bool bEnableRoll; - bool bEnablePitch; - bool bEnableYaw; - bool bEnableX; - bool bEnableY; - bool bEnableZ; -}; - -// Widget that has controls for SMoIR protocol client-settings. -class TrackerControls: public QWidget, public ITrackerDialog -{ - Q_OBJECT -public: - - explicit TrackerControls(); - virtual ~TrackerControls(); - void showEvent ( QShowEvent * event ); - - void Initialize(QWidget *parent); - 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; - void loadSettings(); - void doCommand( int command ); - void doCommand( int command, int value ); - - /** helper **/ - bool settingsDirty; - int prev_state; // Previous engine state - - // - // global variables - // - SMMemMap *pMemData; - - smEngineHandle *engine_handle; - QTimer *timUpdateSettings; // Timer to display current settings - - FTNoIR_Tracker *theTracker; - PortableLockedShm shm; - -private slots: - void doOK(); - void doCancel(); - void save(); - void settingChanged() { settingsDirty = true; } - void doTimUpdate(); - void showSettings( int newState ); - void doStartEngine(){ - doCommand(FT_SM_START); - } - void doStopEngine(){ - doCommand(FT_SM_STOP); - } - void doShowCam(){ - doCommand(FT_SM_SHOW_CAM); - } - void doSetFilter(int value){ - doCommand(FT_SM_SET_PAR_FILTER, value); - } - void settingChanged(int dummy) { - settingsDirty = true; - } - -signals: - void stateChanged(int newState); - -}; - -//******************************************************************************************************* -// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker -//******************************************************************************************************* -class FTNoIR_TrackerDll : public Metadata -{ -public: - FTNoIR_TrackerDll(); - ~FTNoIR_TrackerDll(); - - void Initialize(); - - 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; -}; +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "..\ftnoir_tracker_base\ftnoir_tracker_sm_types.h" +#include "ui_FTNoIR_SM_controls.h" + +#include +#include +#include +#include "Windows.h" +#include "math.h" +#include "facetracknoir/global-settings.h" +#include "compat/compat.h" +#include + +using namespace std; + +class FTNoIR_Tracker : public ITracker +{ +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + + void StartTracker( QFrame* parent_window ); + void StopTracker( bool exit ); + bool GiveHeadPoseData(double *data); // Returns true if confidence is good + void WaitForExit(); + + void loadSettings(); + +private: + // + // global variables + // + PortableLockedShm lck_shm; + SMMemMap *pMemData; + QProcess *faceAPI; + + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; +}; + +// Widget that has controls for SMoIR protocol client-settings. +class TrackerControls: public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + + explicit TrackerControls(); + virtual ~TrackerControls(); + void showEvent ( QShowEvent * event ); + + void Initialize(QWidget *parent); + 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; + void loadSettings(); + void doCommand( int command ); + void doCommand( int command, int value ); + + /** helper **/ + bool settingsDirty; + int prev_state; // Previous engine state + + // + // global variables + // + SMMemMap *pMemData; + + smEngineHandle *engine_handle; + QTimer *timUpdateSettings; // Timer to display current settings + + FTNoIR_Tracker *theTracker; + PortableLockedShm shm; + +private slots: + void doOK(); + void doCancel(); + void save(); + void settingChanged() { settingsDirty = true; } + void doTimUpdate(); + void showSettings( int newState ); + void doStartEngine(){ + doCommand(FT_SM_START); + } + void doStopEngine(){ + doCommand(FT_SM_STOP); + } + void doShowCam(){ + doCommand(FT_SM_SHOW_CAM); + } + void doSetFilter(int value){ + doCommand(FT_SM_SET_PAR_FILTER, value); + } + void settingChanged(int dummy) { + settingsDirty = true; + } + +signals: + void stateChanged(int newState); + +}; + +//******************************************************************************************************* +// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker +//******************************************************************************************************* +class FTNoIR_TrackerDll : public Metadata +{ +public: + FTNoIR_TrackerDll(); + ~FTNoIR_TrackerDll(); + + void Initialize(); + + 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; +}; diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp index 83f518fa..1364ee1c 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp @@ -1,173 +1,173 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_udp.h" -#include "facetracknoir/global-settings.h" - -FTNoIR_Tracker::FTNoIR_Tracker() -{ - inSocket = 0; - outSocket = 0; - - bEnableRoll = true; - bEnablePitch = true; - bEnableYaw = true; - bEnableX = true; - bEnableY = true; - bEnableZ = true; - portAddress = 5551; - should_quit = false; - - for (int i = 0; i < 6; i++) - newHeadPose[i] = 0; -} - -FTNoIR_Tracker::~FTNoIR_Tracker() -{ - if (inSocket) { - inSocket->close(); - delete inSocket; - } - - if (outSocket) { - outSocket->close(); - delete outSocket; - } -} - -/** QThread run @override **/ -void FTNoIR_Tracker::run() { - -QHostAddress sender; -quint16 senderPort; - - // - // Read the data that was received. - // - forever { - if (should_quit) - break; - if (inSocket != 0) { - while (inSocket->hasPendingDatagrams()) { - - QByteArray datagram; - datagram.resize(inSocket->pendingDatagramSize()); - mutex.lock(); - inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort); - mutex.unlock(); - } - } - else { - break; - } - - usleep(10000); - } -} - -void FTNoIR_Tracker::StartTracker(QFrame* videoFrame) -{ - loadSettings(); - // - // Create UDP-sockets if they don't exist already. - // They must be created here, because they must be in the new thread (FTNoIR_Tracker::run()) - // - if (inSocket == 0) { - qDebug() << "FTNoIR_Tracker::Initialize() creating insocket"; - inSocket = new QUdpSocket(); - // Connect the inSocket to the port, to receive messages - - if (!inSocket->bind(QHostAddress::Any, (int) portAddress, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) { - QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton); - delete inSocket; - inSocket = 0; - } - } - start(); - return; -} - -bool FTNoIR_Tracker::GiveHeadPoseData(double *data) -{ - mutex.lock(); - if (bEnableX) { - data[TX] = newHeadPose[TX]; - } - if (bEnableX) { - data[TY] = newHeadPose[TY]; - } - if (bEnableX) { - data[TZ] = newHeadPose[TZ]; - } - if (bEnableYaw) { - data[Yaw] = newHeadPose[Yaw]; - } - if (bEnablePitch) { - data[Pitch] = newHeadPose[Pitch]; - } - if (bEnableRoll) { - data[Roll] = newHeadPose[Roll]; - } - mutex.unlock(); - return true; -} - -// -// 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) - - qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FTNClient" ); - bEnableRoll = iniFile.value ( "EnableRoll", 1 ).toBool(); - bEnablePitch = iniFile.value ( "EnablePitch", 1 ).toBool(); - bEnableYaw = iniFile.value ( "EnableYaw", 1 ).toBool(); - bEnableX = iniFile.value ( "EnableX", 1 ).toBool(); - bEnableY = iniFile.value ( "EnableY", 1 ).toBool(); - bEnableZ = iniFile.value ( "EnableZ", 1 ).toBool(); - portAddress = (float) iniFile.value ( "PortNumber", 5550 ).toInt(); - 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; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_udp.h" +#include "facetracknoir/global-settings.h" + +FTNoIR_Tracker::FTNoIR_Tracker() +{ + inSocket = 0; + outSocket = 0; + + bEnableRoll = true; + bEnablePitch = true; + bEnableYaw = true; + bEnableX = true; + bEnableY = true; + bEnableZ = true; + portAddress = 5551; + should_quit = false; + + for (int i = 0; i < 6; i++) + newHeadPose[i] = 0; +} + +FTNoIR_Tracker::~FTNoIR_Tracker() +{ + if (inSocket) { + inSocket->close(); + delete inSocket; + } + + if (outSocket) { + outSocket->close(); + delete outSocket; + } +} + +/** QThread run @override **/ +void FTNoIR_Tracker::run() { + +QHostAddress sender; +quint16 senderPort; + + // + // Read the data that was received. + // + forever { + if (should_quit) + break; + if (inSocket != 0) { + while (inSocket->hasPendingDatagrams()) { + + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + mutex.lock(); + inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort); + mutex.unlock(); + } + } + else { + break; + } + + usleep(10000); + } +} + +void FTNoIR_Tracker::StartTracker(QFrame* videoFrame) +{ + loadSettings(); + // + // Create UDP-sockets if they don't exist already. + // They must be created here, because they must be in the new thread (FTNoIR_Tracker::run()) + // + if (inSocket == 0) { + qDebug() << "FTNoIR_Tracker::Initialize() creating insocket"; + inSocket = new QUdpSocket(); + // Connect the inSocket to the port, to receive messages + + if (!inSocket->bind(QHostAddress::Any, (int) portAddress, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) { + QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to bind UDP-port",QMessageBox::Ok,QMessageBox::NoButton); + delete inSocket; + inSocket = 0; + } + } + start(); + return; +} + +bool FTNoIR_Tracker::GiveHeadPoseData(double *data) +{ + mutex.lock(); + if (bEnableX) { + data[TX] = newHeadPose[TX]; + } + if (bEnableX) { + data[TY] = newHeadPose[TY]; + } + if (bEnableX) { + data[TZ] = newHeadPose[TZ]; + } + if (bEnableYaw) { + data[Yaw] = newHeadPose[Yaw]; + } + if (bEnablePitch) { + data[Pitch] = newHeadPose[Pitch]; + } + if (bEnableRoll) { + data[Roll] = newHeadPose[Roll]; + } + mutex.unlock(); + return true; +} + +// +// 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) + + qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FTNClient" ); + bEnableRoll = iniFile.value ( "EnableRoll", 1 ).toBool(); + bEnablePitch = iniFile.value ( "EnablePitch", 1 ).toBool(); + bEnableYaw = iniFile.value ( "EnableYaw", 1 ).toBool(); + bEnableX = iniFile.value ( "EnableX", 1 ).toBool(); + bEnableY = iniFile.value ( "EnableY", 1 ).toBool(); + bEnableZ = iniFile.value ( "EnableZ", 1 ).toBool(); + portAddress = (float) iniFile.value ( "PortNumber", 5550 ).toInt(); + 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; +} diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.h b/ftnoir_tracker_udp/ftnoir_tracker_udp.h index c4c85372..76fcacf2 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.h +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.h @@ -1,97 +1,97 @@ -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ui_ftnoir_ftnclientcontrols.h" -#include -#include -#include -#include -#include -#include -#include -#include "facetracknoir/global-settings.h" - -class FTNoIR_Tracker : public ITracker, public QThread -{ -public: - FTNoIR_Tracker(); - ~FTNoIR_Tracker(); - - void StartTracker( QFrame *videoframe ); - bool GiveHeadPoseData(double *data); - void loadSettings(); - volatile bool should_quit; - void WaitForExit() { - should_quit = true; - wait(); - } - -protected: - void run(); // qthread override run method - -private: - // UDP socket-variables - QUdpSocket *inSocket; // Receive from ... - QUdpSocket *outSocket; // Send to ... - QHostAddress destIP; // Destination IP-address - QHostAddress srcIP; // Source IP-address - - double newHeadPose[6]; // Structure with new headpose - - float portAddress; // Port-number - bool bEnableRoll; - bool bEnablePitch; - bool bEnableYaw; - bool bEnableX; - bool bEnableY; - bool bEnableZ; - QMutex mutex; -}; - -// Widget that has controls for FTNoIR protocol client-settings. -class TrackerControls: public QWidget, public ITrackerDialog -{ - Q_OBJECT -public: - - explicit TrackerControls(); - ~TrackerControls(); - void showEvent ( QShowEvent * event ); - - void Initialize(QWidget *parent); - void registerTracker(ITracker *tracker) {}; - void unRegisterTracker() {}; - -private: - Ui::UICFTNClientControls ui; - void loadSettings(); - void save(); - - /** helper **/ - bool settingsDirty; - -private slots: - void doOK(); - void doCancel(); - void settingChanged() { settingsDirty = true; }; - void settingChanged(int) { settingsDirty = true; }; -}; - -//******************************************************************************************************* -// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker -//******************************************************************************************************* -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); - -private: - QString trackerFullName; // Trackers' name and description - QString trackerShortName; - QString trackerDescription; -}; - +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" +#include "ui_ftnoir_ftnclientcontrols.h" +#include +#include +#include +#include +#include +#include +#include +#include "facetracknoir/global-settings.h" + +class FTNoIR_Tracker : public ITracker, public QThread +{ +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + + void StartTracker( QFrame *videoframe ); + bool GiveHeadPoseData(double *data); + void loadSettings(); + volatile bool should_quit; + void WaitForExit() { + should_quit = true; + wait(); + } + +protected: + void run(); // qthread override run method + +private: + // UDP socket-variables + QUdpSocket *inSocket; // Receive from ... + QUdpSocket *outSocket; // Send to ... + QHostAddress destIP; // Destination IP-address + QHostAddress srcIP; // Source IP-address + + double newHeadPose[6]; // Structure with new headpose + + float portAddress; // Port-number + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; + QMutex mutex; +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class TrackerControls: public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + + explicit TrackerControls(); + ~TrackerControls(); + void showEvent ( QShowEvent * event ); + + void Initialize(QWidget *parent); + void registerTracker(ITracker *tracker) {}; + void unRegisterTracker() {}; + +private: + Ui::UICFTNClientControls ui; + void loadSettings(); + void save(); + + /** helper **/ + bool settingsDirty; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; }; + void settingChanged(int) { settingsDirty = true; }; +}; + +//******************************************************************************************************* +// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker +//******************************************************************************************************* +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); + +private: + QString trackerFullName; // Trackers' name and description + QString trackerShortName; + QString trackerDescription; +}; + diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp index 4fe0d8c8..5c0d7b1c 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp @@ -1,182 +1,182 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_udp.h" -#include "facetracknoir/global-settings.h" - -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// -TrackerControls::TrackerControls() : -QWidget() -{ - ui.setupUi( this ); - - // Connect Qt signals to member-functions - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); - - 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))); - - // Load the settings from the current .INI-file - loadSettings(); -} - -// -// Destructor for server-dialog -// -TrackerControls::~TrackerControls() { - qDebug() << "~TrackerControls() says: started"; -} - -// -// Initialize tracker-client-dialog -// -void TrackerControls::Initialize(QWidget *parent) { - - QPoint offsetpos(100, 100); - if (parent) { - this->move(parent->pos() + offsetpos); - } - show(); -} - -// -// OK clicked on server-dialog -// -void TrackerControls::doOK() { - save(); - this->close(); -} - -// override show event -void TrackerControls::showEvent ( QShowEvent * event ) { - loadSettings(); -} - -// -// Cancel clicked on server-dialog -// -void TrackerControls::doCancel() { - // - // Ask if changed Settings should be saved - // - if (settingsDirty) { - int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); - - qDebug() << "doCancel says: answer =" << ret; - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } -} - - -// -// Load the current Settings from the currently 'active' INI-file. -// -void TrackerControls::loadSettings() { - -// qDebug() << "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) - -// qDebug() << "loadSettings says: iniFile = " << currentFile; - - iniFile.beginGroup ( "FTNClient" ); - ui.chkEnableRoll->setChecked(iniFile.value ( "EnableRoll", 1 ).toBool()); - ui.chkEnablePitch->setChecked(iniFile.value ( "EnablePitch", 1 ).toBool()); - ui.chkEnableYaw->setChecked(iniFile.value ( "EnableYaw", 1 ).toBool()); - ui.chkEnableX->setChecked(iniFile.value ( "EnableX", 1 ).toBool()); - ui.chkEnableY->setChecked(iniFile.value ( "EnableY", 1 ).toBool()); - ui.chkEnableZ->setChecked(iniFile.value ( "EnableZ", 1 ).toBool()); - - ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); - iniFile.endGroup (); - - settingsDirty = false; -} - -// -// Save the current Settings to the currently 'active' INI-file. -// -void TrackerControls::save() { - 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 ( "FTNClient" ); - iniFile.setValue ( "EnableRoll", ui.chkEnableRoll->isChecked() ); - iniFile.setValue ( "EnablePitch", ui.chkEnablePitch->isChecked() ); - iniFile.setValue ( "EnableYaw", ui.chkEnableYaw->isChecked() ); - iniFile.setValue ( "EnableX", ui.chkEnableX->isChecked() ); - iniFile.setValue ( "EnableY", ui.chkEnableY->isChecked() ); - iniFile.setValue ( "EnableZ", ui.chkEnableZ->isChecked() ); - iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); - iniFile.endGroup (); - - settingsDirty = false; -} -//////////////////////////////////////////////////////////////////////////////// -// 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( ) -{ - return new TrackerControls; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_udp.h" +#include "facetracknoir/global-settings.h" + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +TrackerControls::TrackerControls() : +QWidget() +{ + ui.setupUi( this ); + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.spinPortNumber, SIGNAL(valueChanged(int)), this, SLOT(settingChanged())); + + 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))); + + // Load the settings from the current .INI-file + loadSettings(); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { + qDebug() << "~TrackerControls() says: started"; +} + +// +// Initialize tracker-client-dialog +// +void TrackerControls::Initialize(QWidget *parent) { + + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void TrackerControls::doOK() { + save(); + this->close(); +} + +// override show event +void TrackerControls::showEvent ( QShowEvent * event ) { + loadSettings(); +} + +// +// Cancel clicked on server-dialog +// +void TrackerControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + qDebug() << "doCancel says: answer =" << ret; + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + + +// +// Load the current Settings from the currently 'active' INI-file. +// +void TrackerControls::loadSettings() { + +// qDebug() << "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) + +// qDebug() << "loadSettings says: iniFile = " << currentFile; + + iniFile.beginGroup ( "FTNClient" ); + ui.chkEnableRoll->setChecked(iniFile.value ( "EnableRoll", 1 ).toBool()); + ui.chkEnablePitch->setChecked(iniFile.value ( "EnablePitch", 1 ).toBool()); + ui.chkEnableYaw->setChecked(iniFile.value ( "EnableYaw", 1 ).toBool()); + ui.chkEnableX->setChecked(iniFile.value ( "EnableX", 1 ).toBool()); + ui.chkEnableY->setChecked(iniFile.value ( "EnableY", 1 ).toBool()); + ui.chkEnableZ->setChecked(iniFile.value ( "EnableZ", 1 ).toBool()); + + ui.spinPortNumber->setValue( iniFile.value ( "PortNumber", 5550 ).toInt() ); + iniFile.endGroup (); + + settingsDirty = false; +} + +// +// Save the current Settings to the currently 'active' INI-file. +// +void TrackerControls::save() { + 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 ( "FTNClient" ); + iniFile.setValue ( "EnableRoll", ui.chkEnableRoll->isChecked() ); + iniFile.setValue ( "EnablePitch", ui.chkEnablePitch->isChecked() ); + iniFile.setValue ( "EnableYaw", ui.chkEnableYaw->isChecked() ); + iniFile.setValue ( "EnableX", ui.chkEnableX->isChecked() ); + iniFile.setValue ( "EnableY", ui.chkEnableY->isChecked() ); + iniFile.setValue ( "EnableZ", ui.chkEnableZ->isChecked() ); + iniFile.setValue ( "PortNumber", ui.spinPortNumber->value() ); + iniFile.endGroup (); + + settingsDirty = false; +} +//////////////////////////////////////////////////////////////////////////////// +// 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( ) +{ + return new TrackerControls; +} diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp index d4afb410..dcdbe487 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dll.cpp @@ -1,73 +1,73 @@ -/******************************************************************************** -* 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 . * -* * -********************************************************************************/ -#include "ftnoir_tracker_udp.h" -#include -#include "facetracknoir/global-settings.h" - -FTNoIR_TrackerDll::FTNoIR_TrackerDll() { - //populate the description strings - trackerFullName = "FaceTrackNoIR UDP"; - trackerShortName = "UDP"; - trackerDescription = "FaceTrackNoIR UDP"; -} - -FTNoIR_TrackerDll::~FTNoIR_TrackerDll() -{ - -} - -void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) -{ - *strToBeFilled = trackerFullName; -} - -void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) -{ - *strToBeFilled = trackerShortName; -} - -void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) -{ - *strToBeFilled = trackerDescription; -} - -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() -{ - return new FTNoIR_TrackerDll; -} +/******************************************************************************** +* 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 . * +* * +********************************************************************************/ +#include "ftnoir_tracker_udp.h" +#include +#include "facetracknoir/global-settings.h" + +FTNoIR_TrackerDll::FTNoIR_TrackerDll() { + //populate the description strings + trackerFullName = "FaceTrackNoIR UDP"; + trackerShortName = "UDP"; + trackerDescription = "FaceTrackNoIR UDP"; +} + +FTNoIR_TrackerDll::~FTNoIR_TrackerDll() +{ + +} + +void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +} + +void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +} + +void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +} + +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() +{ + return new FTNoIR_TrackerDll; +} diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index 1b06bdc2..e0807859 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -1,282 +1,282 @@ -/* Copyright (c) 2012, 2013 StanisÅ‚aw 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 -#include -#include -#include -#include "functionconfig.h" -#include -#include -#include -#include -#include -#include - -// -// Constructor with List of Points in argument. -// -FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) -{ - _mutex = new QMutex(QMutex::Recursive); - _title = title; - _points = QList(); - _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(); -} - -FunctionConfig::FunctionConfig() : - _tracking_active(false), - _max_Input(0), - _max_Output(0), - _data(0), - _mutex(0), - _size(0) -{ - _mutex = new QMutex(); -} - -// -// 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) { - QMutexLocker foo(_mutex); - int x2 = (int) (std::min(std::max(x, -360), 360) * MEMOIZE_PRECISION); - float ret = getValueInternal(x2); - lastValueTracked.setX(x); - lastValueTracked.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 ) { - QMutexLocker foo(_mutex); - point = lastValueTracked; - return _tracking_active; -} - -float FunctionConfig::getValueInternal(int x) { - float sign = x < 0 ? -1 : 1; - x = x < 0 ? -x : 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; -} - -static __inline QPointF ensureInBounds(QList 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]; -} - -static bool sortFn(const QPointF& one, const QPointF& two) { - 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); - } - - 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; - int start = p1.x() * MEMOIZE_PRECISION; - - for (int j = start; j < end && j < _size; j++) { - float t = (j - start) / (float) (end - start); - float t2 = t*t; - float 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; - } - } - - 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; - if (_mutex) - delete _mutex; -} - -// -// Remove a Point from the Function. -// Used by the Widget. -// -void FunctionConfig::removePoint(int i) { - QMutexLocker foo(_mutex); - if (i >= 0 && i < _points.size()) - { - _points.removeAt(i); - reload(); - } -} - -// -// Add a Point to the Function. -// Used by the Widget and by loadSettings. -// -void FunctionConfig::addPoint(QPointF pt) { - QMutexLocker foo(_mutex); - _points.append(pt); - reload(); -} - -// -// Move a Function Point. -// Used by the Widget. -// -void FunctionConfig::movePoint(int idx, QPointF pt) { - QMutexLocker foo(_mutex); - if (idx >= 0 && idx < _points.size()) - { - _points[idx] = pt; - reload(); - } -} - -// -// Return the List of Points. -// Used by the Widget. -// -QList FunctionConfig::getPoints() { - QList ret; - QMutexLocker foo(_mutex); - for (int i = 0; i < _points.size(); i++) { - ret.append(_points[i]); - } - return ret; -} - -// -// 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) { - QMutexLocker foo(_mutex); - QPointF newPoint; - - QList points; - settings.beginGroup(QString("Curves-%1").arg(_title)); - - int max = settings.value("point-count", 0).toInt(); - - qDebug() << _title << "count" << max; - - for (int i = 0; i < max; i++) { - newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), (i + 1) * _max_Input/2).toFloat(), - settings.value(QString("point-%1-y").arg(i), (i + 1) * _max_Output/2).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); - } - settings.endGroup(); - _points = points; - reload(); -} - -// -// 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) { - 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()); - } - - for (int i = max; true; i++) - { - QString x = QString("point-%1-x").arg(i); - if (!settings.contains(x)) - break; - settings.remove(x); - settings.remove(QString("point-%1-y").arg(i)); - } - settings.endGroup(); -} +/* Copyright (c) 2012, 2013 StanisÅ‚aw 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 +#include +#include +#include +#include "functionconfig.h" +#include +#include +#include +#include +#include +#include + +// +// Constructor with List of Points in argument. +// +FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) +{ + _mutex = new QMutex(QMutex::Recursive); + _title = title; + _points = QList(); + _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(); +} + +FunctionConfig::FunctionConfig() : + _tracking_active(false), + _max_Input(0), + _max_Output(0), + _data(0), + _mutex(0), + _size(0) +{ + _mutex = new QMutex(); +} + +// +// 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) { + QMutexLocker foo(_mutex); + int x2 = (int) (std::min(std::max(x, -360), 360) * MEMOIZE_PRECISION); + float ret = getValueInternal(x2); + lastValueTracked.setX(x); + lastValueTracked.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 ) { + QMutexLocker foo(_mutex); + point = lastValueTracked; + return _tracking_active; +} + +float FunctionConfig::getValueInternal(int x) { + float sign = x < 0 ? -1 : 1; + x = x < 0 ? -x : 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; +} + +static __inline QPointF ensureInBounds(QList 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]; +} + +static bool sortFn(const QPointF& one, const QPointF& two) { + 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); + } + + 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; + int start = p1.x() * MEMOIZE_PRECISION; + + for (int j = start; j < end && j < _size; j++) { + float t = (j - start) / (float) (end - start); + float t2 = t*t; + float 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; + } + } + + 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; + if (_mutex) + delete _mutex; +} + +// +// Remove a Point from the Function. +// Used by the Widget. +// +void FunctionConfig::removePoint(int i) { + QMutexLocker foo(_mutex); + if (i >= 0 && i < _points.size()) + { + _points.removeAt(i); + reload(); + } +} + +// +// Add a Point to the Function. +// Used by the Widget and by loadSettings. +// +void FunctionConfig::addPoint(QPointF pt) { + QMutexLocker foo(_mutex); + _points.append(pt); + reload(); +} + +// +// Move a Function Point. +// Used by the Widget. +// +void FunctionConfig::movePoint(int idx, QPointF pt) { + QMutexLocker foo(_mutex); + if (idx >= 0 && idx < _points.size()) + { + _points[idx] = pt; + reload(); + } +} + +// +// Return the List of Points. +// Used by the Widget. +// +QList FunctionConfig::getPoints() { + QList ret; + QMutexLocker foo(_mutex); + for (int i = 0; i < _points.size(); i++) { + ret.append(_points[i]); + } + return ret; +} + +// +// 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) { + QMutexLocker foo(_mutex); + QPointF newPoint; + + QList points; + settings.beginGroup(QString("Curves-%1").arg(_title)); + + int max = settings.value("point-count", 0).toInt(); + + qDebug() << _title << "count" << max; + + for (int i = 0; i < max; i++) { + newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), (i + 1) * _max_Input/2).toFloat(), + settings.value(QString("point-%1-y").arg(i), (i + 1) * _max_Output/2).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); + } + settings.endGroup(); + _points = points; + reload(); +} + +// +// 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) { + 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()); + } + + for (int i = max; true; i++) + { + QString x = QString("point-%1-x").arg(i); + if (!settings.contains(x)) + break; + settings.remove(x); + settings.remove(QString("point-%1-y").arg(i)); + } + settings.endGroup(); +} diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index 0f60c979..21e9e43e 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -1,78 +1,78 @@ -/* Copyright (c) 2011-2012, 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 -#include -#include -#include -#include -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" - -#ifndef FUNCTION_CONFIG_H -#define FUNCTION_CONFIG_H - -#define MEMOIZE_PRECISION 500 - -class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { -private: - QMutex* _mutex; - QList _points; - void reload(); - float* _data; - int _size; - QString _title; - 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&) {} -public: - // - // Contructor(s) and destructor - // - FunctionConfig(); - FunctionConfig(QString title, int intMaxInput, int intMaxOutput); - virtual ~FunctionConfig(); - - float getValue(float x); - bool getLastPoint(QPointF& point); // Get the last Point that was requested. - - // - // Functions to manipulate the Function - // - void removePoint(int i); - void removeAllPoints() { - QMutexLocker foo(_mutex); - _points.clear(); - reload(); - } - - void addPoint(QPointF pt); - void movePoint(int idx, QPointF pt); - QList getPoints(); - void setMaxInput(int MaxInput) { - _max_Input = MaxInput; - } - void setMaxOutput(int MaxOutput) { - _max_Output = MaxOutput; - } - - // - // Functions to load/save the Function-Points to an INI-file - // - void saveSettings(QSettings& settings); - void loadSettings(QSettings& settings); - - void setTrackingActive(bool blnActive) { - _tracking_active = blnActive; - } - QString getTitle() { return _title; } -}; - -#endif +/* Copyright (c) 2011-2012, 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 +#include +#include +#include +#include +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" + +#ifndef FUNCTION_CONFIG_H +#define FUNCTION_CONFIG_H + +#define MEMOIZE_PRECISION 500 + +class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { +private: + QMutex* _mutex; + QList _points; + void reload(); + float* _data; + int _size; + QString _title; + 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&) {} +public: + // + // Contructor(s) and destructor + // + FunctionConfig(); + FunctionConfig(QString title, int intMaxInput, int intMaxOutput); + virtual ~FunctionConfig(); + + float getValue(float x); + bool getLastPoint(QPointF& point); // Get the last Point that was requested. + + // + // Functions to manipulate the Function + // + void removePoint(int i); + void removeAllPoints() { + QMutexLocker foo(_mutex); + _points.clear(); + reload(); + } + + void addPoint(QPointF pt); + void movePoint(int idx, QPointF pt); + QList getPoints(); + void setMaxInput(int MaxInput) { + _max_Input = MaxInput; + } + void setMaxOutput(int MaxOutput) { + _max_Output = MaxOutput; + } + + // + // Functions to load/save the Function-Points to an INI-file + // + void saveSettings(QSettings& settings); + void loadSettings(QSettings& settings); + + void setTrackingActive(bool blnActive) { + _tracking_active = blnActive; + } + QString getTitle() { return _title; } +}; + +#endif -- cgit v1.2.3 From 611f781ea5a9f2260f3fa305cc2274bca48ec60d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 15:35:21 +0200 Subject: Downcase settings directory. Only affects Linux --- facetracknoir/facetracknoir.cpp | 28 +++++++++++----------- facetracknoir/tracker.cpp | 2 +- facetracknoir/tracker.h | 2 +- ftnoir_filter_accela/ftnoir_filter_accela.cpp | 2 +- .../ftnoir_filter_accela_dialog.cpp | 4 ++-- ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp | 2 +- ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp | 4 ++-- ftnoir_protocol_fg/ftnoir_protocol_fg.cpp | 2 +- ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp | 4 ++-- ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp | 2 +- .../ftnoir_protocol_fsuipc_dialog.cpp | 4 ++-- ftnoir_protocol_ft/ftnoir_protocol_ft.cpp | 2 +- ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp | 4 ++-- ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp | 2 +- ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp | 4 ++-- ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp | 2 +- .../ftnoir_protocol_mouse_dialog.cpp | 4 ++-- ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp | 6 ++--- ftnoir_tracker_ht/ftnoir_tracker_ht.cpp | 6 ++--- ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp | 2 +- .../ftnoir_tracker_hydra_dialog.cpp | 4 ++-- ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp | 8 +++---- ftnoir_tracker_rift/ftnoir_tracker_rift.cpp | 2 +- ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp | 4 ++-- ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp | 2 +- .../ftnoir_tracker_faceapi_dialog.cpp | 4 ++-- ftnoir_tracker_udp/ftnoir_tracker_udp.cpp | 2 +- ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp | 4 ++-- qfunctionconfigurator/functionconfig.cpp | 2 +- 29 files changed, 60 insertions(+), 60 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index fe8ce36b..e834b6be 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -347,7 +347,7 @@ void FaceTrackNoIR::open() { QString fileName = dialog.getOpenFileName( this, tr("Select one FTNoir settings file"), - QCoreApplication::applicationDirPath() + "/Settings/", + QCoreApplication::applicationDirPath() + "/settings/", tr("Settings file (*.ini);;All Files (*)"), NULL); @@ -368,7 +368,7 @@ void FaceTrackNoIR::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Tracking" ); @@ -422,14 +422,14 @@ void FaceTrackNoIR::saveAs() // Get the current filename of the INI-file. // QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString oldFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); // // Get the new filename of the INI-file. // QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), oldFile, -// QCoreApplication::applicationDirPath() + "/Settings", +// QCoreApplication::applicationDirPath() + "/settings", tr("Settings file (*.ini);;All Files (*)")); if (!fileName.isEmpty()) { @@ -472,7 +472,7 @@ void FaceTrackNoIR::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); qDebug() << "Config file now" << currentFile; QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) @@ -614,7 +614,7 @@ void FaceTrackNoIR::startTracker( ) { } QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) for (int i = 0; i < 6; i++) @@ -1077,7 +1077,7 @@ void FaceTrackNoIR::profileSelected(int index) // Read the current INI-file setting, to get the folder in which it's located... // QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QFileInfo pathInfo ( currentFile ); // @@ -1096,7 +1096,7 @@ void FaceTrackNoIR::filterSelected(int index) //QSettings settings("opentrack"); // Registry settings (in HK_USER) - //QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + //QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); //QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) ui.btnShowFilterControls->setEnabled ( true ); @@ -1194,7 +1194,7 @@ void FaceTrackNoIR::bindKeyboardShortcuts() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "KB_Shortcuts" ); int idxCenter = iniFile.value("Key_index_Center", 0).toInt(); @@ -1255,7 +1255,7 @@ void KeyboardShortcutDialog::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -1283,7 +1283,7 @@ void KeyboardShortcutDialog::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "KB_Shortcuts" ); @@ -1318,7 +1318,7 @@ QWidget( parent , f) mainApp = ftnoir; // Preserve a pointer to FTNoIR QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QFunctionConfigurator* configs[6] = { ui.txconfig, @@ -1424,7 +1424,7 @@ void CurveConfigurationDialog::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -1490,7 +1490,7 @@ void CurveConfigurationDialog::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); ui.rxconfig->saveSettings(currentFile); ui.ryconfig->saveSettings(currentFile); diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp index 47daa697..cdf28d40 100644 --- a/facetracknoir/tracker.cpp +++ b/facetracknoir/tracker.cpp @@ -193,7 +193,7 @@ void Tracker::loadSettings() { qDebug() << "Tracker::loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup("Tracking"); diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h index eeb18dad..0476eec4 100644 --- a/facetracknoir/tracker.h +++ b/facetracknoir/tracker.h @@ -83,7 +83,7 @@ public: zero(0) { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); curve.loadSettings(iniFile); curveAlt.loadSettings(iniFile); diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp index 0b3d6518..2c0765e8 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp @@ -26,7 +26,7 @@ FTNoIR_Filter::~FTNoIR_Filter() void FTNoIR_Filter::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Accela" ); diff --git a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp index 3e74ad81..0e3660d6 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp +++ b/ftnoir_filter_accela/ftnoir_filter_accela_dialog.cpp @@ -133,7 +133,7 @@ void FilterControls::doCancel() { void FilterControls::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Filter::loadSettings2 says: iniFile = " << currentFile; @@ -156,7 +156,7 @@ void FilterControls::loadSettings() { void FilterControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Filter::save() says: iniFile = " << currentFile; diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp index b127c665..bb9fd4c9 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp @@ -64,7 +64,7 @@ void FTNoIR_Filter::loadSettings() { qDebug() << "FTNoIR_Filter::loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Filter::loadSettings says: iniFile = " << currentFile; diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp index 91777213..f4b8aad2 100644 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp +++ b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp @@ -143,7 +143,7 @@ void FilterControls::loadSettings() { qDebug() << "FilterControls::loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FilterControls::loadSettings says: iniFile = " << currentFile; @@ -166,7 +166,7 @@ void FilterControls::loadSettings() { void FilterControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) double smooth_min, smooth_max, smooth_expt; diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp index d80791ce..dc76d193 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg.cpp @@ -61,7 +61,7 @@ FTNoIR_Protocol::~FTNoIR_Protocol() void FTNoIR_Protocol::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FG" ); diff --git a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp index 2acd3f9c..b670bdd3 100644 --- a/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp +++ b/ftnoir_protocol_fg/ftnoir_protocol_fg_dialog.cpp @@ -134,7 +134,7 @@ void FGControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -160,7 +160,7 @@ void FGControls::loadSettings() { void FGControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FG" ); diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp index ba053e11..df25e9ed 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc.cpp @@ -75,7 +75,7 @@ double local_x; void FTNoIR_Protocol::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FSUIPC" ); diff --git a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp index 90ed22b2..985915b4 100644 --- a/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp +++ b/ftnoir_protocol_fsuipc/ftnoir_protocol_fsuipc_dialog.cpp @@ -121,7 +121,7 @@ void FSUIPCControls::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -142,7 +142,7 @@ void FSUIPCControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FSUIPC" ); diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp index 597f2a5f..b72adb22 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp @@ -73,7 +73,7 @@ FTNoIR_Protocol::~FTNoIR_Protocol() void FTNoIR_Protocol::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FT" ); diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp index 810bef50..eb2d0e76 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp @@ -147,7 +147,7 @@ void FTControls::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -170,7 +170,7 @@ void FTControls::loadSettings() { void FTControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FT" ); diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp index 32d11c37..d29c80c9 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn.cpp @@ -51,7 +51,7 @@ FTNoIR_Protocol::~FTNoIR_Protocol() void FTNoIR_Protocol::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FTN" ); diff --git a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp index c902d6f8..0b61fd48 100644 --- a/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp +++ b/ftnoir_protocol_ftn/ftnoir_protocol_ftn_dialog.cpp @@ -128,7 +128,7 @@ void FTNControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -151,7 +151,7 @@ void FTNControls::loadSettings() { void FTNControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FTN" ); diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp index 6b013d74..8601bdfd 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse.cpp @@ -46,7 +46,7 @@ FTNoIR_Protocol::~FTNoIR_Protocol() void FTNoIR_Protocol::loadSettings() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Mouse" ); diff --git a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp index 1e03a022..c8d62a58 100644 --- a/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp +++ b/ftnoir_protocol_mouse/ftnoir_protocol_mouse_dialog.cpp @@ -134,7 +134,7 @@ void MOUSEControls::loadSettings() { qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -155,7 +155,7 @@ void MOUSEControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Mouse" ); diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp index 6fff39d3..dcd91994 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp @@ -101,7 +101,7 @@ static resolution_tuple resolution_choices[] = { void Tracker::load_settings() { QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "aruco-Tracker" ); @@ -396,7 +396,7 @@ void TrackerControls::loadSettings() names.prepend("Any available"); ui.cameraName->addItems(names); QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "aruco-Tracker" ); ui.cameraName->setCurrentIndex(iniFile.value("camera-index", -1).toInt() + 1); @@ -440,7 +440,7 @@ void TrackerControls::loadSettings() void TrackerControls::save() { QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "aruco-Tracker" ); diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp index b755010c..45c62f55 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp @@ -91,7 +91,7 @@ static resolution_tuple resolution_choices[] = { static void load_settings(ht_config_t* config, Tracker* tracker) { QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "HT-Tracker" ); @@ -318,7 +318,7 @@ void TrackerControls::loadSettings() names.prepend("Any available"); ui.cameraName->addItems(names); QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "HT-Tracker" ); ui.cameraName->setCurrentIndex(iniFile.value("camera-index", -1).toInt() + 1); @@ -362,7 +362,7 @@ void TrackerControls::loadSettings() void TrackerControls::save() { QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); iniFile.beginGroup( "HT-Tracker" ); diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp index 3789c7bf..81307cd6 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp @@ -124,7 +124,7 @@ void Hydra_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(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp index 77d4963b..913f8070 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra_dialog.cpp @@ -127,7 +127,7 @@ void TrackerControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -151,7 +151,7 @@ void TrackerControls::loadSettings() { void TrackerControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Hydra" ); diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp index b0249813..787a5265 100644 --- a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp +++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.cpp @@ -15,7 +15,7 @@ void TrackerSettings::load_ini() qDebug("TrackerSettings::load_ini()"); QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup( "PointTracker" ); @@ -58,7 +58,7 @@ void TrackerSettings::save_ini() const qDebug("TrackerSettings::save_ini()"); QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "PointTracker" ); @@ -102,7 +102,7 @@ void TrackerDialogSettings::load_ini() qDebug("TrackerDialogSettings::load_ini()"); QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup( "PointTrackerDialog" ); @@ -128,7 +128,7 @@ void TrackerDialogSettings::save_ini() const qDebug("TrackerDialogSettings::save_ini()"); QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "PointTrackerDialog" ); diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp index eb05d5f9..f5e1f5fa 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift.cpp @@ -142,7 +142,7 @@ void Rift_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(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; diff --git a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp index 0b644723..26fbbc9f 100644 --- a/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp +++ b/ftnoir_tracker_rift/ftnoir_tracker_rift_dialog.cpp @@ -127,7 +127,7 @@ void TrackerControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -152,7 +152,7 @@ void TrackerControls::loadSettings() { void TrackerControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "Rift" ); diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp index 06c8b206..71e9c558 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi.cpp @@ -138,7 +138,7 @@ 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(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; diff --git a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp index 332a619e..8c3cd922 100644 --- a/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp +++ b/ftnoir_tracker_sm/ftnoir_tracker_faceapi_dialog.cpp @@ -149,7 +149,7 @@ void TrackerControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -176,7 +176,7 @@ void TrackerControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "SMTracker" ); diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp index 1364ee1c..e71d13bb 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp.cpp @@ -141,7 +141,7 @@ 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(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) qDebug() << "FTNoIR_Tracker::loadSettings says: iniFile = " << currentFile; diff --git a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp index 5c0d7b1c..55bb6c97 100644 --- a/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp +++ b/ftnoir_tracker_udp/ftnoir_tracker_udp_dialog.cpp @@ -127,7 +127,7 @@ void TrackerControls::loadSettings() { // qDebug() << "loadSettings says: Starting "; QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) // qDebug() << "loadSettings says: iniFile = " << currentFile; @@ -152,7 +152,7 @@ void TrackerControls::loadSettings() { void TrackerControls::save() { QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FTNClient" ); diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index e0807859..af350143 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -33,7 +33,7 @@ FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) _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(); + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); QSettings iniFile( currentFile, QSettings::IniFormat ); loadSettings(iniFile); reload(); -- cgit v1.2.3 From a847cac005d6e42b302fbc9cb58caa0e9acd4ebd Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 16:18:24 +0200 Subject: Fix splines not loading from ini without restart It's still a mess, though. --- facetracknoir/facetracknoir.cpp | 99 ++++++++++++++----------- qfunctionconfigurator/qfunctionconfigurator.cpp | 23 +++--- 2 files changed, 68 insertions(+), 54 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index 58381c13..8e368b8d 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -198,6 +198,9 @@ FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WFlags flags) : /** sets up all objects and connections to buttons */ void FaceTrackNoIR::setupFaceTrackNoIR() { + // this is needed for Wine plugin subprocess + QDir::setCurrent(QCoreApplication::applicationDirPath()); + // if we simply place a global variable with THeadPoseData, // it gets initialized and pulls in QSettings before // main() starts. program can and will crash. @@ -354,8 +357,10 @@ void FaceTrackNoIR::open() { // If a file was selected, save it's name and read it's contents. // if (! fileName.isEmpty() ) { - QSettings settings("opentrack"); // Registry settings (in HK_USER) - settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath()); + { + QSettings settings("opentrack"); // Registry settings (in HK_USER) + settings.setValue ("SettingsFile", QFileInfo(fileName).absoluteFilePath()); + } loadSettings(); } } @@ -570,12 +575,18 @@ void FaceTrackNoIR::loadSettings() { } } + for (int i = 0; i < 6; i++) + { + axis(i).curve.loadSettings(iniFile); + axis(i).curveAlt.loadSettings(iniFile); + } + if (!_curve_config) { _curve_config = new CurveConfigurationDialog( this, this, Qt::Dialog ); } - ((CurveConfigurationDialog*) _curve_config)->loadSettings(); + ((CurveConfigurationDialog*)_curve_config)->loadSettings(); settingsDirty = false; looping = false; @@ -1323,45 +1334,6 @@ QWidget( parent , f) mainApp = ftnoir; // Preserve a pointer to FTNoIR - QSettings settings("opentrack"); // Registry settings (in HK_USER) - QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); - - 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 - }; - - QCheckBox* checkboxes[6] = { - ui.rx_altp, - ui.ry_altp, - ui.rz_altp, - ui.tx_altp, - ui.ty_altp, - ui.tz_altp - }; - - for (int i = 0; i < 6; i++) - { - configs[i]->setConfig(&mainApp->axis(i).curve, currentFile); - alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt, currentFile); - connect(configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - connect(alt_configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); - connect(checkboxes[i], SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); - } - // Connect Qt signals to member-functions connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); @@ -1427,13 +1399,13 @@ void CurveConfigurationDialog::doCancel() { // Load the current Settings from the currently 'active' INI-file. // void CurveConfigurationDialog::loadSettings() { - qDebug() << "loadSettings says: Starting "; + qDebug() << "CurveConfigurationDialog::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) - qDebug() << "loadSettings says: iniFile = " << currentFile; + qDebug() << "CurveConfigurationDialog::loadSettings says: iniFile = " << currentFile; static const char* names[] = { "tx_alt", @@ -1478,11 +1450,48 @@ void CurveConfigurationDialog::loadSettings() { "zero_ry", "zero_rz" }; - + + for (int i = 0; i < 6; i++) widgets2[i]->setValue(iniFile.value(names2[i], 0).toDouble()); iniFile.endGroup(); + + 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 + }; + + QCheckBox* checkboxes[6] = { + ui.rx_altp, + ui.ry_altp, + ui.rz_altp, + ui.tx_altp, + ui.ty_altp, + ui.tz_altp + }; + + for (int i = 0; i < 6; i++) + { + configs[i]->setConfig(&mainApp->axis(i).curve, currentFile); + alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt, currentFile); + connect(configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + connect(alt_configs[i], SIGNAL(CurveChanged(bool)), this, SLOT(curveChanged(bool))); + connect(checkboxes[i], SIGNAL(stateChanged(int)), this, SLOT(curveChanged(int))); + } settingsDirty = false; } diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 17905752..05ebbc4a 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -89,16 +89,22 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) // Attach an existing FunctionConfig to the Widget. // void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { -QPointF currentPoint; -QPointF drawPoint; -qreal x; + QPointF currentPoint; + QPointF drawPoint; + qreal x; - _config = config; - _points = config->getPoints(); - strSettingsFile = settingsFile; // Remember for Reset() + 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) + config->loadSettings(iniFile); + + _config = config; + + _points = config->getPoints(); + strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); - setCaption(config->getTitle()); + qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); + setCaption(config->getTitle()); // // Get the Function Points, one for each pixel in the horizontal range. @@ -132,7 +138,6 @@ void QFunctionConfigurator::loadSettings(QString settingsFile) { qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; if (_config) { _config->loadSettings(iniFile); - setConfig(_config, settingsFile); } } -- cgit v1.2.3 From cf5a0fb030e44f616475b9c85115f0eafeecde70 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 17:13:34 +0200 Subject: refactor QFunctionConfigurator While the API is more clear now and withstands config changes properly, there's a performance degradation while moving a spline point. It now refreshes whole spline. --- qfunctionconfigurator/qfunctionconfigurator.cpp | 657 ++++++++++++------------ qfunctionconfigurator/qfunctionconfigurator.h | 28 +- 2 files changed, 332 insertions(+), 353 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 05ebbc4a..418d46c8 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -55,31 +55,30 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) : QWidget(parent) { - // - // Defaults, for when the widget has no values different from the domXML() - // - MaxInput = 50; // Maximum input limit - MaxOutput = 180; // Maximum output limit - pPerEGU_Output = 1; // Number of pixels, per EGU - pPerEGU_Input = 4; // Number of pixels, per EGU - gDistEGU_Input = 5; // Distance of gridlines - gDistEGU_Output = 10; // Distance of gridlines - - - // Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output) - // This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) - range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + // + // Defaults, for when the widget has no values different from the domXML() + // + MaxInput = 50; // Maximum input limit + MaxOutput = 180; // Maximum output limit + pPerEGU_Output = 1; // Number of pixels, per EGU + pPerEGU_Input = 4; // Number of pixels, per EGU + gDistEGU_Input = 5; // Distance of gridlines + gDistEGU_Output = 10; // Distance of gridlines + + + // Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output) + // This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) + range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); setMouseTracking(true); movingPoint = -1; // Index of that same point - // - // Variables for FunctionConfig - // - _config = 0; - _points = QList(); - _draw_background = true; - _draw_function = true; + // + // Variables for FunctionConfig + // + _config = 0; + _draw_background = true; + _draw_function = true; // qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created."; @@ -89,10 +88,6 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) // Attach an existing FunctionConfig to the Widget. // void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { - QPointF currentPoint; - QPointF drawPoint; - qreal x; - 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) @@ -100,32 +95,13 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi _config = config; - _points = config->getPoints(); strSettingsFile = settingsFile; // Remember for Reset() qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); setCaption(config->getTitle()); - // - // Get the Function Points, one for each pixel in the horizontal range. - // If the curve does not change, there is no need to run this code every time (it slows down drawing). - // - for (int j = 0; j < MaxInput * pPerEGU_Input; j++) { - // - // Weird: not casting to float causes C++ to round the number... - // - x = (float) j / (float) pPerEGU_Input; - currentPoint.setX ( x ); - currentPoint.setY (_config->getValue( x )); - drawPoint = graphicalizePoint(currentPoint, "setConfig"); - //if (withinRect(drawPoint, range)) { - //_draw_points.append(drawPoint); -// qDebug() << "QFunctionConfigurator::setConfig _draw_Point to add = " << drawPoint; - //} - } - - _draw_function = true; - this->update(); + _draw_function = _draw_background = true; + this->update(); } // @@ -133,25 +109,25 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi // void QFunctionConfigurator::loadSettings(QString settingsFile) { - QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; - if (_config) { - _config->loadSettings(iniFile); - } + QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) + strSettingsFile = settingsFile; // Remember for Reset() + qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; + if (_config) { + _config->loadSettings(iniFile); + } } // // Save the FunctionConfig (points) to the INI-file. // void QFunctionConfigurator::saveSettings(QString settingsFile) { - QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile; + QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) + strSettingsFile = settingsFile; // Remember for Reset() + qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile; - if (_config) { - _config->saveSettings(iniFile); - } + if (_config) { + _config->saveSettings(iniFile); + } } // @@ -163,71 +139,71 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) int i; QRect scale; - qDebug() << "QFunctionConfigurator::drawBackground."; + qDebug() << "QFunctionConfigurator::drawBackground."; - _background = QPixmap(fullRect.width(), fullRect.height()); - QPainter painter(&_background); + _background = QPixmap(fullRect.width(), fullRect.height()); + QPainter painter(&_background); - painter.save(); - painter.setRenderHint(QPainter::Antialiasing); - painter.fillRect(fullRect, colBackground); - QColor bg_color(112, 154, 209); - painter.fillRect(range, bg_color); + painter.save(); + painter.setRenderHint(QPainter::Antialiasing); + painter.fillRect(fullRect, colBackground); + QColor bg_color(112, 154, 209); + painter.fillRect(range, bg_color); - QFont font("ComicSans", 4); + QFont font("ComicSans", 4); font.setPointSize(8); painter.setFont(font); QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine); - // - // Draw the Caption - // - if (_config) { - strCaption = _config->getTitle(); - } - - scale.setCoords(range.left(), 0, range.right(), 20); - painter.drawText(scale, Qt::AlignCenter, strCaption); - - // - // Draw the horizontal grid - // - for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) { - drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen); - scale.setCoords(0, i - 5, range.left() - 5, i + 5); - painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output)); - } - - // - // Draw the vertical guidelines - // - for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) { - drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen); - scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15); - painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input))); - } - - scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35); - painter.drawText(scale, Qt::AlignRight, strInputEGU); - - // - // Draw the EGU of the vertical axis (vertically!) - // - font.setPointSize(10); - painter.translate(range.topLeft().x() - 35, range.topLeft().y()); - painter.rotate(90); - painter.drawText(0,0,strOutputEGU ); - - // - // Draw the two axis - // - pen.setWidth(2); - pen.setColor( Qt::black ); - drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); - drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); - - painter.restore(); + // + // Draw the Caption + // + if (_config) { + strCaption = _config->getTitle(); + } + + scale.setCoords(range.left(), 0, range.right(), 20); + painter.drawText(scale, Qt::AlignCenter, strCaption); + + // + // Draw the horizontal grid + // + for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) { + drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen); + scale.setCoords(0, i - 5, range.left() - 5, i + 5); + painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output)); + } + + // + // Draw the vertical guidelines + // + for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) { + drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen); + scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15); + painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input))); + } + + scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35); + painter.drawText(scale, Qt::AlignRight, strInputEGU); + + // + // Draw the EGU of the vertical axis (vertically!) + // + font.setPointSize(10); + painter.translate(range.topLeft().x() - 35, range.topLeft().y()); + painter.rotate(90); + painter.drawText(0,0,strOutputEGU ); + + // + // Draw the two axis + // + pen.setWidth(2); + pen.setColor( Qt::black ); + drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); + drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); + + painter.restore(); } @@ -236,46 +212,48 @@ QRect scale; // void QFunctionConfigurator::drawFunction(const QRectF &fullRect) { - if (!_config) - return; + if (!_config) + return; int i; QPointF prevPoint; QPointF currentPoint; - // - // Use the background picture to draw on. - // ToDo: find out how to add Pixmaps, without getting it all green... - // - _function = QPixmap(_background); - QPainter painter(&_function); + // + // Use the background picture to draw on. + // ToDo: find out how to add Pixmaps, without getting it all green... + // + _function = QPixmap(_background); + QPainter painter(&_function); - painter.save(); + painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); - // - // Draw the handles for the Points - // - for (i = 0; i < _points.size(); i++) { - currentPoint = graphicalizePoint( _points[i], "drawFunction handles" ); // 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 -//qDebug() << "QFunctionConfigurator::paintEvent, drawing handle for " << currentPoint; - } + // + // Draw the handles for the Points + // + + QList points = _config->getPoints(); + + for (i = 0; i < points.size(); i++) { + currentPoint = graphicalizePoint( 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 + } QPen pen(colBezier, 1.2, Qt::SolidLine); - prevPoint = graphicalizePoint( QPointF(0,0), "drawFunction lines" ); // Start at the Axis - double max = maxInputEGU(); - QPointF prev = graphicalizePoint(QPointF(0, 0)); + prevPoint = graphicalizePoint( QPointF(0,0) ); // Start at the Axis + double max = maxInputEGU(); + QPointF prev = graphicalizePoint(QPointF(0, 0)); double step = 1e-1 / (double) pixPerEGU_Input(); - for (double i = 0; i < max; i += step) { - double val = _config->getValue(i); - QPointF cur = graphicalizePoint(QPointF(i, val)); - drawLine(&painter, prev, cur, pen); - prev = cur; - } - painter.restore(); + for (double i = 0; i < max; i += step) { + double val = _config->getValue(i); + QPointF cur = graphicalizePoint(QPointF(i, val)); + drawLine(&painter, prev, cur, pen); + prev = cur; + } + painter.restore(); } // @@ -290,80 +268,81 @@ int i; // qDebug() << "QFunctionConfigurator::paintEvent."; - QPainter p(this); + QPainter p(this); p.setRenderHint(QPainter::Antialiasing); p.setClipRect(e->rect()); - if (_draw_background) { - drawBackground(e->rect()); // Draw the static parts on a Pixmap - p.drawPixmap(0, 0, _background); // Paint the background - _draw_background = false; - } - - if (_draw_function) { - drawFunction(e->rect()); // Draw the Function on a Pixmap - _draw_function = false; - } - p.drawPixmap(0, 0, _function); // Always draw the background and the function - - QPen pen(Qt::white, 1, Qt::SolidLine); - - // - // Draw the Points, that make up the Curve - // - if (_config) { - // - // When moving, also draw a sketched version of the Function. - // - if (movingPoint >= 0 && movingPoint < _points.size()) { - prevPoint = graphicalizePoint( QPointF(0,0), "paintEvent moving" ); // Start at the Axis - for (i = 0; i < _points.size(); i++) { - currentPoint = graphicalizePoint( _points[i], "paintEvent moving" ); // Get the next point and convert it to Widget measures - drawLine(&p, prevPoint, currentPoint, pen); - prevPoint = currentPoint; + if (_draw_background) { + drawBackground(e->rect()); // Draw the static parts on a Pixmap + p.drawPixmap(0, 0, _background); // Paint the background + _draw_background = false; + } + + if (_draw_function) { + drawFunction(e->rect()); // Draw the Function on a Pixmap + _draw_function = false; + } + p.drawPixmap(0, 0, _function); // Always draw the background and the function + + QPen pen(Qt::white, 1, Qt::SolidLine); + + // + // Draw the Points, that make up the Curve + // + if (_config) { + QList points = _config->getPoints(); + // + // When moving, also draw a sketched version of the Function. + // + if (movingPoint >= 0 && movingPoint < points.size()) { + prevPoint = graphicalizePoint( QPointF(0,0) ); // Start at the Axis + for (i = 0; i < points.size(); i++) { + currentPoint = graphicalizePoint( points[i] ); // Get the next point and convert it to Widget measures + drawLine(&p, prevPoint, currentPoint, pen); + prevPoint = currentPoint; // qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint; - } - - // - // When moving, also draw a few help-lines, so positioning the point gets easier. - // - pen.setWidth(1); - pen.setColor( Qt::white ); - pen.setStyle( Qt::DashLine ); - actualPos = graphicalizePoint(_points[movingPoint], "paintEvent moving help line(s)"); - drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); - drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), 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 )) { + } + + // + // When moving, also draw a few help-lines, so positioning the point gets easier. + // + pen.setWidth(1); + pen.setColor( Qt::white ); + pen.setStyle( Qt::DashLine ); + actualPos = graphicalizePoint(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.bottom()), 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 )) { // qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint; - actualPos = graphicalizePoint( currentPoint, "paintEvent tracking" ); - drawPoint(&p, actualPos, QColor(255, 0, 0, 120)); + actualPos = graphicalizePoint( currentPoint ); + drawPoint(&p, actualPos, 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.bottom()), pen); - } + 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.bottom()), pen); + } - } + } - // - // Draw the delimiters - // - pen.setWidth(1); - pen.setColor( Qt::white ); - pen.setStyle( Qt::SolidLine ); - drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); - drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); + // + // Draw the delimiters + // + pen.setWidth(1); + pen.setColor( Qt::white ); + pen.setStyle( Qt::SolidLine ); + drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); + drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); //QTimer::singleShot(50, this, SLOT(update())); } @@ -397,70 +376,69 @@ void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, co // void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) { - // - // First: check the left mouse-button - // - if (e->button() == Qt::LeftButton) { - - // - // Check to see if the cursor is touching one of the points. - // - bool bTouchingPoint = false; - movingPoint = -1; - if (_config) { - - for (int i = 0; i < _points.size(); i++) { - if ( markContains( graphicalizePoint( _points[i], "mousePressEvent markContains" ), e->pos() ) ) { - bTouchingPoint = true; - movingPoint = i; + QList points = _config->getPoints(); + + // + // First: check the left mouse-button + // + if (e->button() == Qt::LeftButton) { + + // + // Check to see if the cursor is touching one of the points. + // + bool bTouchingPoint = false; + movingPoint = -1; + if (_config) { + for (int i = 0; i < points.size(); i++) { + if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + bTouchingPoint = true; + movingPoint = i; break; - } - } - - // - // If the Left Mouse-button was clicked without touching a Point, add a new Point - // - if (!bTouchingPoint) { - if (withinRect(e->pos(), range)) { - _config->addPoint(normalizePoint(e->pos())); - setConfig(_config, strSettingsFile); + } + } + + // + // If the Left Mouse-button was clicked without touching a Point, add a new Point + // + if (!bTouchingPoint) { + if (withinRect(e->pos(), range)) { + _config->addPoint(normalizePoint(e->pos())); movingPoint = -1; - emit CurveChanged( true ); - } - } - } - } - - // - // Then: check the right mouse-button - // - if (e->button() == Qt::RightButton) { - - // - // Check to see if the cursor is touching one of the points. - // - if (_config) { - - for (int i = 0; i < _points.size(); i++) { - if ( markContains( graphicalizePoint( _points[i], "mousePressEvent RightButton" ), e->pos() ) ) { - movingPoint = i; + emit CurveChanged( true ); + } + } + } + } + + // Then: check the right mouse-button + // + if (e->button() == Qt::RightButton) { + + // + // Check to see if the cursor is touching one of the points. + // + if (_config) { + int found_pt = -1; + for (int i = 0; i < points.size(); i++) { + if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + found_pt = i; break; - } - } - - // - // If the Right Mouse-button was clicked while touching a Point, remove the Point - // - if (movingPoint >= 0 && movingPoint < _points.size()) { - _config->removePoint(movingPoint); - movingPoint = -1; - setConfig(_config, strSettingsFile); - emit CurveChanged( true ); - } - else - movingPoint = -1; + } + } + + // + // If the Right Mouse-button was clicked while touching a Point, remove the Point + // + if (found_pt != -1) { + _config->removePoint(found_pt); + emit CurveChanged( true ); + } + movingPoint = -1; } - } + } + + _draw_function = _draw_background = true; + update(); } // @@ -469,47 +447,53 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) // void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) { + QList points = _config->getPoints(); - if (movingPoint >= 0 && movingPoint < _points.size()) { + if (movingPoint >= 0 && movingPoint < points.size()) { - setCursor(Qt::ClosedHandCursor); + setCursor(Qt::ClosedHandCursor); + + // + // Change the currently moving Point. + // + QPointF new_pt = normalizePoint(e->pos()); + points[movingPoint] = new_pt; + _config->movePoint(movingPoint, new_pt); + _draw_function = _draw_background = true; + update(); + } + else { + + // + // Check to see if the cursor is touching one of the points. + // + bool bTouchingPoint = false; + if (_config) { + + for (int i = 0; i < points.size(); i++) { + if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + bTouchingPoint = true; + } + } + } + + if ( bTouchingPoint ) { + setCursor(Qt::OpenHandCursor); + } + else { + setCursor(Qt::ArrowCursor); + } - // - // Change the currently moving Point. - // - _points[movingPoint] = normalizePoint(e->pos()); - update(); } - else { - - // - // Check to see if the cursor is touching one of the points. - // - bool bTouchingPoint = false; - if (_config) { - - for (int i = 0; i < _points.size(); i++) { - if ( markContains( graphicalizePoint( _points[i], "mouseMoveEvent" ), e->pos() ) ) { - bTouchingPoint = true; - } - } - } - - if ( bTouchingPoint ) { - setCursor(Qt::OpenHandCursor); - } - else { - setCursor(Qt::ArrowCursor); - } - - } } void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) { + QList points = _config->getPoints(); + if (e->button() == Qt::LeftButton) { //qDebug()<<"releasing"; - if (movingPoint >= 0 && movingPoint < _points.size()) { + if (movingPoint >= 0 && movingPoint < points.size()) { emit CurveChanged( true ); // @@ -517,12 +501,14 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) // if (_config) { _config->movePoint(movingPoint, normalizePoint(e->pos())); - setConfig(_config, strSettingsFile); } } setCursor(Qt::ArrowCursor); movingPoint = -1; } + + _draw_function = _draw_background = true; + update(); } // @@ -550,51 +536,49 @@ bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect // QPointF QFunctionConfigurator::normalizePoint(QPointF point) const { - QPointF norm; + QPointF norm; - norm.setX( (point.x() - range.left()) / pPerEGU_Input ); + norm.setX( (point.x() - range.left()) / pPerEGU_Input ); norm.setY( (range.bottom() - point.y()) / pPerEGU_Output ); - if (norm.x() > maxInputEGU()) - norm.setX(maxInputEGU()); - else if (norm.x() < 0) - norm.setX(0); - if (norm.y() > maxOutputEGU()) - norm.setY(maxOutputEGU()); - else if (norm.y() < 0) - norm.setY(0); + if (norm.x() > maxInputEGU()) + norm.setX(maxInputEGU()); + else if (norm.x() < 0) + norm.setX(0); + if (norm.y() > maxOutputEGU()) + norm.setY(maxOutputEGU()); + else if (norm.y() < 0) + norm.setY(0); - return norm; + return norm; } // // Convert the real-life Point into the graphical Point. // -QPointF QFunctionConfigurator::graphicalizePoint(QPointF point, QString source) const +QPointF QFunctionConfigurator::graphicalizePoint(QPointF point) const { QPointF graph; - graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) ); - graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) ); - -// qDebug() << "QFunctionConfigurator::graphicalizePoint source = " << source << ", point = " << point << ", graph = " << graph; + graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) ); + graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) ); - return graph; + return graph; } void QFunctionConfigurator::setmaxInputEGU(int value) { MaxInput = value; - setMinimumWidth(MaxInput * pPerEGU_Input + 55); + setMinimumWidth(MaxInput * pPerEGU_Input + 55); // resetCurve(); - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); + resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } void QFunctionConfigurator::setmaxOutputEGU(int value) { MaxOutput = value; - setMinimumHeight(MaxOutput * pPerEGU_Output + 60); + setMinimumHeight(MaxOutput * pPerEGU_Output + 60); // resetCurve(); - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); + resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } // @@ -603,8 +587,8 @@ void QFunctionConfigurator::setmaxOutputEGU(int value) void QFunctionConfigurator::setpixPerEGU_Input(int value) { pPerEGU_Input = value; - setMinimumWidth(MaxInput * pPerEGU_Input + 55); - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); + setMinimumWidth(MaxInput * pPerEGU_Input + 55); + resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } // @@ -613,8 +597,8 @@ void QFunctionConfigurator::setpixPerEGU_Input(int value) void QFunctionConfigurator::setpixPerEGU_Output(int value) { pPerEGU_Output = value; - setMinimumHeight(MaxOutput * pPerEGU_Output + 60); - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); + setMinimumHeight(MaxOutput * pPerEGU_Output + 60); + resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } // @@ -623,9 +607,9 @@ void QFunctionConfigurator::setpixPerEGU_Output(int value) void QFunctionConfigurator::setgridDistEGU_Input(int value) { gDistEGU_Input = value; - _draw_background = true; - _draw_function = true; - repaint(); + _draw_background = true; + _draw_function = true; + repaint(); } // @@ -634,9 +618,9 @@ void QFunctionConfigurator::setgridDistEGU_Input(int value) void QFunctionConfigurator::setgridDistEGU_Output(int value) { gDistEGU_Output = value; - _draw_background = true; - _draw_function = true; - repaint(); + _draw_background = true; + _draw_function = true; + repaint(); } void QFunctionConfigurator::setColorBezier(QColor color) @@ -668,14 +652,11 @@ void QFunctionConfigurator::setCaption(QString cap) void QFunctionConfigurator::resizeEvent(QResizeEvent *e) { - range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); - qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range; + qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range; - if (_config) { - setConfig(_config, strSettingsFile); - } - _draw_background = true; - _draw_function = true; - repaint(); + _draw_background = true; + _draw_function = true; + repaint(); } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 963f6b13..d2714ced 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -52,18 +52,18 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget { Q_OBJECT - Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU); - Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU); - Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input); - Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output); - Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input); - Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output); - - Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier); - Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground); - Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU); - Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU); - Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption); + Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU) + Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU) + Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input) + Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output) + Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input) + Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output) + + Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier) + Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground) + Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU) + Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU) + Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption) // Return the current value to Designer int maxInputEGU() const @@ -159,7 +159,6 @@ protected: void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); bool markContains(const QPointF &pt, const QPointF &coord) const; -// bool withinRange( const QPointF &coord ) const; bool withinRect( const QPointF &coord, const QRectF &rect ) const; protected: @@ -169,7 +168,7 @@ private: QRectF range; // The actual rectangle for the Bezier-curve QPointF lastPoint; // The right-most point of the Function QPointF normalizePoint (QPointF point) const; // Convert the graphical Point to a real-life Point - QPointF graphicalizePoint (QPointF point, QString source = "") const; // Convert the Point to a graphical Point + QPointF graphicalizePoint (QPointF point) const; // Convert the Point to a graphical Point int movingPoint; @@ -197,7 +196,6 @@ private: // QString _title; // Title do display in Widget and to load Settings FunctionConfig* _config; - QList _points; // Function-points }; #endif // QFUNCTIONCONFIGURATOR_H -- cgit v1.2.3 From fbca62b8ef01796127999405b76bbd918c76c69e Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 17:24:04 +0200 Subject: throttle QFunctionConfigurator updates Don't consume whole CPU time when the spline editor control points are being dragged. --- qfunctionconfigurator/qfunctionconfigurator.cpp | 60 ++++++++++++------------- qfunctionconfigurator/qfunctionconfigurator.h | 2 + 2 files changed, 32 insertions(+), 30 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 418d46c8..76245de4 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -136,10 +136,8 @@ void QFunctionConfigurator::saveSettings(QString settingsFile) { // void QFunctionConfigurator::drawBackground(const QRectF &fullRect) { -int i; -QRect scale; - - qDebug() << "QFunctionConfigurator::drawBackground."; + int i; + QRect scale; _background = QPixmap(fullRect.width(), fullRect.height()); QPainter painter(&_background); @@ -393,6 +391,7 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { bTouchingPoint = true; movingPoint = i; + timer.restart(); break; } } @@ -450,40 +449,40 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) QList points = _config->getPoints(); if (movingPoint >= 0 && movingPoint < points.size()) { - setCursor(Qt::ClosedHandCursor); - // - // Change the currently moving Point. - // - QPointF new_pt = normalizePoint(e->pos()); - points[movingPoint] = new_pt; - _config->movePoint(movingPoint, new_pt); - _draw_function = _draw_background = true; - update(); + if (timer.isValid() && timer.elapsed() > 100) + { + timer.restart(); + QPointF new_pt = normalizePoint(e->pos()); + points[movingPoint] = new_pt; + _config->movePoint(movingPoint, new_pt); + _draw_function = _draw_background = true; + update(); + } } else { - - // - // Check to see if the cursor is touching one of the points. - // - bool bTouchingPoint = false; - if (_config) { - - for (int i = 0; i < points.size(); i++) { - if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { - bTouchingPoint = true; + if (withinRect(e->pos(), rect())) + { + // + // Check to see if the cursor is touching one of the points. + // + bool bTouchingPoint = false; + if (_config) { + for (int i = 0; i < points.size(); i++) { + if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + bTouchingPoint = true; + } } } - } - if ( bTouchingPoint ) { - setCursor(Qt::OpenHandCursor); - } - else { - setCursor(Qt::ArrowCursor); + if ( bTouchingPoint ) { + setCursor(Qt::OpenHandCursor); + } + else { + setCursor(Qt::ArrowCursor); + } } - } } @@ -492,6 +491,7 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) QList points = _config->getPoints(); if (e->button() == Qt::LeftButton) { + timer.invalidate(); //qDebug()<<"releasing"; if (movingPoint >= 0 && movingPoint < points.size()) { emit CurveChanged( true ); diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index d2714ced..fc2a1957 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -39,6 +39,7 @@ #include #include #include +#include #include "qfunctionconfigurator/functionconfig.h" #include "ftnoir_tracker_base/ftnoir_tracker_base.h" @@ -171,6 +172,7 @@ private: QPointF graphicalizePoint (QPointF point) const; // Convert the Point to a graphical Point int movingPoint; + QElapsedTimer timer; int MaxInput; // Maximum input limit int MaxOutput; // Maximum output limit -- cgit v1.2.3 From 14f9db1312149fcf391c95e9c6cadbc6bdaaf7cc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 17:27:00 +0200 Subject: QFC: Don't throttle as much, it's jerky --- qfunctionconfigurator/qfunctionconfigurator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 76245de4..79c5f949 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -447,11 +447,12 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) { QList points = _config->getPoints(); + const int refresh_delay = 50; if (movingPoint >= 0 && movingPoint < points.size()) { setCursor(Qt::ClosedHandCursor); - if (timer.isValid() && timer.elapsed() > 100) + if (timer.isValid() && timer.elapsed() > refresh_delay) { timer.restart(); QPointF new_pt = normalizePoint(e->pos()); -- cgit v1.2.3 From 475df2d12176e906d99822f4517fbb85579f8683 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 14 Sep 2013 17:33:12 +0200 Subject: QFC: cleanup logic and unused stuff --- qfunctionconfigurator/qfunctionconfigurator.cpp | 1 - qfunctionconfigurator/qfunctionconfigurator.h | 9 --------- 2 files changed, 10 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 79c5f949..97d89cbb 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -402,7 +402,6 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) if (!bTouchingPoint) { if (withinRect(e->pos(), range)) { _config->addPoint(normalizePoint(e->pos())); - movingPoint = -1; emit CurveChanged( true ); } } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index fc2a1957..7260de1f 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -143,11 +143,6 @@ public slots: void setOutputEGU(QString); void setCaption(QString); - void resetCurve() { - qDebug() << "QFunctionConfigurator::resetCurve = " << strSettingsFile; - loadSettings( strSettingsFile ); - } - protected slots: void paintEvent(QPaintEvent *e); void mousePressEvent(QMouseEvent *e); @@ -193,10 +188,6 @@ private: 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) - // - // Properties of the CurveConfigurator Widget - // - QString _title; // Title do display in Widget and to load Settings FunctionConfig* _config; }; -- cgit v1.2.3 From e1cf876626aad4cbed2db96f30867c8e11af340e Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 15 Sep 2013 03:44:46 +0200 Subject: Fix MSVC build. Also, minor reformat --- CMakeLists.txt | 8 +- facetracknoir/curve-config.h | 1 - facetracknoir/facetracknoir.cpp | 2 +- facetracknoir/facetracknoir.h | 104 ++++++++++----------- facetracknoir/tracker.h | 15 --- ftnoir_filter_accela/ftnoir_filter_accela.h | 5 +- ftnoir_filter_base/ftnoir_filter_base_global.h | 2 +- ftnoir_protocol_base/ftnoir_protocol_base_global.h | 2 +- ftnoir_tracker_base/ftnoir_tracker_base.h | 6 -- ftnoir_tracker_base/ftnoir_tracker_base_global.h | 2 +- ftnoir_tracker_base/ftnoir_tracker_types.h | 5 - qfunctionconfigurator/functionconfig.cpp | 5 + qfunctionconfigurator/functionconfig.h | 11 +-- qfunctionconfigurator/qfunctionconfigurator.h | 2 + 14 files changed, 66 insertions(+), 104 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/CMakeLists.txt b/CMakeLists.txt index 25d3a809..f906d0a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,6 @@ if(NOT SDK_FACEAPI_ONLY) find_package(OpenCV) find_package(Qt4 COMPONENTS QtCore QtGui QtDesigner QtXml QtNetwork REQUIRED) - add_definitions(-DFTNOIR_FILTER_BASE_LIB -DFTNOIR_TRACKER_BASE_LIB -DFTNOIR_PROTOCOL_BASE_LIB) - if(NOT WIN32) if(NOT QXT_QXTGUI_LIB_RELEASE) find_package(Qxt COMPONENTS QxtGui REQUIRED) @@ -297,7 +295,6 @@ endif() SET (CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS_INIT} -rdynamic CACHE STRING "Flags used by the linker during the creation of modules.") endif() - add_library(opentrack-compat SHARED ${opentrack-compat-c}) if(NOT WIN32) target_link_libraries(opentrack-compat rt) @@ -314,8 +311,8 @@ endif() add_library(opentrack-pose-widget SHARED ${opentrack-pose-widget-c} ${opentrack-pose-widget-moc} ${opentrack-pose-widget-rcc}) target_link_libraries(opentrack-pose-widget ${MY_QT_LIBS}) - add_library(opentrack-spline-widget SHARED ${opentrack-spline-widget-c} ${opentrack-spline-widget-moc} ${MY_QT_LIBS} ${QT_QTDESIGNER_LIBRARY_RELEASE}) - target_link_libraries(opentrack-spline-widget ${MY_QT_LIBS}) + add_library(opentrack-spline-widget SHARED ${opentrack-spline-widget-c} ${opentrack-spline-widget-moc}) + target_link_libraries(opentrack-spline-widget ${MY_QT_LIBS} ${QT_QTDESIGNER_LIBRARY_RELEASE}) add_library(opentrack-filter-accela SHARED ${opentrack-filter-accela-c} ${opentrack-filter-accela-moc} ${opentrack-filter-accela-uih} ${opentrack-filter-accela-rcc}) target_link_libraries(opentrack-filter-accela ${MY_QT_LIBS}) @@ -508,6 +505,7 @@ endif() if(NOT WIN32) target_link_libraries(opentrack dl) endif() + set_target_properties(opentrack PROPERTIES COMPILE_FLAGS -DOPENTRACK_MAIN) endif() # make install diff --git a/facetracknoir/curve-config.h b/facetracknoir/curve-config.h index 1fcddc4e..d02f1587 100644 --- a/facetracknoir/curve-config.h +++ b/facetracknoir/curve-config.h @@ -8,7 +8,6 @@ class CurveConfigurationDialog: public QWidget { Q_OBJECT public: - explicit CurveConfigurationDialog( FaceTrackNoIR *ftnoir, QWidget *parent ); virtual ~CurveConfigurationDialog(); void showEvent ( QShowEvent * event ); diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index 534f18c8..17dded92 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -24,7 +24,7 @@ #include "facetracknoir.h" #include "shortcuts.h" #include "tracker.h" -#include +#include "curve-config.h" #include #if defined(_WIN32) diff --git a/facetracknoir/facetracknoir.h b/facetracknoir/facetracknoir.h index b4ea2912..2aa6614f 100644 --- a/facetracknoir/facetracknoir.h +++ b/facetracknoir/facetracknoir.h @@ -25,13 +25,6 @@ #ifndef FaceTrackNoIR_H #define FaceTrackNoIR_H -#undef FTNOIR_PROTOCOL_BASE_LIB -#undef FTNOIR_TRACKER_BASE_LIB -#undef FTNOIR_FILTER_BASE_LIB -#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT - #include #include #include @@ -55,15 +48,14 @@ #include "ui_facetracknoir.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 "global-settings.h" #include "tracker.h" -#include "facetracknoir/curve-config.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" + class Tracker; // pre-define class to avoid circular includes class FaceTrackNoIR; @@ -105,7 +97,7 @@ public: QxtGlobalShortcut* keyCenter; #endif public slots: - void shortcutRecentered(); + void shortcutRecentered(); private: HeadPoseData pose; @@ -133,50 +125,50 @@ private: QList dlopen_protocols; bool looping; - + private slots: - //file menu - void open(); - void save(); - void saveAs(); - void exit(); -// void setIcon(int index); - void profileSelected(int index); - - void showVideoWidget(); - void showHeadPoseWidget(); - void showTrackerSettings(); - void showSecondTrackerSettings(); - - void showServerControls(); - void showFilterControls(); - void showKeyboardShortcuts(); - void showCurveConfiguration(); - - void setInvertAxis( Axis axis, int invert ); - void setInvertYaw(int invert) { - setInvertAxis(Yaw, invert); - } - void setInvertPitch(int invert) { - setInvertAxis(Pitch, invert); - } - void setInvertRoll(int invert) { - setInvertAxis(Roll, invert); - } - void setInvertX(int invert) { - setInvertAxis(TX, invert); - } - void setInvertY(int invert) { - setInvertAxis(TY, invert); - } - void setInvertZ(int invert) { - setInvertAxis(TZ, invert); - } - void showHeadPose(); - - void startTracker(); - void stopTracker(); - + //file menu + void open(); + void save(); + void saveAs(); + void exit(); + // void setIcon(int index); + void profileSelected(int index); + + void showVideoWidget(); + void showHeadPoseWidget(); + void showTrackerSettings(); + void showSecondTrackerSettings(); + + void showServerControls(); + void showFilterControls(); + void showKeyboardShortcuts(); + void showCurveConfiguration(); + + void setInvertAxis( Axis axis, int invert ); + void setInvertYaw(int invert) { + setInvertAxis(Yaw, invert); + } + void setInvertPitch(int invert) { + setInvertAxis(Pitch, invert); + } + void setInvertRoll(int invert) { + setInvertAxis(Roll, invert); + } + void setInvertX(int invert) { + setInvertAxis(TX, invert); + } + void setInvertY(int invert) { + setInvertAxis(TY, invert); + } + void setInvertZ(int invert) { + setInvertAxis(TZ, invert); + } + void showHeadPose(); + + void startTracker(); + void stopTracker(); + }; #endif // FaceTrackNoIR_H diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h index 0476eec4..31489d87 100644 --- a/facetracknoir/tracker.h +++ b/facetracknoir/tracker.h @@ -35,22 +35,7 @@ #include "global-settings.h" #include -//#define DIRECTINPUT_VERSION 0x0800 -//#include -#undef FTNOIR_PROTOCOL_BASE_LIB -#undef FTNOIR_TRACKER_BASE_LIB -#undef FTNOIR_FILTER_BASE_LIB -#undef FTNOIR_PROTOCOL_BASE_EXPORT -#undef FTNOIR_TRACKER_BASE_EXPORT -#undef FTNOIR_FILTER_BASE_EXPORT -#define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT -#define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT - #include -#include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#include "ftnoir_protocol_base/ftnoir_protocol_base.h" -#include "ftnoir_filter_base/ftnoir_filter_base.h" #include "tracker_types.h" class FaceTrackNoIR; // pre-define parent-class to avoid circular includes diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h index 82766293..effb06c2 100644 --- a/ftnoir_filter_accela/ftnoir_filter_accela.h +++ b/ftnoir_filter_accela/ftnoir_filter_accela.h @@ -26,9 +26,6 @@ #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_accela_filtercontrols.h" #include "facetracknoir/global-settings.h" @@ -36,7 +33,7 @@ #define ACCELA_SMOOTHING_ROTATION 60.0 #define ACCELA_SMOOTHING_TRANSLATION 40.0 -#define ACCELA_ZOOM_SLOWNESS 35 +#define ACCELA_ZOOM_SLOWNESS 35 //******************************************************************************************************* // FaceTrackNoIR Filter class. diff --git a/ftnoir_filter_base/ftnoir_filter_base_global.h b/ftnoir_filter_base/ftnoir_filter_base_global.h index 02733ace..ce112411 100644 --- a/ftnoir_filter_base/ftnoir_filter_base_global.h +++ b/ftnoir_filter_base/ftnoir_filter_base_global.h @@ -3,7 +3,7 @@ #include -#ifdef FTNOIR_FILTER_BASE_LIB +#ifndef OPENTRACK_MAIN # define FTNOIR_FILTER_BASE_EXPORT Q_DECL_EXPORT #else # define FTNOIR_FILTER_BASE_EXPORT Q_DECL_IMPORT diff --git a/ftnoir_protocol_base/ftnoir_protocol_base_global.h b/ftnoir_protocol_base/ftnoir_protocol_base_global.h index 9f66d67a..bed874c4 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base_global.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base_global.h @@ -3,7 +3,7 @@ #include -#ifdef FTNOIR_PROTOCOL_BASE_LIB +#ifndef OPENTRACK_MAIN # define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_EXPORT #else # define FTNOIR_PROTOCOL_BASE_EXPORT Q_DECL_IMPORT diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h index 4d968e59..39db6bb6 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base.h @@ -22,12 +22,6 @@ * with this program; if not, see . * * This class implements a tracker-base * *********************************************************************************/ -/* - Modifications (last one on top): - 20122109 - C14: Replaced Release with virtual destructor - 20120009 - WVR: Removed AutoClosePtr (seemed like it didn't work OK) - 20110415 - WVR: Added overloaded operator - and -= -*/ #ifndef FTNOIR_TRACKER_BASE_H #define FTNOIR_TRACKER_BASE_H diff --git a/ftnoir_tracker_base/ftnoir_tracker_base_global.h b/ftnoir_tracker_base/ftnoir_tracker_base_global.h index af9899c5..30fb95e9 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base_global.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base_global.h @@ -3,7 +3,7 @@ #include -#ifdef FTNOIR_TRACKER_BASE_LIB +#ifndef OPENTRACK_MAIN # define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT #else # define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT diff --git a/ftnoir_tracker_base/ftnoir_tracker_types.h b/ftnoir_tracker_base/ftnoir_tracker_types.h index 591728a6..74612371 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_types.h +++ b/ftnoir_tracker_base/ftnoir_tracker_types.h @@ -22,11 +22,6 @@ * with this program; if not, see . * * This class implements a tracker-base * *********************************************************************************/ -/* - Modifications (last one on top): - 20120924 - C14: Moved T6DOF to separate file (not pulic interface) - 20110415 - WVR: Added overloaded operator - and -= -*/ #ifndef FTNOIR_TRACKER_TYPES_H #define FTNOIR_TRACKER_TYPES_H diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index af350143..5dab2b52 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -39,6 +39,11 @@ FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) reload(); } +void FunctionConfig::setTrackingActive(bool blnActive) +{ + _tracking_active = blnActive; +} + FunctionConfig::FunctionConfig() : _tracking_active(false), _max_Input(0), diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index 21e9e43e..f1310a8c 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -6,6 +6,8 @@ * notice appear in all copies. */ +#pragma once + #include #include #include @@ -13,9 +15,6 @@ #include #include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#ifndef FUNCTION_CONFIG_H -#define FUNCTION_CONFIG_H - #define MEMOIZE_PRECISION 500 class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { @@ -69,10 +68,6 @@ public: void saveSettings(QSettings& settings); void loadSettings(QSettings& settings); - void setTrackingActive(bool blnActive) { - _tracking_active = blnActive; - } + void setTrackingActive(bool blnActive); QString getTitle() { return _title; } }; - -#endif diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 7260de1f..c9290722 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -50,9 +50,11 @@ // 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. // + class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget { Q_OBJECT + Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU) Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU) Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input) -- cgit v1.2.3 From ec228053011db8a2d265e39ed0ba2ce240177d17 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 15 Sep 2013 03:51:42 +0200 Subject: Use double precision for intermediate computation --- qfunctionconfigurator/functionconfig.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index 5dab2b52..6e1569f9 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -138,20 +138,20 @@ void FunctionConfig::reload() { int start = p1.x() * MEMOIZE_PRECISION; for (int j = start; j < end && j < _size; j++) { - float t = (j - start) / (float) (end - start); - float t2 = t*t; - float t3 = t*t*t; + double t = (j - start) / (double) (end - start); + double t2 = t*t; + double t3 = t*t*t; - int x = .5 * ((2 * p1.x()) + + 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) + (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()) + + 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); + (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; -- cgit v1.2.3 From 28a6805bbc37590612836d32cc4321bd4bbd4c5d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 15 Sep 2013 03:52:06 +0200 Subject: Reduce UI artifacts in edge cases --- qfunctionconfigurator/qfunctionconfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 97d89cbb..4a5f7ca6 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -244,7 +244,7 @@ QPointF currentPoint; prevPoint = graphicalizePoint( QPointF(0,0) ); // Start at the Axis double max = maxInputEGU(); QPointF prev = graphicalizePoint(QPointF(0, 0)); - double step = 1e-1 / (double) pixPerEGU_Input(); + const double step = 1.01; for (double i = 0; i < max; i += step) { double val = _config->getValue(i); QPointF cur = graphicalizePoint(QPointF(i, val)); -- cgit v1.2.3 From 7b907c5f88836effdefcad320d398ce1b18e857d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 17 Sep 2013 17:42:44 +0200 Subject: splines: mutex without ptr; appease -Wreorder --- qfunctionconfigurator/functionconfig.cpp | 33 +++++++++++++++----------------- qfunctionconfigurator/functionconfig.h | 4 ++-- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index 6e1569f9..f9c9957e 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -21,9 +21,9 @@ // // Constructor with List of Points in argument. // -FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) +FunctionConfig::FunctionConfig(QString title, int intMaxInput, int intMaxOutput) : + _mutex(QMutex::Recursive) { - _mutex = new QMutex(QMutex::Recursive); _title = title; _points = QList(); _data = 0; @@ -45,14 +45,13 @@ void FunctionConfig::setTrackingActive(bool blnActive) } FunctionConfig::FunctionConfig() : + _mutex(QMutex::Recursive), + _data(0), + _size(0), _tracking_active(false), _max_Input(0), - _max_Output(0), - _data(0), - _mutex(0), - _size(0) + _max_Output(0) { - _mutex = new QMutex(); } // @@ -61,7 +60,7 @@ FunctionConfig::FunctionConfig() : // 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) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); int x2 = (int) (std::min(std::max(x, -360), 360) * MEMOIZE_PRECISION); float ret = getValueInternal(x2); lastValueTracked.setX(x); @@ -73,7 +72,7 @@ float FunctionConfig::getValue(float x) { // 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 ) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); point = lastValueTracked; return _tracking_active; } @@ -172,8 +171,6 @@ void FunctionConfig::reload() { FunctionConfig::~FunctionConfig() { if (_data) delete[] _data; - if (_mutex) - delete _mutex; } // @@ -181,7 +178,7 @@ FunctionConfig::~FunctionConfig() { // Used by the Widget. // void FunctionConfig::removePoint(int i) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); if (i >= 0 && i < _points.size()) { _points.removeAt(i); @@ -194,7 +191,7 @@ void FunctionConfig::removePoint(int i) { // Used by the Widget and by loadSettings. // void FunctionConfig::addPoint(QPointF pt) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); _points.append(pt); reload(); } @@ -204,7 +201,7 @@ void FunctionConfig::addPoint(QPointF pt) { // Used by the Widget. // void FunctionConfig::movePoint(int idx, QPointF pt) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); if (idx >= 0 && idx < _points.size()) { _points[idx] = pt; @@ -218,8 +215,8 @@ void FunctionConfig::movePoint(int idx, QPointF pt) { // QList FunctionConfig::getPoints() { QList ret; - QMutexLocker foo(_mutex); - for (int i = 0; i < _points.size(); i++) { + QMutexLocker foo(&_mutex); + for (int i = 0; i < _points.size(); i++) { ret.append(_points[i]); } return ret; @@ -230,7 +227,7 @@ QList FunctionConfig::getPoints() { // Settings for a specific Curve are loaded from their own Group in the INI-file. // void FunctionConfig::loadSettings(QSettings& settings) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); QPointF newPoint; QList points; @@ -266,7 +263,7 @@ void FunctionConfig::loadSettings(QSettings& settings) { // The number of Points is also saved, to make loading more convenient. // void FunctionConfig::saveSettings(QSettings& settings) { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); settings.beginGroup(QString("Curves-%1").arg(_title)); int max = _points.size(); settings.setValue("point-count", max); diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index f1310a8c..b6257df2 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -19,7 +19,7 @@ class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { private: - QMutex* _mutex; + QMutex _mutex; QList _points; void reload(); float* _data; @@ -47,7 +47,7 @@ public: // void removePoint(int i); void removeAllPoints() { - QMutexLocker foo(_mutex); + QMutexLocker foo(&_mutex); _points.clear(); reload(); } -- cgit v1.2.3 From 9c605834652206f550ecca66c464ca990e4d30c0 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 19 Sep 2013 15:51:11 +0200 Subject: qfc: pass -Wall -pedantic -Wextra --- qfunctionconfigurator/qfunctionconfigurator.cpp | 6 +++--- qfunctionconfigurator/qfunctionconfigurator.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 4a5f7ca6..0bd9aad0 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -208,7 +208,7 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) // // Draw the Function for the graph, on a Pixmap. // -void QFunctionConfigurator::drawFunction(const QRectF &fullRect) +void QFunctionConfigurator::drawFunction() { if (!_config) return; @@ -277,7 +277,7 @@ int i; } if (_draw_function) { - drawFunction(e->rect()); // Draw the Function on a Pixmap + drawFunction(); // Draw the Function on a Pixmap _draw_function = false; } p.drawPixmap(0, 0, _function); // Always draw the background and the function @@ -650,7 +650,7 @@ void QFunctionConfigurator::setCaption(QString cap) update(); } -void QFunctionConfigurator::resizeEvent(QResizeEvent *e) +void QFunctionConfigurator::resizeEvent(QResizeEvent *) { range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index c9290722..6669f92e 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -153,7 +153,7 @@ protected slots: protected: void drawBackground(const QRectF &rect); - void drawFunction(const QRectF &rect); + void drawFunction(); void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); bool markContains(const QPointF &pt, const QPointF &coord) const; -- cgit v1.2.3 From 51b0e2bf53eb74b3041a98908ba32aaeaf4ed253 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 9 Oct 2013 18:12:02 +0200 Subject: use native background color in spline dialog Signed-off-by: Stanislaw Halik --- facetracknoir/ftnoir_curves.ui | 54 ++++--------------------- qfunctionconfigurator/qfunctionconfigurator.cpp | 14 ++----- qfunctionconfigurator/qfunctionconfigurator.h | 12 ------ 3 files changed, 10 insertions(+), 70 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index bbdce4e2..83b514b5 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -6,8 +6,8 @@ 0 0 - 1050 - 667 + 1042 + 659 @@ -24,49 +24,9 @@ false - background-color: rgb(240, 240, 240); -/* -QWidget#widgetTop { -background-color: #595959; -border-bottom: 1px solid #000; -} -*/ + -/* Make text in message boxes selectable. */ -QMessageBox { -/* LinksAccessibleByMouse | TextSelectableByMouse */ -messagebox-text-interaction-flags: 5; -} -/* Make the entire row selected in item views. */ -QAbstractItemView { -show-decoration-selected: 1; -} - -/* Nice WindowsXP-style password character for password line edits. */ -QLineEdit[echoMode="2"] { -lineedit-password-character: 9679; -} - -/* Customize tooltips. */ -QToolTip { -background-color: rgb(170, 255, 127); -opacity: 200; -} - -/* Customize push buttons and comboboxes. Our read-only combobox -is very similar to a push button, so they share the same border image. */ - -QPushButton { -min-width: 4em; -} - -QPushButton:disabled { -color: rgb(128, 128, 128); -} - -QGroupBox { -color: rgb(255, 255, 255); -} + @@ -156,9 +116,9 @@ color: rgb(255, 255, 255); - 240 - 240 - 240 + 255 + 255 + 255 diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 0bd9aad0..802c0a1d 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -140,15 +140,14 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) QRect scale; _background = QPixmap(fullRect.width(), fullRect.height()); + QColor bgColor = palette().color(QPalette::Normal, QPalette::Background); QPainter painter(&_background); - - painter.save(); + painter.fillRect(fullRect, bgColor); painter.setRenderHint(QPainter::Antialiasing); - painter.fillRect(fullRect, colBackground); QColor bg_color(112, 154, 209); painter.fillRect(range, bg_color); - QFont font("ComicSans", 4); + QFont font; font.setPointSize(8); painter.setFont(font); @@ -200,8 +199,6 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) pen.setColor( Qt::black ); drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); - - painter.restore(); } @@ -628,11 +625,6 @@ void QFunctionConfigurator::setColorBezier(QColor color) colBezier = color; update(); } -void QFunctionConfigurator::setColorBackground(QColor color) -{ - colBackground = color; - update(); -} void QFunctionConfigurator::setInputEGU(QString egu) { diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 6669f92e..07eeeae3 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -63,7 +63,6 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output) Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier) - Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground) Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU) Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU) Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption) @@ -94,27 +93,18 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget return gDistEGU_Output; } - // Return the current color to Designer QColor colorBezier() const { return colBezier; } - // Return the current color to Designer - QColor colorBackground() const - { - return colBackground; - } - // Return the current string to Designer QString stringInputEGU() const { return strInputEGU; } - // Return the current string to Designer QString stringOutputEGU() const { return strOutputEGU; } - // Return the current string to Designer QString stringCaption() const { return strCaption; @@ -140,7 +130,6 @@ public slots: void setgridDistEGU_Output(int); void setColorBezier(QColor); - void setColorBackground(QColor); void setInputEGU(QString); void setOutputEGU(QString); void setCaption(QString); @@ -179,7 +168,6 @@ private: int gDistEGU_Output; // Distance of the grid, in EGU of Output QColor colBezier; // Color of Bezier curve - QColor colBackground; // Color of widget background QString strInputEGU; // Engineering Units input (vertical axis) QString strOutputEGU; // Engineering Units output (horizontal axis) QString strCaption; // Caption of the graph -- cgit v1.2.3 From 63461cea1a06434343a800a57004b326d4905f03 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 11 Oct 2013 12:58:08 +0200 Subject: clarify copyright Please see facetracknoir/develop: 336fc06ebe550d2c5fefae7dc1f967377eef998d https://sourceforge.net/p/facetracknoir/codegit/ci/336fc06ebe550d2c5fefae7dc1f967377eef998d/tree/ % git clone http://git.code.sf.net/p/facetracknoir/codegit Signed-off-by: Stanislaw Halik --- freetrackclient/freetrackclient.cpp | 45 ++++++++---------- ftnoir_protocol_ft/fttypes.h | 55 +++++++++------------- qfunctionconfigurator/qfunctionconfigurator.cpp | 41 +++------------- qfunctionconfigurator/qfunctionconfigurator.h | 40 +++------------- .../qfunctionconfiguratorplugin.cpp | 40 +++------------- .../qfunctionconfiguratorplugin.h | 6 +++ 6 files changed, 65 insertions(+), 162 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/freetrackclient/freetrackclient.cpp b/freetrackclient/freetrackclient.cpp index 0f8ced65..efc639ca 100644 --- a/freetrackclient/freetrackclient.cpp +++ b/freetrackclient/freetrackclient.cpp @@ -1,29 +1,22 @@ -/******************************************************************************** -* FreeTrackClientDll Implements the FreeTrack 2.0 interface for FT-enabled * -* games. * -* It uses the FreeTrack protocol (memory mapping) to * -* receive data from FaceTrackNoIR (or FreeTrack, or ...). * -* * -* Copyright (C) 2013 Wim Vriend (Developing) * -* Ron Hendriks (Testing and Research) * -* * -* 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 . * -* * -********************************************************************************/ - +/*********************************************************************************** + * * 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 * + * * * + * * 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 FT_EXPORT(t) extern "C" t __declspec(dllexport) __stdcall #define NP_AXIS_MAX 16383 diff --git a/ftnoir_protocol_ft/fttypes.h b/ftnoir_protocol_ft/fttypes.h index 0c65fc2f..ced844dc 100644 --- a/ftnoir_protocol_ft/fttypes.h +++ b/ftnoir_protocol_ft/fttypes.h @@ -1,34 +1,21 @@ -/******************************************************************************** -* FTTypes FTTypes contains th specific type definitions for the * -* FreeTrack protocol. * -* It was loosely translated from FTTypes.pas * -* which was created by the FreeTrack-team. * -* * -* Copyright (C) 2013 Wim Vriend (Developing) * -* Ron Hendriks (Testing and Research) * -* * -* 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 . * -* * -* We would like to extend our grattitude to the creators of SweetSpotter, * -* which has become the basis of this program: "Great work guys!" * -********************************************************************************/ -/* - Modifications (last one on top): - 20130125 - WVR: Upgraded to FT2.0: now the FreeTrack protocol supports all TIR-enabled games. The memory-mapping was expanded for this purpose. -*/ +/************************************************************************************ + * * 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 * + * * * + * * 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 FTTypes sources were translated from the original Delphi sources * + * * created by the FreeTrack developers. * + */ #ifndef INCLUDED_FTTYPES_H #define INCLUDED_FTTYPES_H @@ -50,8 +37,8 @@ typedef __int32 my_32bit_int; #define FREETRACK_MUTEX "FT_Mutext" struct TFreeTrackData { - int DataID; - int CamWidth; + int DataID; + int CamWidth; int CamHeight; // virtual pose float Yaw; // positive yaw to the left @@ -80,7 +67,7 @@ struct TFreeTrackData { typedef TFreeTrackData * PFreetrackData; struct FTMemMap { - TFreeTrackData data; + TFreeTrackData data; my_32bit_int GameID; unsigned char table[8]; my_32bit_int GameID2; diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 802c0a1d..bad06f8a 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -1,37 +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 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 . * -* * -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to * -* FaceTrackNoIR. * -* * -* All credits for this nice piece of code should go to Stanislaw. * -* * -* Copyright (c) 2011-2012, 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. * -********************************************************************************/ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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 #include diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 07eeeae3..8460751a 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -1,37 +1,9 @@ -/******************************************************************************** -* 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 . * -* * -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to * -* FaceTrackNoIR. * -* * -* All credits for this nice piece of code should go to Stanislaw. * -* * -* Copyright (c) 2011-2012, 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. * -********************************************************************************/ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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. + */ #ifndef QFUNCTIONCONFIGURATOR_H #define QFUNCTIONCONFIGURATOR_H diff --git a/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp b/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp index 5e98eb39..9bed2c9e 100644 --- a/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp +++ b/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp @@ -1,37 +1,9 @@ -/******************************************************************************** -* 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 . * -* * -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to * -* FaceTrackNoIR. * -* * -* All credits for this nice piece of code should go to Stanislaw. * -* * -* Copyright (c) 2011-2012, 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. * -********************************************************************************/ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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.h" #include diff --git a/qfunctionconfigurator/qfunctionconfiguratorplugin.h b/qfunctionconfigurator/qfunctionconfiguratorplugin.h index c6b65fcc..c854d3a2 100644 --- a/qfunctionconfigurator/qfunctionconfiguratorplugin.h +++ b/qfunctionconfigurator/qfunctionconfiguratorplugin.h @@ -1,3 +1,9 @@ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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. + */ #ifndef QFUNCTIONCONFIGURATORPLUGIN_H #define QFUNCTIONCONFIGURATORPLUGIN_H -- cgit v1.2.3 From e3c36cc73d7cdcaa51bfb5e2b80709f636385d1f Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 15 Oct 2013 08:53:04 +0200 Subject: drop designer plugins for now, no time to fix them Signed-off-by: Stanislaw Halik --- cmake/FindQxt.cmake | 155 --------------------- .../broken/qfunctionconfiguratorplugin.cpp | 118 ++++++++++++++++ .../broken/qfunctionconfiguratorplugin.h | 37 +++++ .../qfunctionconfiguratorplugin.cpp | 118 ---------------- .../qfunctionconfiguratorplugin.h | 36 ----- 5 files changed, 155 insertions(+), 309 deletions(-) delete mode 100644 cmake/FindQxt.cmake create mode 100644 qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp create mode 100644 qfunctionconfigurator/broken/qfunctionconfiguratorplugin.h delete mode 100644 qfunctionconfigurator/qfunctionconfiguratorplugin.cpp delete mode 100644 qfunctionconfigurator/qfunctionconfiguratorplugin.h (limited to 'qfunctionconfigurator') diff --git a/cmake/FindQxt.cmake b/cmake/FindQxt.cmake deleted file mode 100644 index 1ddfa0dd..00000000 --- a/cmake/FindQxt.cmake +++ /dev/null @@ -1,155 +0,0 @@ -############# -## basic FindQxt.cmake -## This is an *EXTREMELY BASIC* cmake find/config file for -## those times you have a cmake project and wish to use -## libQxt. -## -## It should be noted that at the time of writing, that -## I (mschnee) have an extremely limited understanding of the -## way Find*.cmake files work, but I have attempted to -## emulate what FindQt4.cmake and a few others do. -## -## To enable a specific component, set your QXT_USE_${modname}: -## SET(QXT_USE_QXTCORE TRUE) -## SET(QXT_USE_QXTGUI FALSE) -## Currently available components: -## QxtCore, QxtGui, QxtNetwork, QxtWeb, QxtSql -## Auto-including directories are enabled with INCLUDE_DIRECTORIES(), but -## can be accessed if necessary via ${QXT_INCLUDE_DIRS} -## -## To add the libraries to your build, TARGET_LINK_LIBRARIES(), such as... -## TARGET_LINK_LIBRARIES(YourTargetNameHere ${QXT_LIBRARIES}) -## ...or.. -## TARGET_LINK_LIBRARIES(YourTargetNameHere ${QT_LIBRARIES} ${QXT_LIBRARIES}) -################### TODO: -## The purpose of this cmake file is to find what components -## exist, regardless of how libQxt was build or configured, thus -## it should search/find all possible options. As I am not aware -## that any module requires anything special to be used, adding all -## modules to ${QXT_MODULES} below should be sufficient. -## Eventually, there should be version numbers, but -## I am still too unfamiliar with cmake to determine how to do -## version checks and comparisons. -## At the moment, this cmake returns a failure if you -## try to use a component that doesn't exist. I don't know how to -## set up warnings. -## It would be nice having a FindQxt.cmake and a UseQxt.cmake -## file like done for Qt - one to check for everything in advance - -############## - -###### setup -SET(QXT_MODULES QxtGui QxtWeb QxtZeroConf QxtNetwork QxtSql QxtBerkeley QxtCore) -SET(QXT_FOUND_MODULES) -FOREACH(mod ${QXT_MODULES}) - STRING(TOUPPER ${mod} U_MOD) - SET(QXT_${U_MOD}_INCLUDE_DIR NOTFOUND) - SET(QXT_${U_MOD}_LIB_DEBUG NOTFOUND) - SET(QXT_${U_MOD}_LIB_RELEASE NOTFOUND) - SET(QXT_FOUND_${U_MOD} FALSE) -ENDFOREACH(mod) -SET(QXT_QXTGUI_DEPENDSON QxtCore) -SET(QXT_QXTWEB_DEPENDSON QxtCore QxtNetwork) -SET(QXT_QXTZEROCONF_DEPENDSON QxtCore QxtNetwork) -SET(QXT_QXTNETWORK_DEPENDSON QxtCore) -SET(QXT_QXTQSQL_DEPENDSON QxtCore) -SET(QXT_QXTBERKELEY_DEPENDSON QxtCore) - -FOREACH(mod ${QXT_MODULES}) - STRING(TOUPPER ${mod} U_MOD) - IF(NOT ${U_MOD}_INCLUDE_DIR) - FIND_PATH(QXT_${U_MOD}_INCLUDE_DIR NAME ${mod} - PATH_SUFFIXES ${mod} include/${mod} - qxt/include/${mod} include/qxt/${mod} - Qxt/include/${mod} include/Qxt/${mod} - PATHS - ~/Library/Frameworks/ - /Library/Frameworks/ - /sw/ - /usr/local/ - /usr - /opt/local/ - /opt/csw - /opt - "C:/Program Files/libqxt/include" - "C:/Program Files (x86)/libqxt/include" - NO_DEFAULT_PATH - ) - FIND_LIBRARY(QXT_${U_MOD}_LIB_RELEASE NAME ${mod} - PATH_SUFFIXES Qxt/lib64 Qxt/lib lib64 lib lib/${CMAKE_LIBRARY_ARCHITECTURE} - PATHS - /sw - /usr/local - /usr - /opt/local - /opt/csw - /opt - "C:/Program Files/libqxt" - "C:/Program Files (x86)/libqxt" - NO_DEFAULT_PATH - ) - FIND_LIBRARY(QXT_${U_MOD}_LIB_DEBUG NAME ${mod}d - PATH_SUFFIXES Qxt/lib64 Qxt/lib lib64 lib lib/${CMAKE_LIBRARY_ARCHITECTURE} - PATHS - /sw - /usr/local - /usr - /opt/local - /opt/csw - /opt - "C:/Program Files/libqxt/" - "C:/Program Files (x86)/libqxt/" - NO_DEFAULT_PATH - ) - IF (QXT_${U_MOD}_LIB_RELEASE) - SET(QXT_FOUND_MODULES "${QXT_FOUND_MODULES} ${mod}") - ENDIF (QXT_${U_MOD}_LIB_RELEASE) - - IF (QXT_${U_MOD}_LIB_DEBUG) - SET(QXT_FOUND_MODULES "${QXT_FOUND_MODULES} ${mod}") - ENDIF (QXT_${U_MOD}_LIB_DEBUG) - ENDIF() -ENDFOREACH(mod) - -FOREACH(mod ${QXT_MODULES}) - STRING(TOUPPER ${mod} U_MOD) - IF(QXT_${U_MOD}_INCLUDE_DIR AND QXT_${U_MOD}_LIB_RELEASE) - SET(QXT_FOUND_${U_MOD} TRUE) - ENDIF(QXT_${U_MOD}_INCLUDE_DIR AND QXT_${U_MOD}_LIB_RELEASE) -ENDFOREACH(mod) - - -##### find and include -# To use a Qxt Library.... -# SET(QXT_FIND_COMPONENTS QxtCore, QxtGui) -# ...and this will do the rest -IF( QXT_FIND_COMPONENTS ) - FOREACH( component ${QXT_FIND_COMPONENTS} ) - STRING( TOUPPER ${component} _COMPONENT ) - SET(QXT_USE_${_COMPONENT}_COMPONENT TRUE) - ENDFOREACH( component ) -ENDIF( QXT_FIND_COMPONENTS ) - -SET(QXT_LIBRARIES "") -SET(QXT_INCLUDE_DIRS "") - -# like FindQt4.cmake, in order of dependence -FOREACH( module ${QXT_MODULES} ) - STRING(TOUPPER ${module} U_MOD) - IF(QXT_USE_${U_MOD} OR QXT_DEPENDS_${U_MOD}) - IF(QXT_FOUND_${U_MOD}) - STRING(REPLACE "QXT" "" qxt_module_def "${U_MOD}") - ADD_DEFINITIONS(-DQXT_${qxt_module_def}_LIB) - SET(QXT_INCLUDE_DIRS ${QXT_INCLUDE_DIRS} ${QXT_${U_MOD}_INCLUDE_DIR}) - INCLUDE_DIRECTORIES(${QXT_${U_MOD}_INCLUDE_DIR}) - SET(QXT_LIBRARIES ${QXT_LIBRARIES} ${QXT_${U_MOD}_LIB_RELEASE}) - ELSE(QXT_FOUND_${U_MOD}) - MESSAGE("Could not find Qxt Module ${module}") - RETURN() - ENDIF(QXT_FOUND_${U_MOD}) - FOREACH(dep QXT_${U_MOD}_DEPENDSON) - SET(QXT_DEPENDS_${dep} TRUE) - ENDFOREACH(dep) - ENDIF(QXT_USE_${U_MOD} OR QXT_DEPENDS_${U_MOD}) -ENDFOREACH(module) -MESSAGE(STATUS "Found Qxt Libraries:${QXT_FOUND_MODULES}") diff --git a/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp new file mode 100644 index 00000000..9bed2c9e --- /dev/null +++ b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp @@ -0,0 +1,118 @@ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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.h" + +#include +#include "qfunctionconfiguratorplugin.h" + + +QFunctionConfiguratorPlugin::QFunctionConfiguratorPlugin(QObject *parent) + : QObject(parent) +{ + initialized = false; +} + +void QFunctionConfiguratorPlugin::initialize(QDesignerFormEditorInterface *) +{ + if (initialized) + return; + + initialized = true; +} + +bool QFunctionConfiguratorPlugin::isInitialized() const +{ + return initialized; +} + +QWidget *QFunctionConfiguratorPlugin::createWidget(QWidget *parent) +{ + return new QFunctionConfigurator(parent); +} + +QString QFunctionConfiguratorPlugin::name() const +{ + return "QFunctionConfigurator"; +} + +QString QFunctionConfiguratorPlugin::group() const +{ + return "My Plugins"; +} + +QIcon QFunctionConfiguratorPlugin::icon() const +{ + return QIcon(); +} + +QString QFunctionConfiguratorPlugin::toolTip() const +{ + return QString(); +} + +QString QFunctionConfiguratorPlugin::whatsThis() const +{ + return QString(); +} + +bool QFunctionConfiguratorPlugin::isContainer() const +{ + return false; +} + +QString QFunctionConfiguratorPlugin::domXml() const +{ + return "\n" + " \n" + " \n" + " 0\n" + " 0\n" + " 161\n" + " 220\n" + " \n" + " \n" + " \n" + " \n" + " 255\n" + " 170\n" + " 0\n" + " \n" + " \n" + " \n" + " \n" + " 192\n" + " 192\n" + " 192\n" + " \n" + " \n" + " \n" + " Input Yaw (degr.)\n" + " \n" + " \n" + " Output Yaw (degr.)\n" + " \n" + " \n" + " 50\n" + " \n" + " \n" + " 180\n" + " \n" + " \n" + " 2\n" + " \n" + " \n" + " 1\n" + " \n" + "\n"; +} + +QString QFunctionConfiguratorPlugin::includeFile() const +{ + return "qfunctionconfigurator.h"; +} + +Q_EXPORT_PLUGIN2(qfunctionconfigurator, QFunctionConfiguratorPlugin) diff --git a/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.h b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.h new file mode 100644 index 00000000..bc637338 --- /dev/null +++ b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2011-2012 Stanislaw Halik + * 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. + */ +#ifndef QFUNCTIONCONFIGURATORPLUGIN_H +#define QFUNCTIONCONFIGURATORPLUGIN_H + +#include + +class QFunctionConfiguratorPlugin : public QObject, public QDesignerCustomWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface" FILE "analogclock.json") + Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + QFunctionConfiguratorPlugin(QObject *parent = 0); + + bool isContainer() const; + bool isInitialized() const; + QIcon icon() const; + QString domXml() const; + QString group() const; + QString includeFile() const; + QString name() const; + QString toolTip() const; + QString whatsThis() const; + QWidget *createWidget(QWidget *parent); + void initialize(QDesignerFormEditorInterface *core); + +private: + bool initialized; +}; + +#endif // QFUNCTIONCONFIGURATORPLUGIN_H diff --git a/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp b/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp deleted file mode 100644 index 9bed2c9e..00000000 --- a/qfunctionconfigurator/qfunctionconfiguratorplugin.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (c) 2011-2012 Stanislaw Halik - * 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.h" - -#include -#include "qfunctionconfiguratorplugin.h" - - -QFunctionConfiguratorPlugin::QFunctionConfiguratorPlugin(QObject *parent) - : QObject(parent) -{ - initialized = false; -} - -void QFunctionConfiguratorPlugin::initialize(QDesignerFormEditorInterface *) -{ - if (initialized) - return; - - initialized = true; -} - -bool QFunctionConfiguratorPlugin::isInitialized() const -{ - return initialized; -} - -QWidget *QFunctionConfiguratorPlugin::createWidget(QWidget *parent) -{ - return new QFunctionConfigurator(parent); -} - -QString QFunctionConfiguratorPlugin::name() const -{ - return "QFunctionConfigurator"; -} - -QString QFunctionConfiguratorPlugin::group() const -{ - return "My Plugins"; -} - -QIcon QFunctionConfiguratorPlugin::icon() const -{ - return QIcon(); -} - -QString QFunctionConfiguratorPlugin::toolTip() const -{ - return QString(); -} - -QString QFunctionConfiguratorPlugin::whatsThis() const -{ - return QString(); -} - -bool QFunctionConfiguratorPlugin::isContainer() const -{ - return false; -} - -QString QFunctionConfiguratorPlugin::domXml() const -{ - return "\n" - " \n" - " \n" - " 0\n" - " 0\n" - " 161\n" - " 220\n" - " \n" - " \n" - " \n" - " \n" - " 255\n" - " 170\n" - " 0\n" - " \n" - " \n" - " \n" - " \n" - " 192\n" - " 192\n" - " 192\n" - " \n" - " \n" - " \n" - " Input Yaw (degr.)\n" - " \n" - " \n" - " Output Yaw (degr.)\n" - " \n" - " \n" - " 50\n" - " \n" - " \n" - " 180\n" - " \n" - " \n" - " 2\n" - " \n" - " \n" - " 1\n" - " \n" - "\n"; -} - -QString QFunctionConfiguratorPlugin::includeFile() const -{ - return "qfunctionconfigurator.h"; -} - -Q_EXPORT_PLUGIN2(qfunctionconfigurator, QFunctionConfiguratorPlugin) diff --git a/qfunctionconfigurator/qfunctionconfiguratorplugin.h b/qfunctionconfigurator/qfunctionconfiguratorplugin.h deleted file mode 100644 index c854d3a2..00000000 --- a/qfunctionconfigurator/qfunctionconfiguratorplugin.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2011-2012 Stanislaw Halik - * 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. - */ -#ifndef QFUNCTIONCONFIGURATORPLUGIN_H -#define QFUNCTIONCONFIGURATORPLUGIN_H - -#include - -class QFunctionConfiguratorPlugin : public QObject, public QDesignerCustomWidgetInterface -{ - Q_OBJECT - Q_INTERFACES(QDesignerCustomWidgetInterface) - -public: - QFunctionConfiguratorPlugin(QObject *parent = 0); - - bool isContainer() const; - bool isInitialized() const; - QIcon icon() const; - QString domXml() const; - QString group() const; - QString includeFile() const; - QString name() const; - QString toolTip() const; - QString whatsThis() const; - QWidget *createWidget(QWidget *parent); - void initialize(QDesignerFormEditorInterface *core); - -private: - bool initialized; -}; - -#endif // QFUNCTIONCONFIGURATORPLUGIN_H -- cgit v1.2.3 From e384433c993ee062d6d4c1b1e0224dd870a6455f Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 15 Oct 2013 08:53:43 +0200 Subject: correct some obsolete stuff Signed-off-by: Stanislaw Halik --- facetracknoir/facetracknoir.cpp | 4 +-- facetracknoir/facetracknoir.h | 6 ++-- facetracknoir/facetracknoir.ui | 40 +++++++++++++++------------ ftnoir_protocol_base/ftnoir_protocol_base.h | 4 +-- ftnoir_tracker_base/ftnoir_tracker_base.h | 4 +-- qfunctionconfigurator/qfunctionconfigurator.h | 1 - 6 files changed, 32 insertions(+), 27 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index 2ccb2bb7..eb24b320 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -89,7 +89,7 @@ static void fill_combobox(const QString& filter, QList& list, Q // // Setup the Main Dialog // -FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WFlags flags) : +FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), #if defined(_WIN32) keybindingWorker(NULL), @@ -938,7 +938,7 @@ void FaceTrackNoIR::bindKeyboardShortcuts() seq = "Alt+" + seq; if (iniFile.value("Ctrl_Center", false).toBool()) seq = "Ctrl+" + seq; - keyCenter = new QxtGlobalShortcut(QKeySequence(seq)); + keyCenter = new QxtGlobalShortcut(QKeySequence(seq), this); connect(keyCenter, SIGNAL(activated()), this, SLOT(shortcutRecentered())); } } diff --git a/facetracknoir/facetracknoir.h b/facetracknoir/facetracknoir.h index b9c7168b..6c087c43 100644 --- a/facetracknoir/facetracknoir.h +++ b/facetracknoir/facetracknoir.h @@ -25,7 +25,7 @@ #ifndef FaceTrackNoIR_H #define FaceTrackNoIR_H -#include +#include #include #include #include @@ -39,7 +39,7 @@ #include #include #if !defined(_WIN32) -# include +# include "qxt-mini/QxtGlobalShortcut" #else # include #endif @@ -67,7 +67,7 @@ class FaceTrackNoIR : public QMainWindow, IDynamicLibraryProvider Q_OBJECT public: - FaceTrackNoIR(QWidget *parent = 0, Qt::WFlags flags = 0); + FaceTrackNoIR(QWidget *parent = 0, Qt::WindowFlags flags = 0); ~FaceTrackNoIR(); QFrame *get_video_widget(); // Get a pointer to the video-widget, to use in the DLL diff --git a/facetracknoir/facetracknoir.ui b/facetracknoir/facetracknoir.ui index 5c573a0b..5568db26 100644 --- a/facetracknoir/facetracknoir.ui +++ b/facetracknoir/facetracknoir.ui @@ -1480,8 +1480,8 @@ background:none; QFrame::NoFrame - - 6 + + 2 @@ -1496,8 +1496,8 @@ background:none; QFrame::NoFrame - - 6 + + 2 @@ -1546,6 +1546,9 @@ color:white; QFrame::NoFrame + + 2 + @@ -1576,6 +1579,9 @@ border:none; QFrame::NoFrame + + 2 + @@ -1640,8 +1646,8 @@ color:white; QFrame::NoFrame - - 6 + + 2 @@ -1656,8 +1662,8 @@ color:white; QFrame::NoFrame - - 5 + + 2 @@ -1704,8 +1710,8 @@ color:white; QFrame::Raised - - 5 + + 1 QLCDNumber::Flat @@ -1732,8 +1738,8 @@ color:white; QFrame::Raised - - 5 + + 1 QLCDNumber::Flat @@ -1760,8 +1766,8 @@ color:white; QFrame::Raised - - 5 + + 1 QLCDNumber::Flat @@ -1788,7 +1794,7 @@ color:white; QFrame::Raised - + 5 @@ -1816,7 +1822,7 @@ color:white; QFrame::Raised - + 5 @@ -1844,7 +1850,7 @@ color:white; QFrame::Raised - + 5 diff --git a/ftnoir_protocol_base/ftnoir_protocol_base.h b/ftnoir_protocol_base/ftnoir_protocol_base.h index d20e01b5..79f0800c 100644 --- a/ftnoir_protocol_base/ftnoir_protocol_base.h +++ b/ftnoir_protocol_base/ftnoir_protocol_base.h @@ -34,8 +34,8 @@ #include "ftnoir_protocol_base_global.h" #include "ftnoir_tracker_base/ftnoir_tracker_types.h" -#include -#include +#include +#include struct IProtocol { diff --git a/ftnoir_tracker_base/ftnoir_tracker_base.h b/ftnoir_tracker_base/ftnoir_tracker_base.h index cd603225..edbe7379 100644 --- a/ftnoir_tracker_base/ftnoir_tracker_base.h +++ b/ftnoir_tracker_base/ftnoir_tracker_base.h @@ -27,8 +27,8 @@ #include "ftnoir_tracker_base_global.h" #include "ftnoir_tracker_types.h" -#include -#include +#include +#include #include #include #include diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 8460751a..fa72fb72 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -9,7 +9,6 @@ #include #include -#include #include #include #include "qfunctionconfigurator/functionconfig.h" -- cgit v1.2.3 From 1abc4a8aaba0cb1d01492b60d655181814e67ac0 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 17 Oct 2013 01:19:53 +0200 Subject: simplify color stuffies Signed-off-by: Stanislaw Halik --- qfunctionconfigurator/qfunctionconfigurator.cpp | 8 +++----- qfunctionconfigurator/qfunctionconfigurator.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index bad06f8a..a068a53c 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -17,10 +17,9 @@ #include #include #include - #include - -#include +#include +#include static const int pointSize = 5; @@ -111,9 +110,8 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) { int i; QRect scale; - _background = QPixmap(fullRect.width(), fullRect.height()); - QColor bgColor = palette().color(QPalette::Normal, QPalette::Background); + auto bgColor = palette().button(); QPainter painter(&_background); painter.fillRect(fullRect, bgColor); painter.setRenderHint(QPainter::Antialiasing); diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index fa72fb72..1ac919fe 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -112,7 +112,7 @@ protected slots: void mouseReleaseEvent(QMouseEvent *e); protected: - void drawBackground(const QRectF &rect); + void drawBackground(const QRectF &); void drawFunction(); void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); -- cgit v1.2.3 From 8f23371ba8e894f5301cdccdce5e49e86a0222f8 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 17 Oct 2013 20:15:21 +0200 Subject: hardcode colors, since qt tabpage is somewhat 'special' Signed-off-by: Stanislaw Halik --- facetracknoir/curve-config.cpp | 6 +- facetracknoir/curve-config.h | 1 + facetracknoir/facetracknoir.cpp | 1 + facetracknoir/ftnoir_curves.ui | 1693 +++++++++++------------ qfunctionconfigurator/qfunctionconfigurator.cpp | 4 +- 5 files changed, 841 insertions(+), 864 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/curve-config.cpp b/facetracknoir/curve-config.cpp index 117e5803..50aa8acf 100644 --- a/facetracknoir/curve-config.cpp +++ b/facetracknoir/curve-config.cpp @@ -2,15 +2,13 @@ #include "facetracknoir/curve-config.h" #include CurveConfigurationDialog::CurveConfigurationDialog(FaceTrackNoIR *ftnoir, QWidget *parent) : -QWidget( parent, Qt::Dialog ) + QWidget( parent, Qt::Dialog ), mainApp(ftnoir) { ui.setupUi( this ); - QPoint offsetpos(120, 30); + QPoint offsetpos(120, 30); this->move(parent->pos() + offsetpos); - mainApp = ftnoir; // Preserve a pointer to FTNoIR - // Connect Qt signals to member-functions connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); diff --git a/facetracknoir/curve-config.h b/facetracknoir/curve-config.h index a9073840..d2acf371 100644 --- a/facetracknoir/curve-config.h +++ b/facetracknoir/curve-config.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "ui_ftnoir_curves.h" class FaceTrackNoIR; diff --git a/facetracknoir/facetracknoir.cpp b/facetracknoir/facetracknoir.cpp index bec35522..b5ccfdff 100644 --- a/facetracknoir/facetracknoir.cpp +++ b/facetracknoir/facetracknoir.cpp @@ -105,6 +105,7 @@ FaceTrackNoIR::FaceTrackNoIR(QWidget *parent, Qt::WindowFlags flags) : looping(false) { ui.setupUi(this); + setFixedSize(size()); // // Initialize Widget handles, to prevent memory-access errors. diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index 46a1892c..d9198a76 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -6,7 +6,7 @@ 0 0 - 980 + 970 655 @@ -27,847 +27,841 @@ Qt::LeftToRight - + background-color: #ccc; - - - - - - - - - - 0 - - - - Yaw - - - - - 0 - 0 - 921 - 240 - - - - 180 - - - 180 - - - 5 - - - - 255 - 0 - 0 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 166 - 21 - - - - Use alternative - - - - - - 0 - 340 - 921 - 240 - - - - 180 - - - 180 - - - 5 - - - - 255 - 0 - 0 - - - - - 255 - 255 - 255 - - - - - - - Pitch - - - - - 0 - 0 - 595 - 240 - - - - 90 - - - 90 - - - 10 - - - 2 - - - - 0 - 255 - 0 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 199 - 21 - - - - Use alternative - - - - - - 0 - 340 - 1013 - 240 - - - - 90 - - - 90 - - - 10 - - - 2 - - - - 0 - 255 - 0 - - - - - 240 - 240 - 240 - - - - - - - Roll - - - - - 0 - 0 - 595 - 240 - - - - 180 - - - 180 - - - 5 - - - 1 - - - - 0 - 0 - 255 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 271 - 21 - - - - Use alternative - - - - - - 0 - 340 - 595 - 240 - - - - 180 - - - 180 - - - 5 - - - 1 - - - - 0 - 0 - 255 - - - - - 240 - 240 - 240 - - - - - - - X - - - - - 0 - 0 - 555 - 270 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 255 - 0 - 255 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 228 - 21 - - - - Use alternative - - - - - - 0 - 310 - 555 - 160 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 255 - 0 - 255 - - - - - 240 - 240 - 240 - - - - - - - Y - - - - - 0 - 0 - 555 - 160 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 255 - 255 - 0 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 229 - 21 - - - - Use alternative - - - - - - 0 - 310 - 555 - 160 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 255 - 255 - 0 - - - - - 240 - 240 - 240 - - - - - - - Z - - - - - 0 - 0 - 555 - 160 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 0 - 255 - 255 - - - - - 240 - 240 - 240 - - - - - - - 0 - 280 - 263 - 21 - - - - Use alternative - - - - - - 0 - 310 - 555 - 160 - - - - 100 - - - 100 - - - 7 - - - 2 - - - - 0 - 255 - 255 - - - - - 240 - 240 - 240 - - - - - - - Positions - - - - - 10 - 44 - 35 - 16 - - - - RY - - - - - - 10 - 10 - 34 - 20 - - - - RX - - - - - - 9 - 75 - 33 - 16 - - - - RZ - - - - - - 50 - 10 - 131 - 22 - - - - deg. - - - 3 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - 50 - 40 - 131 - 22 - - - - deg. - - - 3 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - 49 - 71 - 131 - 22 - - - - deg. - - - 3 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - 209 - 10 - 32 - 20 - - - - TX - - - - - - 249 - 10 - 152 - 22 - - - - cm - - - 3 - - - -100.000000000000000 - - - 100.000000000000000 - - - - - - 249 - 40 - 152 - 22 - - - - cm - - - 3 - - - -100.000000000000000 - - - 100.000000000000000 - - - - - - 248 - 71 - 154 - 22 - - - - cm - - - 3 - - - -100.000000000000000 - - - 100.000000000000000 - - - - - - 209 - 44 - 32 - 16 - - - - TY - - - - - - 208 - 75 - 35 - 16 - - - - TZ - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - OK - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Cancel - - - - - - - - + + + + 810 + 625 + 72 + 24 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + + + + OK + + + + + + 886 + 625 + 69 + 24 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Cancel + + + + + + 0 + 0 + 984 + 621 + + + + background-color: #ccc; + + + QTabWidget::North + + + 0 + + + + Yaw + + + + + 0 + 0 + 921 + 240 + + + + 180 + + + 180 + + + 5 + + + + 255 + 0 + 0 + + + + + 240 + 240 + 240 + + + + + + + 10 + 260 + 166 + 21 + + + + Use alternative + + + + + + 0 + 300 + 975 + 275 + + + + 180 + + + 180 + + + 5 + + + + 255 + 0 + 0 + + + + + 255 + 255 + 255 + + + + + + + Pitch + + + + + 0 + 0 + 595 + 240 + + + + 90 + + + 90 + + + 10 + + + 2 + + + + 0 + 255 + 0 + + + + + 240 + 240 + 240 + + + + + + + 10 + 260 + 199 + 21 + + + + Use alternative + + + + + + 0 + 300 + 1013 + 240 + + + + 90 + + + 90 + + + 10 + + + 2 + + + + 0 + 255 + 0 + + + + + 240 + 240 + 240 + + + + + + + Roll + + + + + 0 + 0 + 595 + 240 + + + + 180 + + + 180 + + + 5 + + + 1 + + + + 0 + 0 + 255 + + + + + 240 + 240 + 240 + + + + + + + 10 + 260 + 271 + 21 + + + + Use alternative + + + + + + 0 + 300 + 595 + 240 + + + + 180 + + + 180 + + + 5 + + + 1 + + + + 0 + 0 + 255 + + + + + 240 + 240 + 240 + + + + + + + X + + + + + 0 + 0 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 255 + 0 + 255 + + + + + 240 + 240 + 240 + + + + + + + 10 + 270 + 228 + 21 + + + + Use alternative + + + + + + 0 + 300 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 255 + 0 + 255 + + + + + 240 + 240 + 240 + + + + + + + Y + + + + + 0 + 0 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 255 + 255 + 0 + + + + + 240 + 240 + 240 + + + + + + + 10 + 270 + 229 + 21 + + + + Use alternative + + + + + + 0 + 300 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 255 + 255 + 0 + + + + + 240 + 240 + 240 + + + + + + + Z + + + + + 0 + 0 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 0 + 255 + 255 + + + + + 240 + 240 + 240 + + + + + + + 10 + 270 + 263 + 21 + + + + Use alternative + + + + + + 0 + 300 + 555 + 160 + + + + 100 + + + 100 + + + 7 + + + 2 + + + + 0 + 255 + 255 + + + + + 240 + 240 + 240 + + + + + + + Defaults + + + + + 10 + 44 + 35 + 16 + + + + RY + + + + + + 10 + 10 + 34 + 20 + + + + RX + + + + + + 9 + 75 + 33 + 16 + + + + RZ + + + + + + 50 + 10 + 131 + 22 + + + + deg. + + + 3 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + 50 + 40 + 131 + 22 + + + + deg. + + + 3 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + 49 + 71 + 131 + 22 + + + + deg. + + + 3 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + 209 + 10 + 32 + 20 + + + + TX + + + + + + 249 + 10 + 152 + 22 + + + + cm + + + 3 + + + -100.000000000000000 + + + 100.000000000000000 + + + + + + 249 + 40 + 152 + 22 + + + + cm + + + 3 + + + -100.000000000000000 + + + 100.000000000000000 + + + + + + 248 + 71 + 154 + 22 + + + + cm + + + 3 + + + -100.000000000000000 + + + 100.000000000000000 + + + + + + 209 + 44 + 32 + 16 + + + + TY + + + + + + 208 + 75 + 35 + 16 + + + + TZ + + + + @@ -878,23 +872,6 @@ - - - 10 - - - 10 - - - false - - - false - - - true - - startEngineClicked() stopEngineClicked() diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index a068a53c..6bacf294 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -20,6 +20,7 @@ #include #include #include +#include static const int pointSize = 5; @@ -111,9 +112,8 @@ void QFunctionConfigurator::drawBackground(const QRectF &fullRect) int i; QRect scale; _background = QPixmap(fullRect.width(), fullRect.height()); - auto bgColor = palette().button(); QPainter painter(&_background); - painter.fillRect(fullRect, bgColor); + painter.fillRect(fullRect, QColor::fromRgb(204, 204, 204)); painter.setRenderHint(QPainter::Antialiasing); QColor bg_color(112, 154, 209); painter.fillRect(range, bg_color); -- cgit v1.2.3 From d37cbece940357105480c0991a70ee8394939301 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 17 Oct 2013 20:34:39 +0200 Subject: get rid of QFC artifacts Signed-off-by: Stanislaw Halik --- facetracknoir/ftnoir_curves.ui | 2 +- .../broken/qfunctionconfiguratorplugin.cpp | 7 ------- qfunctionconfigurator/qfunctionconfigurator.cpp | 24 +++++++++++----------- qfunctionconfigurator/qfunctionconfigurator.h | 2 +- 4 files changed, 14 insertions(+), 21 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index d9198a76..d0c1b2cd 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -168,7 +168,7 @@ 0 300 975 - 275 + 206 diff --git a/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp index 9bed2c9e..1a9da10a 100644 --- a/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp +++ b/qfunctionconfigurator/broken/qfunctionconfiguratorplugin.cpp @@ -82,13 +82,6 @@ QString QFunctionConfiguratorPlugin::domXml() const " 0\n" " \n" " \n" - " \n" - " \n" - " 192\n" - " 192\n" - " 192\n" - " \n" - " \n" " \n" " Input Yaw (degr.)\n" " \n" diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 6bacf294..0b4df033 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -43,7 +43,6 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) // This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); - setMouseTracking(true); movingPoint = -1; // Index of that same point // @@ -107,13 +106,13 @@ void QFunctionConfigurator::saveSettings(QString settingsFile) { // Draw the Background for the graph, the gridlines and the gridpoints. // The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up... // -void QFunctionConfigurator::drawBackground(const QRectF &fullRect) +void QFunctionConfigurator::drawBackground() { int i; QRect scale; - _background = QPixmap(fullRect.width(), fullRect.height()); + _background = QPixmap(width(), height()); QPainter painter(&_background); - painter.fillRect(fullRect, QColor::fromRgb(204, 204, 204)); + painter.fillRect(rect(), QColor::fromRgb(204, 204, 204)); painter.setRenderHint(QPainter::Antialiasing); QColor bg_color(112, 154, 209); painter.fillRect(range, bg_color); @@ -236,11 +235,10 @@ int i; QPainter p(this); p.setRenderHint(QPainter::Antialiasing); - p.setClipRect(e->rect()); if (_draw_background) { - drawBackground(e->rect()); // Draw the static parts on a Pixmap - p.drawPixmap(0, 0, _background); // Paint the background + drawBackground(); // Draw the static parts on a Pixmap + p.drawPixmap(e->rect(), _background); // Paint the background _draw_background = false; } @@ -248,14 +246,13 @@ int i; drawFunction(); // Draw the Function on a Pixmap _draw_function = false; } - p.drawPixmap(0, 0, _function); // Always draw the background and the function - - QPen pen(Qt::white, 1, Qt::SolidLine); + p.drawPixmap(e->rect(), _function); // Always draw the background and the function // // Draw the Points, that make up the Curve // if (_config) { + QPen pen(Qt::white, 1, Qt::SolidLine); QList points = _config->getPoints(); // // When moving, also draw a sketched version of the Function. @@ -304,12 +301,13 @@ int i; // // Draw the delimiters // +#if 0 pen.setWidth(1); pen.setColor( Qt::white ); pen.setStyle( Qt::SolidLine ); drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); - +#endif //QTimer::singleShot(50, this, SLOT(update())); } @@ -360,6 +358,7 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) bTouchingPoint = true; movingPoint = i; timer.restart(); + setMouseTracking(true); break; } } @@ -400,9 +399,9 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) emit CurveChanged( true ); } movingPoint = -1; + setMouseTracking(false); } } - _draw_function = _draw_background = true; update(); } @@ -459,6 +458,7 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) QList points = _config->getPoints(); if (e->button() == Qt::LeftButton) { + setMouseTracking(false); timer.invalidate(); //qDebug()<<"releasing"; if (movingPoint >= 0 && movingPoint < points.size()) { diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 1ac919fe..35f06a0d 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -112,7 +112,7 @@ protected slots: void mouseReleaseEvent(QMouseEvent *e); protected: - void drawBackground(const QRectF &); + 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); -- cgit v1.2.3 From b47421b6b86aed973bc35407dfe2a44c977bd968 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 17 Oct 2013 20:41:38 +0200 Subject: Now that mouse tracking is gone, increase point bbox Signed-off-by: Stanislaw Halik --- qfunctionconfigurator/qfunctionconfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 0b4df033..1d401ddd 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -486,7 +486,7 @@ bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coor { QRectF rect(pos.x() - pointSize, pos.y() - pointSize, - pointSize*2, pointSize*2); + pointSize*3, pointSize*3); QPainterPath path; path.addEllipse(rect); return path.contains(coord); -- cgit v1.2.3 From 4461b2971abb43a8f93989e6adf61c01f91fa973 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 19 Oct 2013 17:26:17 +0200 Subject: bah, stupido (valgrind) Signed-off-by: Stanislaw Halik --- facetracknoir/tracker.h | 2 +- qfunctionconfigurator/functionconfig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/tracker.h b/facetracknoir/tracker.h index 5f5ab1dc..24a22c16 100644 --- a/facetracknoir/tracker.h +++ b/facetracknoir/tracker.h @@ -129,7 +129,7 @@ public: { for (int i = 0; i < 6; i++) { - delete[] axes[i]; + delete axes[i]; } } }; diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index b6257df2..4f48096a 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -37,7 +37,7 @@ public: // FunctionConfig(); FunctionConfig(QString title, int intMaxInput, int intMaxOutput); - virtual ~FunctionConfig(); + ~FunctionConfig(); float getValue(float x); bool getLastPoint(QPointF& point); // Get the last Point that was requested. -- cgit v1.2.3 From dd41b87d6029d2accd3c32ea71873beefaebb149 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 25 Oct 2013 15:29:53 +0200 Subject: don't flood stderr with each and every qfc Signed-off-by: Stanislaw Halik --- qfunctionconfigurator/functionconfig.cpp | 3 --- qfunctionconfigurator/qfunctionconfigurator.cpp | 5 ----- 2 files changed, 8 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index f9c9957e..b937d95e 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -16,7 +16,6 @@ #include #include #include -#include // // Constructor with List of Points in argument. @@ -235,8 +234,6 @@ void FunctionConfig::loadSettings(QSettings& settings) { int max = settings.value("point-count", 0).toInt(); - qDebug() << _title << "count" << max; - for (int i = 0; i < max; i++) { newPoint = QPointF(settings.value(QString("point-%1-x").arg(i), (i + 1) * _max_Input/2).toFloat(), settings.value(QString("point-%1-y").arg(i), (i + 1) * _max_Output/2).toFloat()); diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 1d401ddd..afd6561b 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -69,7 +69,6 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); setCaption(config->getTitle()); _draw_function = _draw_background = true; @@ -83,7 +82,6 @@ void QFunctionConfigurator::loadSettings(QString settingsFile) { QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; if (_config) { _config->loadSettings(iniFile); } @@ -95,7 +93,6 @@ void QFunctionConfigurator::loadSettings(QString settingsFile) { void QFunctionConfigurator::saveSettings(QString settingsFile) { QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) strSettingsFile = settingsFile; // Remember for Reset() - qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile; if (_config) { _config->saveSettings(iniFile); @@ -617,8 +614,6 @@ void QFunctionConfigurator::resizeEvent(QResizeEvent *) { range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); - qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range; - _draw_background = true; _draw_function = true; repaint(); -- cgit v1.2.3 From ef0d7dcf585a7a6b807d2a287dfbdc59657a30cc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 5 Nov 2013 08:59:40 +0100 Subject: fix potential crash Signed-off-by: Stanislaw Halik --- qfunctionconfigurator/qfunctionconfigurator.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index afd6561b..a80e3b6b 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -337,6 +337,8 @@ void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, co // void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) { + if (!_config) + return; QList points = _config->getPoints(); // @@ -409,6 +411,8 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) // void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) { + if (!_config) + return; QList points = _config->getPoints(); const int refresh_delay = 50; @@ -452,6 +456,8 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) { + if (!_config) + return; QList points = _config->getPoints(); if (e->button() == Qt::LeftButton) { -- cgit v1.2.3 From 51c93f8c6c7c9d84634c0e840281373bbe25a89c Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 26 Dec 2013 01:36:41 +0100 Subject: qfc: reenable mouse tracking all the time --- qfunctionconfigurator/qfunctionconfigurator.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index a80e3b6b..4ad0a9a4 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -52,6 +52,8 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) _draw_background = true; _draw_function = true; + setMouseTracking(true); + // qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created."; } @@ -357,7 +359,6 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) bTouchingPoint = true; movingPoint = i; timer.restart(); - setMouseTracking(true); break; } } @@ -398,7 +399,6 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) emit CurveChanged( true ); } movingPoint = -1; - setMouseTracking(false); } } _draw_function = _draw_background = true; @@ -461,7 +461,6 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) QList points = _config->getPoints(); if (e->button() == Qt::LeftButton) { - setMouseTracking(false); timer.invalidate(); //qDebug()<<"releasing"; if (movingPoint >= 0 && movingPoint < points.size()) { @@ -489,7 +488,7 @@ bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coor { QRectF rect(pos.x() - pointSize, pos.y() - pointSize, - pointSize*3, pointSize*3); + pointSize*M_PI, pointSize*M_PI); QPainterPath path; path.addEllipse(rect); return path.contains(coord); -- cgit v1.2.3 From 4350b676bd4fd94dd5cfd10a664ac666d459ddbc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 26 Dec 2013 01:38:12 +0100 Subject: while here, allow floats as qfc resolution --- qfunctionconfigurator/qfunctionconfigurator.h | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 35f06a0d..dccd4601 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -26,12 +26,12 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget { Q_OBJECT - Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU) - Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU) - Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input) - Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output) - Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input) - Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output) + Q_PROPERTY(double maxInputEGU READ maxInputEGU WRITE setmaxInputEGU) + Q_PROPERTY(double maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU) + Q_PROPERTY(double pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input) + Q_PROPERTY(double pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output) + Q_PROPERTY(double gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input) + Q_PROPERTY(double gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output) Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier) Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU) @@ -39,27 +39,27 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption) // Return the current value to Designer - int maxInputEGU() const + double maxInputEGU() const { return MaxInput; } - int maxOutputEGU() const + double maxOutputEGU() const { return MaxOutput; } - int pixPerEGU_Input() const + double pixPerEGU_Input() const { return pPerEGU_Input; } - int pixPerEGU_Output() const + double pixPerEGU_Output() const { return pPerEGU_Output; } - int gridDistEGU_Input() const + double gridDistEGU_Input() const { return gDistEGU_Input; } - int gridDistEGU_Output() const + double gridDistEGU_Output() const { return gDistEGU_Output; } @@ -131,12 +131,12 @@ private: int movingPoint; QElapsedTimer timer; - int MaxInput; // Maximum input limit - int MaxOutput; // Maximum output limit - int pPerEGU_Input; // Number of pixels, per EGU of Input - int pPerEGU_Output; // Number of pixels, per EGU of Output - int gDistEGU_Input; // Distance of the grid, in EGU of Input - int gDistEGU_Output; // Distance of the grid, in EGU of Output + double MaxInput; // Maximum input limit + double MaxOutput; // Maximum output limit + double pPerEGU_Input; // Number of pixels, per EGU of Input + double pPerEGU_Output; // Number of pixels, per EGU of Output + double gDistEGU_Input; // Distance of the grid, in EGU of Input + double gDistEGU_Output; // Distance of the grid, in EGU of Output QColor colBezier; // Color of Bezier curve QString strInputEGU; // Engineering Units input (vertical axis) -- cgit v1.2.3 From fd3d77ecd23a605822890cf049077114cda3368a Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 26 Dec 2013 01:41:17 +0100 Subject: qfc: prevent default to nonsense on broken config --- qfunctionconfigurator/functionconfig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cpp index b937d95e..97a6db24 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp @@ -235,8 +235,8 @@ void FunctionConfig::loadSettings(QSettings& settings) { 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), (i + 1) * _max_Input/2).toFloat(), - settings.value(QString("point-%1-y").arg(i), (i + 1) * _max_Output/2).toFloat()); + 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? -- cgit v1.2.3 From 84e82b6c56d74d75834328b9495e9c1d81510fed Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 26 Dec 2013 01:42:55 +0100 Subject: qfc: use saner sub-degree precision value --- qfunctionconfigurator/functionconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index 4f48096a..a8bb3371 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -15,7 +15,7 @@ #include #include "ftnoir_tracker_base/ftnoir_tracker_base.h" -#define MEMOIZE_PRECISION 500 +#define MEMOIZE_PRECISION 100 class FTNOIR_TRACKER_BASE_EXPORT FunctionConfig { private: -- cgit v1.2.3 From 379137fcf8fda2fd480d467f82bf072523e707aa Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 31 Dec 2013 08:42:51 +0100 Subject: qfc: delete copy ctor --- qfunctionconfigurator/functionconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index a8bb3371..d809259b 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -30,7 +30,7 @@ private: volatile bool _tracking_active; int _max_Input; int _max_Output; - FunctionConfig(const FunctionConfig&) {} + FunctionConfig(const FunctionConfig&) = delete; public: // // Contructor(s) and destructor -- cgit v1.2.3 From 9f0ba65825054b182d9a9c2b53dad955a90d4df1 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 1 Jan 2014 13:40:41 +0100 Subject: base spline widget size on config size --- facetracknoir/ftnoir_curves.ui | 12 ++++++------ qfunctionconfigurator/functionconfig.h | 2 ++ qfunctionconfigurator/qfunctionconfigurator.cpp | 7 +++++-- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index f96df044..9b5c8d07 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -325,7 +325,7 @@ 100 - 7 + 28 2 @@ -374,7 +374,7 @@ 100 - 7 + 28 2 @@ -415,7 +415,7 @@ 100 - 7 + 28 2 @@ -464,7 +464,7 @@ 100 - 7 + 28 2 @@ -505,7 +505,7 @@ 100 - 7 + 28 2 @@ -554,7 +554,7 @@ 100 - 7 + 28 2 diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index d809259b..ab2d0d0c 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -32,6 +32,8 @@ private: int _max_Output; FunctionConfig(const FunctionConfig&) = delete; public: + const int maxInput() const { return _max_Input; } + const int maxOutput() const { return _max_Output; } // // Contructor(s) and destructor // diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 4ad0a9a4..5a02a826 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -31,8 +31,7 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) // // Defaults, for when the widget has no values different from the domXML() // - MaxInput = 50; // Maximum input limit - MaxOutput = 180; // Maximum output limit + pPerEGU_Output = 1; // Number of pixels, per EGU pPerEGU_Input = 4; // Number of pixels, per EGU gDistEGU_Input = 5; // Distance of gridlines @@ -74,6 +73,10 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi setCaption(config->getTitle()); _draw_function = _draw_background = true; + + setmaxInputEGU(config->maxInput()); + setmaxOutputEGU(config->maxOutput()); + this->update(); } -- cgit v1.2.3 From 44162ed05648e68bd07dfcb35e86b6a18b3d3372 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 1 Jan 2014 13:50:44 +0100 Subject: one const too many --- qfunctionconfigurator/functionconfig.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.h index ab2d0d0c..4d771dfd 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h @@ -32,8 +32,8 @@ private: int _max_Output; FunctionConfig(const FunctionConfig&) = delete; public: - const int maxInput() const { return _max_Input; } - const int maxOutput() const { return _max_Output; } + int maxInput() const { return _max_Input; } + int maxOutput() const { return _max_Output; } // // Contructor(s) and destructor // -- cgit v1.2.3 From a95b9c206231cb7749648574b31c06b17a5a41d0 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 12 Jan 2014 14:19:36 +0100 Subject: qfc: simplify --- qfunctionconfigurator/qfunctionconfigurator.cpp | 59 +++++++------------------ qfunctionconfigurator/qfunctionconfigurator.h | 1 - 2 files changed, 17 insertions(+), 43 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 5a02a826..cd79f23a 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -370,10 +370,8 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) // If the Left Mouse-button was clicked without touching a Point, add a new Point // if (!bTouchingPoint) { - if (withinRect(e->pos(), range)) { - _config->addPoint(normalizePoint(e->pos())); - emit CurveChanged( true ); - } + _config->addPoint(normalizePoint(e->pos())); + emit CurveChanged( true ); } } } @@ -433,26 +431,20 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) } } else { - if (withinRect(e->pos(), rect())) - { - // - // Check to see if the cursor is touching one of the points. - // - bool bTouchingPoint = false; - if (_config) { - for (int i = 0; i < points.size(); i++) { - if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { - bTouchingPoint = true; - } + bool bTouchingPoint = false; + if (_config) { + for (int i = 0; i < points.size(); i++) { + if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + bTouchingPoint = true; } } + } - if ( bTouchingPoint ) { - setCursor(Qt::OpenHandCursor); - } - else { - setCursor(Qt::ArrowCursor); - } + if ( bTouchingPoint ) { + setCursor(Qt::OpenHandCursor); + } + else { + setCursor(Qt::ArrowCursor); } } } @@ -489,22 +481,10 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) // bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const { - QRectF rect(pos.x() - pointSize, - pos.y() - pointSize, - pointSize*M_PI, pointSize*M_PI); - QPainterPath path; - path.addEllipse(rect); - return path.contains(coord); + return coord.x() >= pos.x() - pointSize && coord.x() < pos.x() + pointSize && + coord.y() >= pos.y() - pointSize && coord.y() < pos.y() + pointSize; } -bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect ) const -{ - QPainterPath path; - path.addRect(rect); - return path.contains(coord); -} - -// // Convert the Point in the graph, to the real-life Point. // QPointF QFunctionConfigurator::normalizePoint(QPointF point) const @@ -533,8 +513,8 @@ QPointF QFunctionConfigurator::graphicalizePoint(QPointF point) const { QPointF graph; - graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) ); - graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) ); + graph.setX( range.left() + point.x() * pPerEGU_Input); + graph.setY( range.bottom() - point.y() * pPerEGU_Output); return graph; } @@ -542,14 +522,11 @@ QPointF graph; void QFunctionConfigurator::setmaxInputEGU(int value) { MaxInput = value; - setMinimumWidth(MaxInput * pPerEGU_Input + 55); -// resetCurve(); resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } void QFunctionConfigurator::setmaxOutputEGU(int value) { MaxOutput = value; - setMinimumHeight(MaxOutput * pPerEGU_Output + 60); // resetCurve(); resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } @@ -560,7 +537,6 @@ void QFunctionConfigurator::setmaxOutputEGU(int value) void QFunctionConfigurator::setpixPerEGU_Input(int value) { pPerEGU_Input = value; - setMinimumWidth(MaxInput * pPerEGU_Input + 55); resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } @@ -570,7 +546,6 @@ void QFunctionConfigurator::setpixPerEGU_Input(int value) void QFunctionConfigurator::setpixPerEGU_Output(int value) { pPerEGU_Output = value; - setMinimumHeight(MaxOutput * pPerEGU_Output + 60); resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index dccd4601..84f4ad8b 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -117,7 +117,6 @@ protected: void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); bool markContains(const QPointF &pt, const QPointF &coord) const; - bool withinRect( const QPointF &coord, const QRectF &rect ) const; protected: virtual void resizeEvent(QResizeEvent *); -- cgit v1.2.3 From c4fd758f368972ecf49e8e1828409488919ead02 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 12 Jan 2014 16:08:52 +0100 Subject: refactor QFC --- qfunctionconfigurator/qfunctionconfigurator.cpp | 415 +++++++----------------- qfunctionconfigurator/qfunctionconfigurator.h | 92 +----- 2 files changed, 132 insertions(+), 375 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index cd79f23a..755e2f9c 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -21,97 +21,52 @@ #include #include #include +#include static const int pointSize = 5; QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) : QWidget(parent) { - - // - // Defaults, for when the widget has no values different from the domXML() - // - - pPerEGU_Output = 1; // Number of pixels, per EGU - pPerEGU_Input = 4; // Number of pixels, per EGU - gDistEGU_Input = 5; // Distance of gridlines - gDistEGU_Output = 10; // Distance of gridlines - - - // Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output) - // This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) - range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); - movingPoint = -1; // Index of that same point - - // - // Variables for FunctionConfig - // _config = 0; _draw_background = true; _draw_function = true; - + update_range(); setMouseTracking(true); - -// qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created."; - } -// -// Attach an existing FunctionConfig to the Widget. -// void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { 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) - config->loadSettings(iniFile); + config->loadSettings(iniFile); _config = config; - - strSettingsFile = settingsFile; // Remember for Reset() - - setCaption(config->getTitle()); - _draw_function = _draw_background = true; - - setmaxInputEGU(config->maxInput()); - setmaxOutputEGU(config->maxOutput()); - this->update(); } -// -// Load the FunctionConfig (points) from the INI-file. -// void QFunctionConfigurator::loadSettings(QString settingsFile) { QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - strSettingsFile = settingsFile; // Remember for Reset() if (_config) { _config->loadSettings(iniFile); } } -// -// Save the FunctionConfig (points) to the INI-file. -// void QFunctionConfigurator::saveSettings(QString settingsFile) { QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - strSettingsFile = settingsFile; // Remember for Reset() if (_config) { _config->saveSettings(iniFile); } } -// -// Draw the Background for the graph, the gridlines and the gridpoints. -// The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up... -// void QFunctionConfigurator::drawBackground() { - int i; - QRect scale; + if (!_config) + return; _background = QPixmap(width(), height()); QPainter painter(&_background); painter.fillRect(rect(), QColor::fromRgb(204, 204, 204)); @@ -122,87 +77,94 @@ void QFunctionConfigurator::drawBackground() QFont font; font.setPointSize(8); painter.setFont(font); + QFontMetrics metrics(font); QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine); - // - // Draw the Caption - // - if (_config) { - strCaption = _config->getTitle(); + const int xstep = 10, ystep = 10; + const int maxx = _config->maxInput(); + const int maxy = _config->maxOutput(); + + // horizontal grid + + for (int i = 0; i < maxx; i += xstep) + { + double y = range.height() - i * c.y() + range.y(); + drawLine(&painter, + QPointF(range.x(), y), + QPointF(range.x() + range.width(), y), + pen); + painter.drawText(QRectF(10, + y - metrics.height()/2, + range.left(), + metrics.height()), + QString::number(i)); } - scale.setCoords(range.left(), 0, range.right(), 20); - painter.drawText(scale, Qt::AlignCenter, strCaption); - - // - // Draw the horizontal grid - // - for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) { - drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen); - scale.setCoords(0, i - 5, range.left() - 5, i + 5); - painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output)); + { + const int i = maxx; + double y = range.height() - i * c.y() + range.y(); + drawLine(&painter, + QPointF(range.x(), y), + QPointF(range.x() + range.width(), y), + pen); + painter.drawText(QRectF(10, + y - metrics.height()/2, + range.x() - 10, + metrics.height()), + QString::number(i)); } - // - // Draw the vertical guidelines - // - for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) { - drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen); - scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15); - painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input))); + // vertical grid + + for (int i = 0; i < maxy; i += ystep) + { + double x = range.x() + i * c.x(); + drawLine(&painter, + QPointF(x, range.y()), + QPointF(x, range.y() + range.height()), + pen); + const QString text = QString::number(i); + painter.drawText(QRectF(x - metrics.width(text)/2, + range.height() + 10 + metrics.height(), + metrics.width(text), + metrics.height()), + text); + } + { + const int i = maxy; + double x = range.x() + i * c.x(); + drawLine(&painter, + QPointF(x, range.y()), + QPointF(x, range.y() + range.height()), + pen); + const QString text = QString::number(i); + painter.drawText(QRectF(x - metrics.width(text)/2, + range.height() + 10 + metrics.height(), + metrics.width(text), + metrics.height()), + text); } - - scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35); - painter.drawText(scale, Qt::AlignRight, strInputEGU); - - // - // Draw the EGU of the vertical axis (vertically!) - // - font.setPointSize(10); - painter.translate(range.topLeft().x() - 35, range.topLeft().y()); - painter.rotate(90); - painter.drawText(0,0,strOutputEGU ); - - // - // Draw the two axis - // - pen.setWidth(2); - pen.setColor( Qt::black ); - drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); - drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); } - -// -// Draw the Function for the graph, on a Pixmap. -// void QFunctionConfigurator::drawFunction() { if (!_config) return; -int i; -QPointF prevPoint; -QPointF currentPoint; - - // - // Use the background picture to draw on. - // ToDo: find out how to add Pixmaps, without getting it all green... - // + int i; + QPointF prevPoint; + QPointF currentPoint; + _function = QPixmap(_background); QPainter painter(&_function); painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); - // - // Draw the handles for the Points - // - QList points = _config->getPoints(); for (i = 0; i < points.size(); i++) { - currentPoint = graphicalizePoint( points[i] ); // Get the next point and convert it to Widget measures + 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 } @@ -210,39 +172,34 @@ QPointF currentPoint; QPen pen(colBezier, 1.2, Qt::SolidLine); - prevPoint = graphicalizePoint( QPointF(0,0) ); // Start at the Axis - double max = maxInputEGU(); - QPointF prev = graphicalizePoint(QPointF(0, 0)); + prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis + 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 = graphicalizePoint(QPointF(i, val)); + QPointF cur = point_to_pixel(QPointF(i, val)); drawLine(&painter, prev, cur, pen); prev = cur; } painter.restore(); } -// -// The Widget paints the surface every x msecs. -// void QFunctionConfigurator::paintEvent(QPaintEvent *e) { -QPointF prevPoint; -QPointF currentPoint; -QPointF actualPos; -int i; - -// qDebug() << "QFunctionConfigurator::paintEvent."; + QPointF prevPoint; + QPointF currentPoint; + QPointF actualPos; + int i; QPainter p(this); p.setRenderHint(QPainter::Antialiasing); if (_draw_background) { - drawBackground(); // Draw the static parts on a Pixmap - p.drawPixmap(e->rect(), _background); // Paint the background + drawBackground(); _draw_background = false; } + p.drawPixmap(e->rect(), _background); if (_draw_function) { drawFunction(); // Draw the Function on a Pixmap @@ -250,33 +207,22 @@ int i; } p.drawPixmap(e->rect(), _function); // Always draw the background and the function - // - // Draw the Points, that make up the Curve - // if (_config) { QPen pen(Qt::white, 1, Qt::SolidLine); QList points = _config->getPoints(); - // - // When moving, also draw a sketched version of the Function. - // if (movingPoint >= 0 && movingPoint < points.size()) { - prevPoint = graphicalizePoint( QPointF(0,0) ); // Start at the Axis + prevPoint = point_to_pixel( QPointF(0,0) ); // Start at the Axis for (i = 0; i < points.size(); i++) { - currentPoint = graphicalizePoint( points[i] ); // Get the next point and convert it to Widget measures + currentPoint = point_to_pixel( points[i] ); // Get the next point and convert it to Widget measures drawLine(&p, prevPoint, currentPoint, pen); prevPoint = currentPoint; -// qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint; } - - // - // When moving, also draw a few help-lines, so positioning the point gets easier. - // pen.setWidth(1); pen.setColor( Qt::white ); pen.setStyle( Qt::DashLine ); - actualPos = graphicalizePoint(points[movingPoint]); + 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.bottom()), pen); + drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.height() + range.top()), pen); } // @@ -285,32 +231,17 @@ int i; // This new feature is very handy for tweaking the curves! // if (_config->getLastPoint( currentPoint )) { - -// qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint; - - actualPos = graphicalizePoint( currentPoint ); + actualPos = point_to_pixel( currentPoint ); drawPoint(&p, actualPos, 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.bottom()), pen); + drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.width()), pen); } } - - // - // Draw the delimiters - // -#if 0 - pen.setWidth(1); - pen.setColor( Qt::white ); - pen.setStyle( Qt::SolidLine ); - drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); - drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); -#endif - //QTimer::singleShot(50, this, SLOT(update())); } // @@ -336,65 +267,40 @@ void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, co painter->restore(); } -// -// If the mousebutton is pressed, check if it is inside one of the Points. -// If so: start moving that Point, until mouse release. -// void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) { if (!_config) return; QList points = _config->getPoints(); - - // - // First: check the left mouse-button - // if (e->button() == Qt::LeftButton) { - - // - // Check to see if the cursor is touching one of the points. - // bool bTouchingPoint = false; movingPoint = -1; if (_config) { for (int i = 0; i < points.size(); i++) { - if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + if ( point_within_pixel(points[i], e->pos() ) ) { bTouchingPoint = true; movingPoint = i; timer.restart(); break; } } - - // - // If the Left Mouse-button was clicked without touching a Point, add a new Point - // if (!bTouchingPoint) { - _config->addPoint(normalizePoint(e->pos())); + _config->addPoint(pixel_coord_to_point(e->pos())); emit CurveChanged( true ); } } } - // Then: check the right mouse-button - // if (e->button() == Qt::RightButton) { - - // - // Check to see if the cursor is touching one of the points. - // if (_config) { int found_pt = -1; for (int i = 0; i < points.size(); i++) { - if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + if ( point_within_pixel(points[i], e->pos() ) ) { found_pt = i; break; } } - // - // If the Right Mouse-button was clicked while touching a Point, remove the Point - // if (found_pt != -1) { _config->removePoint(found_pt); emit CurveChanged( true ); @@ -402,14 +308,10 @@ void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) movingPoint = -1; } } - _draw_function = _draw_background = true; + _draw_function = true; update(); } -// -// If the mouse if moving, make sure the Bezier moves along. -// Of course, only when a Point is selected... -// void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) { if (!_config) @@ -423,10 +325,10 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) if (timer.isValid() && timer.elapsed() > refresh_delay) { timer.restart(); - QPointF new_pt = normalizePoint(e->pos()); + QPointF new_pt = pixel_coord_to_point(e->pos()); points[movingPoint] = new_pt; _config->movePoint(movingPoint, new_pt); - _draw_function = _draw_background = true; + _draw_function = true; update(); } } @@ -434,7 +336,7 @@ void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) bool bTouchingPoint = false; if (_config) { for (int i = 0; i < points.size(); i++) { - if ( markContains( graphicalizePoint( points[i] ), e->pos() ) ) { + if ( point_within_pixel(points[i], e->pos() ) ) { bTouchingPoint = true; } } @@ -457,118 +359,52 @@ void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) if (e->button() == Qt::LeftButton) { timer.invalidate(); - //qDebug()<<"releasing"; if (movingPoint >= 0 && movingPoint < points.size()) { emit CurveChanged( true ); - - // - // Update the Point in the _config - // if (_config) { - _config->movePoint(movingPoint, normalizePoint(e->pos())); + _config->movePoint(movingPoint, pixel_coord_to_point(e->pos())); } } setCursor(Qt::ArrowCursor); movingPoint = -1; } - _draw_function = _draw_background = true; + _draw_function = true; update(); } -// -// Determine if the mousebutton was pressed within the range of the Point. -// -bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const +bool QFunctionConfigurator::point_within_pixel(QPointF pt, QPointF pixel) const { - return coord.x() >= pos.x() - pointSize && coord.x() < pos.x() + pointSize && - coord.y() >= pos.y() - pointSize && coord.y() < pos.y() + pointSize; -} - -// Convert the Point in the graph, to the real-life Point. -// -QPointF QFunctionConfigurator::normalizePoint(QPointF point) const -{ - QPointF norm; - - norm.setX( (point.x() - range.left()) / pPerEGU_Input ); - norm.setY( (range.bottom() - point.y()) / pPerEGU_Output ); - - if (norm.x() > maxInputEGU()) - norm.setX(maxInputEGU()); - else if (norm.x() < 0) - norm.setX(0); - if (norm.y() > maxOutputEGU()) - norm.setY(maxOutputEGU()); - else if (norm.y() < 0) - norm.setY(0); - - return norm; + QPointF pixel2(range.x() + pt.x() * c.x(), (range.y() + range.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; } -// -// Convert the real-life Point into the graphical Point. -// -QPointF QFunctionConfigurator::graphicalizePoint(QPointF point) const +QPointF QFunctionConfigurator::pixel_coord_to_point(QPointF point) const { -QPointF graph; - - graph.setX( range.left() + point.x() * pPerEGU_Input); - graph.setY( range.bottom() - point.y() * pPerEGU_Output); - - return graph; -} + if (!_config) + return QPointF(-1, -1); -void QFunctionConfigurator::setmaxInputEGU(int value) -{ - MaxInput = value; - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); -} -void QFunctionConfigurator::setmaxOutputEGU(int value) -{ - MaxOutput = value; -// resetCurve(); - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); -} + double x = (point.x() - range.x()) / c.x(); + double y = (range.height() - point.y() + range.y()) / c.y(); -// -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. -// -void QFunctionConfigurator::setpixPerEGU_Input(int value) -{ - pPerEGU_Input = value; - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); -} + if (x < 0) + x = 0; + if (x > _config->maxInput()) + x = _config->maxInput(); -// -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. -// -void QFunctionConfigurator::setpixPerEGU_Output(int value) -{ - pPerEGU_Output = value; - resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); -} + if (y < 0) + y = 0; + if (y > _config->maxOutput()) + y = _config->maxOutput(); -// -// Define the distance of the grid 'in EGU' points. -// -void QFunctionConfigurator::setgridDistEGU_Input(int value) -{ - gDistEGU_Input = value; - _draw_background = true; - _draw_function = true; - repaint(); + return QPointF(x, y); } -// -// Define the distance of the grid 'in EGU' points. -// -void QFunctionConfigurator::setgridDistEGU_Output(int value) +QPointF QFunctionConfigurator::point_to_pixel(QPointF point) const { - gDistEGU_Output = value; - _draw_background = true; - _draw_function = true; - repaint(); + return QPointF(range.x() + point.x() * c.x(), + range.y() + range.height() - point.y() * c.y()); } void QFunctionConfigurator::setColorBezier(QColor color) @@ -577,27 +413,10 @@ void QFunctionConfigurator::setColorBezier(QColor color) update(); } -void QFunctionConfigurator::setInputEGU(QString egu) -{ - strInputEGU = egu; - update(); -} -void QFunctionConfigurator::setOutputEGU(QString egu) -{ - strOutputEGU = egu; - update(); -} -void QFunctionConfigurator::setCaption(QString cap) -{ - strCaption = cap; - update(); -} - void QFunctionConfigurator::resizeEvent(QResizeEvent *) { - range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); - _draw_background = true; _draw_function = true; + update_range(); repaint(); } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 84f4ad8b..17cb3a44 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -25,62 +25,11 @@ class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget { Q_OBJECT - - Q_PROPERTY(double maxInputEGU READ maxInputEGU WRITE setmaxInputEGU) - Q_PROPERTY(double maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU) - Q_PROPERTY(double pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input) - Q_PROPERTY(double pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output) - Q_PROPERTY(double gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input) - Q_PROPERTY(double gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output) - Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier) - Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU) - Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU) - Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption) - - // Return the current value to Designer - double maxInputEGU() const - { - return MaxInput; - } - double maxOutputEGU() const - { - return MaxOutput; - } - double pixPerEGU_Input() const - { - return pPerEGU_Input; - } - double pixPerEGU_Output() const - { - return pPerEGU_Output; - } - double gridDistEGU_Input() const - { - return gDistEGU_Input; - } - double gridDistEGU_Output() const - { - return gDistEGU_Output; - } - - QColor colorBezier() const + QColor colorBezier() const { return colBezier; } - QString stringInputEGU() const - { - return strInputEGU; - } - QString stringOutputEGU() const - { - return strOutputEGU; - } - QString stringCaption() const - { - return strCaption; - } - public: QFunctionConfigurator(QWidget *parent = 0); FunctionConfig* config(); @@ -93,18 +42,7 @@ signals: void CurveChanged(bool); public slots: - void setmaxInputEGU(int); - void setmaxOutputEGU(int); - void setpixPerEGU_Input(int); - void setpixPerEGU_Output(int); - void setgridDistEGU_Input(int); - void setgridDistEGU_Output(int); - void setColorBezier(QColor); - void setInputEGU(QString); - void setOutputEGU(QString); - void setCaption(QString); - protected slots: void paintEvent(QPaintEvent *e); void mousePressEvent(QMouseEvent *e); @@ -116,32 +54,32 @@ protected: void drawFunction(); void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); - bool markContains(const QPointF &pt, const QPointF &coord) const; + bool point_within_pixel(QPointF pt, QPointF pixel) const; protected: virtual void resizeEvent(QResizeEvent *); 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()); + } + QRectF range; // The actual rectangle for the Bezier-curve QPointF lastPoint; // The right-most point of the Function - QPointF normalizePoint (QPointF point) const; // Convert the graphical Point to a real-life Point - QPointF graphicalizePoint (QPointF point) const; // Convert the Point to a graphical Point + 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 int movingPoint; QElapsedTimer timer; - - double MaxInput; // Maximum input limit - double MaxOutput; // Maximum output limit - double pPerEGU_Input; // Number of pixels, per EGU of Input - double pPerEGU_Output; // Number of pixels, per EGU of Output - double gDistEGU_Input; // Distance of the grid, in EGU of Input - double gDistEGU_Output; // Distance of the grid, in EGU of Output + QPointF c; QColor colBezier; // Color of Bezier curve - QString strInputEGU; // Engineering Units input (vertical axis) - QString strOutputEGU; // Engineering Units output (horizontal axis) - QString strCaption; // Caption of the graph - QString strSettingsFile; // Name of last read INI-file 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.) -- cgit v1.2.3 From 6d6d15e1b328ec5c0469f8bc142848715b1491e8 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 12 Jan 2014 16:22:42 +0100 Subject: fix qfc display artifacts & bugs --- facetracknoir/ftnoir_curves.ui | 48 ++++++++++++------------- qfunctionconfigurator/qfunctionconfigurator.cpp | 13 ++++--- qfunctionconfigurator/qfunctionconfigurator.h | 1 + 3 files changed, 31 insertions(+), 31 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/ftnoir_curves.ui b/facetracknoir/ftnoir_curves.ui index 04ff7887..195083b9 100644 --- a/facetracknoir/ftnoir_curves.ui +++ b/facetracknoir/ftnoir_curves.ui @@ -50,8 +50,8 @@ 0 0 - 921 - 240 + 930 + 260 @@ -96,8 +96,8 @@ 0 300 - 975 - 206 + 930 + 260 @@ -134,8 +134,8 @@ 0 0 - 595 - 240 + 930 + 260 @@ -183,8 +183,8 @@ 0 300 - 1013 - 240 + 930 + 260 @@ -224,8 +224,8 @@ 0 0 - 595 - 240 + 930 + 260 @@ -273,8 +273,8 @@ 0 300 - 595 - 240 + 930 + 260 @@ -314,8 +314,8 @@ 0 0 - 555 - 160 + 930 + 260 @@ -363,8 +363,8 @@ 0 300 - 555 - 160 + 930 + 260 @@ -404,8 +404,8 @@ 0 0 - 555 - 160 + 930 + 260 @@ -453,8 +453,8 @@ 0 300 - 555 - 160 + 930 + 260 @@ -494,8 +494,8 @@ 0 0 - 555 - 160 + 930 + 260 @@ -543,8 +543,8 @@ 0 300 - 555 - 160 + 930 + 260 diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 755e2f9c..6540e66f 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -44,7 +44,8 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi config->loadSettings(iniFile); _config = config; _draw_function = _draw_background = true; - this->update(); + update_range(); + update(); } void QFunctionConfigurator::loadSettings(QString settingsFile) { @@ -87,7 +88,7 @@ void QFunctionConfigurator::drawBackground() // horizontal grid - for (int i = 0; i < maxx; i += xstep) + for (int i = 0; i < maxy; i += xstep) { double y = range.height() - i * c.y() + range.y(); drawLine(&painter, @@ -102,7 +103,7 @@ void QFunctionConfigurator::drawBackground() } { - const int i = maxx; + const int i = maxy; double y = range.height() - i * c.y() + range.y(); drawLine(&painter, QPointF(range.x(), y), @@ -117,7 +118,7 @@ void QFunctionConfigurator::drawBackground() // vertical grid - for (int i = 0; i < maxy; i += ystep) + for (int i = 0; i < maxx; i += ystep) { double x = range.x() + i * c.x(); drawLine(&painter, @@ -132,7 +133,7 @@ void QFunctionConfigurator::drawBackground() text); } { - const int i = maxy; + const int i = maxx; double x = range.x() + i * c.x(); drawLine(&painter, QPointF(x, range.y()), @@ -415,8 +416,6 @@ void QFunctionConfigurator::setColorBezier(QColor color) void QFunctionConfigurator::resizeEvent(QResizeEvent *) { - _draw_background = true; - _draw_function = true; update_range(); repaint(); } diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index 17cb3a44..bb2aced0 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -68,6 +68,7 @@ private: 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; } QRectF range; // The actual rectangle for the Bezier-curve -- cgit v1.2.3 From 6e822bf3984270ead48249714f2cd77747fc2383 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 12 Jan 2014 18:50:54 +0100 Subject: display current value in qfc correctly --- qfunctionconfigurator/qfunctionconfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qfunctionconfigurator') diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index 6540e66f..b959b56c 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -232,7 +232,7 @@ void QFunctionConfigurator::paintEvent(QPaintEvent *e) // This new feature is very handy for tweaking the curves! // if (_config->getLastPoint( currentPoint )) { - actualPos = point_to_pixel( currentPoint ); + actualPos = point_to_pixel( QPointF(fabs(currentPoint.x()), fabs(currentPoint.y())) ); drawPoint(&p, actualPos, QColor(255, 0, 0, 120)); pen.setWidth(1); -- cgit v1.2.3 From 733b0ff713eb28c7c4b7dab5d3de423f784f2734 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 10 Feb 2014 07:35:59 +0100 Subject: don't load spline config twice --- facetracknoir/curve-config.cpp | 6 ++---- qfunctionconfigurator/qfunctionconfigurator.cpp | 10 +--------- qfunctionconfigurator/qfunctionconfigurator.h | 5 ++--- 3 files changed, 5 insertions(+), 16 deletions(-) (limited to 'qfunctionconfigurator') diff --git a/facetracknoir/curve-config.cpp b/facetracknoir/curve-config.cpp index 1e911ddd..2bff009a 100644 --- a/facetracknoir/curve-config.cpp +++ b/facetracknoir/curve-config.cpp @@ -83,10 +83,8 @@ void CurveConfigurationDialog::loadSettings() { for (int i = 0; i < 6; i++) { - configs[i]->setConfig(&mainApp->axis(i).curve, currentFile); - alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt, currentFile); - configs[i]->loadSettings(currentFile); - alt_configs[i]->loadSettings(currentFile); + configs[i]->setConfig(&mainApp->axis(i).curve); + alt_configs[i]->setConfig(&mainApp->axis(i).curveAlt); } } diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index b959b56c..55d1e1bc 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -36,7 +36,7 @@ QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) setMouseTracking(true); } -void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { +void QFunctionConfigurator::setConfig(FunctionConfig* config) { 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) @@ -48,14 +48,6 @@ void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFi update(); } -void QFunctionConfigurator::loadSettings(QString settingsFile) { - - QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) - if (_config) { - _config->loadSettings(iniFile); - } -} - void QFunctionConfigurator::saveSettings(QString settingsFile) { QSettings iniFile( settingsFile, QSettings::IniFormat ); // Application settings (in INI-file) diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index bb2aced0..1f6b4f78 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -34,9 +34,8 @@ public: QFunctionConfigurator(QWidget *parent = 0); FunctionConfig* config(); - void setConfig(FunctionConfig* config, QString settingsFile); // Connect the FunctionConfig to the Widget. - void loadSettings(QString settingsFile); // Load the FunctionConfig (points) from the INI-file - void saveSettings(QString settingsFile); // Save the FunctionConfig (points) to the INI-file + void setConfig(FunctionConfig* config); + void saveSettings(QString settingsFile); signals: void CurveChanged(bool); -- cgit v1.2.3