void CServerDriver_Hydra::ScanForNewControllers( bool bNotifyServer ) { for ( int base = 0; base < sixenseGetMaxBases(); ++base ) { if ( sixenseIsBaseConnected( base ) ) { sixenseSetActiveBase( base ); for ( int i = 0; i < sixenseGetMaxControllers(); ++i ) { if ( sixenseIsControllerEnabled( i ) ) { char buf[256]; GenerateSerialNumber( buf, sizeof( buf ), base, i ); scope_lock lock( m_Mutex ); if ( !FindTrackedDeviceDriver( buf, vr::ITrackedDeviceServerDriver_Version ) ) { DriverLog( "added new device %s\n", buf ); m_vecControllers.push_back( new CHydraHmdLatest( m_pDriverHost, base, i ) ); if ( bNotifyServer && m_pDriverHost ) { m_pDriverHost->TrackedDeviceAdded( m_vecControllers.back()->GetSerialNumber() ); } } } } } } }
void FlyingMouse::updateHydraData() { #ifdef USE_SIXENSE //int left_index = sixenseUtils::getTheControllerManager()->getIndex(sixenseUtils::ControllerManager::P1L); //int right_index = sixenseUtils::getTheControllerManager()->getIndex(sixenseUtils::ControllerManager::P1R); m_active = false; const int maxBases = sixenseGetMaxBases(); for (int base = 0; base < maxBases; ++base) { sixenseSetActiveBase(base); if (!sixenseIsBaseConnected(base)) continue; sixenseAllControllerData acd; sixenseGetAllNewestData(&acd); const int maxControllers = sixenseGetMaxControllers(); for (int cont = 0; cont < maxControllers; cont++) { if (!sixenseIsControllerEnabled(cont)) continue; m_active = true; const sixenseControllerData& cd = acd.controllers[cont]; float* mtx = mtxL; if (cd.which_hand == 2) mtx = mtxR; mtx[0] = cd.rot_mat[0][0]; mtx[1] = cd.rot_mat[0][1]; mtx[2] = cd.rot_mat[0][2]; mtx[3] = 0.0f; mtx[4] = cd.rot_mat[1][0]; mtx[5] = cd.rot_mat[1][1]; mtx[6] = cd.rot_mat[1][2]; mtx[7] = 0.0f; mtx[ 8] = cd.rot_mat[2][0]; mtx[ 9] = cd.rot_mat[2][1]; mtx[10] = cd.rot_mat[2][2]; mtx[11] = 0.0f; const float posS = 0.001f; // Try to match world space mtx[12] = cd.pos[0] * posS; mtx[13] = cd.pos[1] * posS; mtx[14] = cd.pos[2] * posS; mtx[15] = 1.0f; } g_lastAcd = g_curAcd; g_curAcd = acd; } //sixenseUtils::getTheControllerManager()->update(&acd); #endif // USE_SIXENSE }
void CServerDriver_Hydra::ThreadFunc() { // We know the sixense SDK thread is running at "60 FPS", but we don't know when // those frames are. To minimize latency, we sleep for slightly less than the // target rate, and detect when the frame has not advanced to wait a bit longer. auto longInterval = std::chrono::milliseconds( 16 ); auto retryInterval = std::chrono::milliseconds( 2 ); auto scanInterval = std::chrono::seconds( 1 ); auto pollDeadline = std::chrono::steady_clock::now(); auto scanDeadline = std::chrono::steady_clock::now() + scanInterval; #ifdef _WIN32 // Request at least 2ms timing granularity for the life of this process timeBeginPeriod( 2 ); #endif while ( !m_bStopRequested ) { // Check for new controllers here because sixense API is modal // (e.g. sixenseSetActiveBase()) so it can't happen in parallel with pose updates if ( pollDeadline > scanDeadline ) { ScanForNewControllers( true ); scanDeadline += scanInterval; } bool bAnyActivated = false; bool bAllUpdated = true; for ( int base = 0; base < sixenseGetMaxBases(); ++base ) { if ( !sixenseIsBaseConnected( base ) ) continue; sixenseAllControllerData acd; sixenseSetActiveBase( base ); if ( sixenseGetAllNewestData( &acd ) != SIXENSE_SUCCESS ) continue; for ( int id = 0; id < sixenseGetMaxControllers(); ++id ) { for ( auto it = m_vecControllers.begin(); it != m_vecControllers.end(); ++it ) { CHydraHmdLatest *pHydra = *it; if ( pHydra->IsActivated() && pHydra->HasControllerId( base, id ) ) { bAnyActivated = true; // Returns true if this is new data (so we can sleep for long interval) if ( !pHydra->Update( acd.controllers[id] ) ) { bAllUpdated = false; } break; } } } } CheckForChordedSystemButtons(); // If everyone just got new data, we can wait about 1/60s, else try again soon pollDeadline += !bAnyActivated ? scanInterval : bAllUpdated ? longInterval : retryInterval; std::this_thread::sleep_until( pollDeadline ); } #ifdef _WIN32 timeEndPeriod( 2 ); #endif }
const bool Sixense_MotionController::IsConnected() const { return sixenseIsBaseConnected(m_BaseIndex) != 0; }