TEST(BasicJointClientKitWithInterface, ConstructDestruct) { auto options = osvrJointClientCreateOptions(); ASSERT_NE(nullptr, options); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrJointClientOptionsLoadPlugin(options, "com_osvr_example_AnalogSync")); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrJointClientOptionsTriggerHardwareDetect(options)); auto ctx = osvrJointClientInit("org.osvr.test.jointclientkit", options); ASSERT_NE(nullptr, ctx); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrClientUpdate(ctx)); OSVR_ClientInterface eye = nullptr; ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrClientGetInterface(ctx, "/com_osvr_example_AnalogSync/MySyncDevice/analog/0", &eye)); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrRegisterAnalogCallback(eye, &myAnalogCallback, nullptr)); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrClientUpdate(ctx)); ASSERT_EQ(true, reportReceived); ASSERT_EQ(OSVR_RETURN_SUCCESS, osvrClientShutdown(ctx)); }
bool OSVRInterface::Init(OSVR_ClientContext OSVRClientContext, const FName& InterfaceName) { bool Result(true); #if OSVR_ENABLED OSVR_ReturnCode ReturnCode = osvrClientGetInterface(OSVRClientContext, InterfaceName.GetPlainANSIString(), &OSVRClientInterface); Result = ReturnCode == OSVR_RETURN_SUCCESS; this->OSVRClientContext = OSVRClientContext; RefreshCapabilities(); RegisterCallbacks(); #endif // OSVR_ENABLED Name = InterfaceName; return Result; }
int main() { OSVR_ClientContext ctx = osvrClientInit("com.osvr.exampleclients.ButtonCallback", 0); OSVR_ClientInterface button1 = NULL; /* This is just one of the paths: specifically, the Hydra's left * controller's button labelled "1". More are in the docs and/or listed on * startup */ osvrClientGetInterface(ctx, "/controller/left/1", &button1); osvrRegisterButtonCallback(button1, &myButtonCallback, NULL); /* Pretend that this is your application's mainloop. */ int i; for (i = 0; i < 1000000; ++i) { osvrClientUpdate(ctx); } osvrClientShutdown(ctx); printf("Library shut down, exiting.\n"); return 0; }
FOSVRInputDevice::FOSVRInputDevice( const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler, TSharedPtr<OSVREntryPoint, ESPMode::ThreadSafe> osvrEntryPoint, TSharedPtr<FOSVRHMD, ESPMode::ThreadSafe> osvrHMD) : mOSVREntryPoint(osvrEntryPoint), mOSVRHMD(osvrHMD), MessageHandler(InMessageHandler) { // make sure OSVR module is loaded. contextMutex = mOSVREntryPoint->GetClientContextMutex(); FScopeLock lock(contextMutex); context = mOSVREntryPoint->GetClientContext(); bContextValid = context && osvrClientCheckStatus(context) == OSVR_RETURN_SUCCESS; if (bContextValid) { const float defaultThreshold = 0.25f; TSharedPtr<OSVRButton> buttons[] = { // left hand MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::SpecialLeft, "/controller/left/middle")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_Shoulder, "/controller/left/bumper")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_Thumbstick, "/controller/left/joystick/button")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_FaceButton1, "/controller/left/1")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_FaceButton2, "/controller/left/2")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_FaceButton3, "/controller/left/3")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Left_FaceButton4, "/controller/left/4")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Left_Thumbstick_X, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::MotionController_Left_Thumbstick_Right, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::MotionController_Left_Thumbstick_Left, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Left_Thumbstick_Y, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::MotionController_Left_Thumbstick_Up, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::MotionController_Left_Thumbstick_Down, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Left_TriggerAxis, "/controller/left/trigger")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, FGamepadKeyNames::MotionController_Left_Trigger, "/controller/left/trigger")), // right hand MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::SpecialRight, "/controller/right/middle")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_Shoulder, "/controller/right/bumper")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_Thumbstick, "/controller/right/joystick/button")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_FaceButton1, "/controller/right/1")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_FaceButton2, "/controller/right/2")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_FaceButton3, "/controller/right/3")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::MotionController_Right_FaceButton4, "/controller/right/4")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Right_Thumbstick_X, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::MotionController_Right_Thumbstick_Right, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::MotionController_Right_Thumbstick_Left, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Right_Thumbstick_Y, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::MotionController_Right_Thumbstick_Up, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::MotionController_Right_Thumbstick_Down, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::MotionController_Right_TriggerAxis, "/controller/right/trigger")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, FGamepadKeyNames::MotionController_Right_Trigger, "/controller/right/trigger")), // "controller" (like xbox360) MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::RightShoulder, "/controller/right/bumper")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::RightThumb, "/controller/right/joystick/button")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::FaceButtonBottom, "/controller/right/1")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::FaceButtonRight, "/controller/right/2")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::FaceButtonLeft, "/controller/right/3")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::FaceButtonTop, "/controller/right/4")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::LeftShoulder, "/controller/left/bumper")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::LeftThumb, "/controller/left/joystick/button")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::DPadDown, "/controller/left/1")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::DPadRight, "/controller/left/2")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::DPadLeft, "/controller/left/3")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_DIGITAL, FGamepadKeyNames::DPadUp, "/controller/left/4")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::LeftAnalogX, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::LeftStickRight, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::LeftStickLeft, "/controller/left/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::LeftAnalogY, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::LeftStickUp, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::LeftStickDown, "/controller/left/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::RightAnalogX, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::RightStickRight, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::RightStickLeft, "/controller/right/joystick/x")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::RightAnalogY, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_GT, defaultThreshold, FGamepadKeyNames::RightStickUp, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, OSVR_THRESHOLD_TYPE_LT, -defaultThreshold, FGamepadKeyNames::RightStickDown, "/controller/right/joystick/y")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::LeftTriggerAnalog, "/controller/left/trigger")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_ANALOG, FGamepadKeyNames::RightTriggerAnalog, "/controller/right/trigger")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, FGamepadKeyNames::LeftTriggerThreshold, "/controller/left/trigger")), MakeShareable(new OSVRButton(OSVR_BUTTON_TYPE_THRESHOLD, FGamepadKeyNames::RightTriggerThreshold, "/controller/right/trigger")), }; osvrButtons.Append(buttons, ARRAY_COUNT(buttons)); for (auto& button : osvrButtons) { auto ifaceItr = interfaces.Find(button->ifacePath); OSVR_ClientInterface iface = nullptr; if (!ifaceItr) { if (osvrClientGetInterface(context, TCHAR_TO_ANSI(*(button->ifacePath)), &iface) != OSVR_RETURN_SUCCESS) { button->bIsValid = false; } else { interfaces.Add(button->ifacePath, iface); } } else { iface = *ifaceItr; } if (button->bIsValid) { if (button->type == OSVR_BUTTON_TYPE_DIGITAL) { if (osvrRegisterButtonCallback(iface, buttonCallback, button.Get()) == OSVR_RETURN_FAILURE) { button->bIsValid = false; } } if (button->type == OSVR_BUTTON_TYPE_ANALOG || button->type == OSVR_BUTTON_TYPE_THRESHOLD) { if (osvrRegisterAnalogCallback(iface, analogCallback, button.Get()) == OSVR_RETURN_FAILURE) { button->bIsValid = false; } } } } bLeftHandValid = osvrClientGetInterface(context, "/me/hands/left", &leftHand) == OSVR_RETURN_SUCCESS; bRightHandValid = osvrClientGetInterface(context, "/me/hands/right", &rightHand) == OSVR_RETURN_SUCCESS; IModularFeatures::Get().RegisterModularFeature(GetModularFeatureName(), this); #if !OSVR_UNREAL_4_12 // This may need to be removed in a future version of the engine. // From the SteamVR plugin: "construction of the controller happens after InitializeMotionControllers(), so we manually add this to the array here" GEngine->MotionControllerDevices.AddUnique(this); #endif } }
CombinedPositionReader::CombinedPositionReader(OSVR_ClientContext ctx, Json::Value position_paths) { osvrClientGetInterface(ctx, position_paths["x"].asCString(), &(m_positions[0])); osvrClientGetInterface(ctx, position_paths["y"].asCString(), &(m_positions[1])); osvrClientGetInterface(ctx, position_paths["z"].asCString(), &(m_positions[2])); }
SinglePositionReader::SinglePositionReader(OSVR_ClientContext ctx, std::string position_path) { osvrClientGetInterface(ctx, position_path.c_str(), &m_position); }
CombinedOrientationReader::CombinedOrientationReader(OSVR_ClientContext ctx, Json::Value orientation_paths) { osvrClientGetInterface(ctx, orientation_paths["roll"].asCString(), &(m_orientations[0])); osvrClientGetInterface(ctx, orientation_paths["pitch"].asCString(), &(m_orientations[1])); osvrClientGetInterface(ctx, orientation_paths["yaw"].asCString(), &(m_orientations[2])); }
SingleOrientationReader::SingleOrientationReader(OSVR_ClientContext ctx, std::string orientation_path) { osvrClientGetInterface(ctx, orientation_path.c_str(), &m_orientation); }
QVRDevice::QVRDevice(int deviceIndex) : _index(deviceIndex) { _internals = new struct QVRDeviceInternals; #ifdef HAVE_VRPN _internals->vrpnPositionPtr = &_position; _internals->vrpnOrientationPtr = &_orientation; _internals->vrpnButtonsPtr = &_buttons; _internals->vrpnAnalogsPtr = &_analogs; _internals->vrpnTrackerRemote = NULL; _internals->vrpnAnalogRemote = NULL; _internals->vrpnButtonRemote = NULL; #endif #ifdef HAVE_OCULUS _internals->oculusTrackedEye = -1; #endif #ifdef HAVE_OPENVR _internals->openVrTrackedEntity = -1; _internals->openVrButtonsEntity = -1; _internals->openVrAnalogsEntity = -1; #endif #ifdef HAVE_OSVR _internals->osvrTrackedEye = -1; _internals->osvrTrackingInterface = NULL; #endif switch (config().trackingType()) { case QVR_Device_Tracking_None: break; case QVR_Device_Tracking_Static: { QStringList args = config().trackingParameters().split(' ', QString::SkipEmptyParts); if (args.length() == 3 || args.length() == 6) _position = QVector3D(args[0].toFloat(), args[1].toFloat(), args[2].toFloat()); if (args.length() == 6) _orientation = QQuaternion::fromEulerAngles(args[3].toFloat(), args[4].toFloat(), args[5].toFloat()); } break; case QVR_Device_Tracking_VRPN: #ifdef HAVE_VRPN if (QVRManager::processIndex() == config().processIndex()) { QStringList args = config().trackingParameters().split(' ', QString::SkipEmptyParts); QString name = (args.length() >= 1 ? args[0] : config().trackingParameters()); int sensor = (args.length() >= 2 ? args[1].toInt() : vrpn_ALL_SENSORS); _internals->vrpnTrackerRemote = new vrpn_Tracker_Remote(qPrintable(name)); vrpn_System_TextPrinter.set_ostream_to_use(stderr); _internals->vrpnTrackerRemote->register_change_handler(_internals, QVRVrpnTrackerChangeHandler, sensor); } #endif break; case QVR_Device_Tracking_Oculus: #ifdef HAVE_OCULUS if (QVRManager::processIndex() == config().processIndex()) { QString arg = config().trackingParameters().trimmed(); if (arg == "head") _internals->oculusTrackedEye = 0; else if (arg == "eye-left") _internals->oculusTrackedEye = 1; else if (arg == "eye-right") _internals->oculusTrackedEye = 2; else QVR_WARNING("device %s: invalid Oculus tracking parameter", qPrintable(id())); } #endif break; case QVR_Device_Tracking_OpenVR: #ifdef HAVE_OPENVR if (QVRManager::processIndex() == config().processIndex()) { QString arg = config().trackingParameters().trimmed(); if (arg == "head") _internals->openVrTrackedEntity = 0; else if (arg == "eye-left") _internals->openVrTrackedEntity = 1; else if (arg == "eye-right") _internals->openVrTrackedEntity = 2; else if (arg == "controller-0") _internals->openVrTrackedEntity = 3; else if (arg == "controller-1") _internals->openVrTrackedEntity = 4; else QVR_WARNING("device %s: invalid OpenVR tracking parameter", qPrintable(id())); } #endif break; case QVR_Device_Tracking_OSVR: #ifdef HAVE_OSVR if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROsvrClientContext); const QString& osvrPath = config().trackingParameters(); if (osvrPath == "eye-center") { _internals->osvrTrackedEye = 0; } else if (osvrPath == "eye-left") { _internals->osvrTrackedEye = 1; } else if (osvrPath == "eye-right") { _internals->osvrTrackedEye = 2; } else { osvrClientGetInterface(QVROsvrClientContext, qPrintable(osvrPath), &_internals->osvrTrackingInterface); if (!_internals->osvrTrackingInterface) { QVR_WARNING("device %s: OSVR interface path %s does not exist", qPrintable(id()), qPrintable(osvrPath)); } } } #endif break; } switch (config().buttonsType()) { case QVR_Device_Buttons_None: break; case QVR_Device_Buttons_Static: { QStringList args = config().buttonsParameters().split(' ', QString::SkipEmptyParts); _buttons.resize(args.length()); for (int i = 0; i < _buttons.length(); i++) _buttons[i] = args[i].toInt(); } break; case QVR_Device_Buttons_VRPN: #ifdef HAVE_VRPN { QStringList args = config().buttonsParameters().split(' ', QString::SkipEmptyParts); QString name = (args.length() >= 1 ? args[0] : config().buttonsParameters()); if (args.length() > 1) { _buttons.resize(args.length() - 1); _internals->vrpnButtons.resize(_buttons.length()); for (int i = 0; i < _buttons.length(); i++) _internals->vrpnButtons[i] = args[i + 1].toInt(); } else { _buttons.resize(32); _internals->vrpnButtons.resize(_buttons.length()); for (int i = 0; i < _buttons.length(); i++) _internals->vrpnButtons[i] = i; } for (int i = 0; i < _buttons.length(); i++) _buttons[i] = false; if (QVRManager::processIndex() == config().processIndex()) { _internals->vrpnButtonRemote = new vrpn_Button_Remote(qPrintable(name)); vrpn_System_TextPrinter.set_ostream_to_use(stderr); _internals->vrpnButtonRemote->register_change_handler(_internals, QVRVrpnButtonChangeHandler); } } #endif break; case QVR_Device_Buttons_OpenVR: #ifdef HAVE_OPENVR { QString arg = config().buttonsParameters().trimmed(); if (arg == "controller-0") { _buttons.resize(6); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROpenVRSystem); _internals->openVrButtonsEntity = 0; } } else if (arg == "controller-1") { _buttons.resize(6); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROpenVRSystem); _internals->openVrButtonsEntity = 1; } } else { QVR_WARNING("device %s: invalid OpenVR buttons parameter", qPrintable(id())); } } #endif break; case QVR_Device_Buttons_OSVR: #ifdef HAVE_OSVR { QStringList args = config().buttonsParameters().split(' ', QString::SkipEmptyParts); _buttons.resize(args.length()); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROsvrClientContext); for (int i = 0; i < _buttons.length(); i++) { const QString& osvrPath = args[i]; OSVR_ClientInterface osvrInterface; osvrClientGetInterface(QVROsvrClientContext, qPrintable(osvrPath), &osvrInterface); if (!osvrInterface) { QVR_WARNING("device %s: OSVR interface path %s does not exist", qPrintable(id()), qPrintable(osvrPath)); } _internals->osvrButtonsInterfaces.append(osvrInterface); } } } #endif break; } switch (config().analogsType()) { case QVR_Device_Analogs_None: break; case QVR_Device_Analogs_Static: { QStringList args = config().analogsParameters().split(' ', QString::SkipEmptyParts); _analogs.resize(args.length()); for (int i = 0; i < _analogs.length(); i++) _analogs[i] = args[i].toFloat(); } break; case QVR_Device_Analogs_VRPN: #ifdef HAVE_VRPN { QStringList args = config().analogsParameters().split(' ', QString::SkipEmptyParts); QString name = (args.length() >= 1 ? args[0] : config().analogsParameters()); if (args.length() > 1) { _analogs.resize(args.length() - 1); _internals->vrpnAnalogs.resize(_analogs.length()); for (int i = 0; i < _analogs.length(); i++) _internals->vrpnAnalogs[i] = args[i + 1].toInt(); } else { _analogs.resize(8); _internals->vrpnAnalogs.resize(_analogs.length()); for (int i = 0; i < _analogs.length(); i++) _internals->vrpnAnalogs[i] = i; } for (int i = 0; i < _analogs.length(); i++) _analogs[i] = 0.0f; if (QVRManager::processIndex() == config().processIndex()) { _internals->vrpnAnalogRemote = new vrpn_Analog_Remote(qPrintable(name)); vrpn_System_TextPrinter.set_ostream_to_use(stderr); _internals->vrpnAnalogRemote->register_change_handler(_internals, QVRVrpnAnalogChangeHandler); } } #endif break; case QVR_Device_Analogs_OpenVR: #ifdef HAVE_OPENVR { QString arg = config().analogsParameters().trimmed(); if (arg == "controller-0") { _analogs.resize(3); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROpenVRSystem); _internals->openVrAnalogsEntity = 0; } } else if (arg == "controller-1") { _analogs.resize(3); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROpenVRSystem); _internals->openVrAnalogsEntity = 1; } } else { QVR_WARNING("device %s: invalid OpenVR analogs parameter", qPrintable(id())); } } #endif break; case QVR_Device_Analogs_OSVR: #ifdef HAVE_OSVR { QStringList args = config().analogsParameters().split(' ', QString::SkipEmptyParts); _analogs.resize(args.length()); if (QVRManager::processIndex() == config().processIndex()) { Q_ASSERT(QVROsvrClientContext); for (int i = 0; i < _analogs.length(); i++) { const QString& osvrPath = args[i]; OSVR_ClientInterface osvrInterface; osvrClientGetInterface(QVROsvrClientContext, qPrintable(osvrPath), &osvrInterface); if (!osvrInterface) { QVR_WARNING("device %s: OSVR interface path %s does not exist", qPrintable(id()), qPrintable(osvrPath)); } _internals->osvrAnalogsInterfaces.append(osvrInterface); } } } #endif break; } }
/** * Handle OSVR tracking. ***/ void* OSVR_Tracker::Provoke(void* pThis, int eD3D, int eD3DInterface, int eD3DMethod, DWORD dwNumberConnected, int& nProvokerIndex) { // update game timer m_cGameTimer.Tick(); static UINT unFrameSkip = 200; if (unFrameSkip > 0) { unFrameSkip--; return nullptr; } if ((!m_psOSVR_ClientContext) || (!m_psOSVR_ClientInterface)) { // create client context handle m_psOSVR_ClientContext = osvrClientInit("com.mtbs3d.vireio.osvr.tracker", 0); // get client interface osvrClientGetInterface(m_psOSVR_ClientContext, "/me/head", &m_psOSVR_ClientInterface); } else { // update the client context osvrClientUpdate(m_psOSVR_ClientContext); // let's read the tracker state. OSVR_ReturnCode cRet = osvrGetPoseState(m_psOSVR_ClientInterface, &m_sTimestamp, &m_sState); if (cRet != OSVR_RETURN_SUCCESS) { OutputDebugStringA("No pose state!\n"); } else { m_bControlUpdate = true; // backup old euler angles and velocity float afEulerOld[3]; float afEulerVelocityOld[3]; memcpy(&afEulerOld[0], &m_afEuler[0], sizeof(float)* 3); memcpy(&afEulerVelocityOld[0], &m_afEulerVelocity[0], sizeof(float)* 3); // quaternion -> euler angles const float w = (float)m_sState.rotation.data[0]; const float x = (float)m_sState.rotation.data[1]; const float y = (float)m_sState.rotation.data[2]; const float z = (float)m_sState.rotation.data[3]; float sqw = w*w; float sqx = x*x; float sqy = y*y; float sqz = z*z; float unit = sqx + sqy + sqz + sqw; float test = x*y + z*w; if (test > 0.499*unit) { // singularity at north pole m_afEuler[1] = 2 * atan2(x, w); m_afEuler[2] = FLOAT_PI / 2; m_afEuler[0] = 0; } else if (test < -0.499*unit) { // singularity at south pole m_afEuler[1] = -2 * atan2(x, w); m_afEuler[2] = -FLOAT_PI / 2; m_afEuler[0] = 0; } else { m_afEuler[1] = atan2(2 * y*w - 2 * x*z, sqx - sqy - sqz + sqw); m_afEuler[2] = asin(2 * test / unit); m_afEuler[0] = atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); } // PITCH = atan2(2.0 * (x * y + w * z), w * w + x * x - y * y - z * z); // ROLL = atan2(2 * y * w - 2 * x * z, 1 - 2 * y * y - 2 * z * z); // get euler velocity + acceleration float afEulerAcceleration[3]; for (UINT unI = 0; unI < 3; unI++) { // get the velocity m_afEulerVelocity[unI] = (m_afEuler[unI] - afEulerOld[unI]) / (float)m_cGameTimer.DeltaTime(); // get the acceleration afEulerAcceleration[unI] = (m_afEulerVelocity[unI] - afEulerVelocityOld[unI]) / (float)m_cGameTimer.DeltaTime(); } // get predicted euler for (UINT unI = 0; unI < 3; unI++) { // compute predicted euler m_afEulerPredicted[unI] = (0.5f * afEulerAcceleration[unI] * ((float)m_cGameTimer.DeltaTime() * (float)m_cGameTimer.DeltaTime())) + (m_afEulerVelocity[unI] * (float)m_cGameTimer.DeltaTime()) + m_afEuler[unI]; } // set position m_afPosition[0] = (float)m_sState.translation.data[0]; m_afPosition[1] = (float)m_sState.translation.data[1]; m_afPosition[2] = (float)m_sState.translation.data[2]; #ifdef _DEBUG // output debug data std::wstringstream szPose; szPose << L"Got POSE state: Position = (" << m_sState.translation.data[0] << L", " << m_sState.translation.data[1] << L", " << m_sState.translation.data[2] << L"), orientation = (" << osvrQuatGetW(&(m_sState.rotation)) << L", " << osvrQuatGetX(&(m_sState.rotation)) << L", " << osvrQuatGetY(&(m_sState.rotation)) << L", " << osvrQuatGetZ(&(m_sState.rotation)) << L")"; OutputDebugString(szPose.str().c_str()); #endif } } return nullptr; }