TSharedPtr< class IInputDevice > FOSVRInput::CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) { auto& osvr = IOSVR::Get(); auto entryPoint = osvr.GetEntryPoint(); auto osvrHMD = osvr.GetHMD(); FScopeLock lock(entryPoint->GetClientContextMutex()); if (entryPoint->IsOSVRConnected()) { FOSVRInputDevice::RegisterNewKeys(); InputDevice = MakeShareable(new FOSVRInputDevice(InMessageHandler, entryPoint, osvrHMD)); return InputDevice; } return nullptr; }
FOSVRHMD::FOSVRHMD() : LastHmdOrientation(FQuat::Identity), CurHmdOrientation(FQuat::Identity), DeltaControlRotation(FRotator::ZeroRotator), DeltaControlOrientation(FQuat::Identity), CurHmdPosition(FVector::ZeroVector), BaseOrientation(FQuat::Identity), BasePosition(FVector::ZeroVector), WorldToMetersScale(100.0f), bHmdPosTracking(false), bHaveVisionTracking(false), bStereoEnabled(true), bHmdEnabled(true), bHmdOverridesApplied(false), DisplayConfig(nullptr) { static const FName RendererModuleName("Renderer"); RendererModule = FModuleManager::GetModulePtr<IRendererModule>(RendererModuleName); auto entryPoint = IOSVR::Get().GetEntryPoint(); FScopeLock lock(entryPoint->GetClientContextMutex()); auto osvrClientContext = entryPoint->GetClientContext(); // Prevents debugger hangs that sometimes occur with only one monitor. #if OSVR_UNREAL_DEBUG_FORCED_WINDOWMODE FSystemResolution::RequestResolutionChange(1280, 720, EWindowMode::Windowed); // bStereo ? WindowedMirror : Windowed #endif EnablePositionalTracking(true); IConsoleVariable* CVScreenPercentage = IConsoleManager::Get().FindConsoleVariable(TEXT("r.screenpercentage")); if (CVScreenPercentage) { mScreenScale = float(CVScreenPercentage->GetInt()) / 100.0f; } StartCustomPresent(); // enable vsync IConsoleVariable* CVSyncVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.VSync")); if (CVSyncVar) { CVSyncVar->Set(false); } // Uncap fps to enable FPS higher than 62 GEngine->bSmoothFrameRate = false; // check if the client context is ok. bool bClientContextOK = entryPoint->IsOSVRConnected(); // get the display context bool bDisplayConfigOK = false; if (bClientContextOK) { bool bFailure = false; auto rc = osvrClientGetDisplay(osvrClientContext, &DisplayConfig); if (rc == OSVR_RETURN_FAILURE) { UE_LOG(OSVRHMDLog, Warning, TEXT("Could not create DisplayConfig. Treating this as if the HMD is not connected.")); } else { auto begin = FDateTime::Now().GetSecond(); auto end = begin + 3; while (!bDisplayConfigOK && FDateTime::Now().GetSecond() < end) { bDisplayConfigOK = osvrClientCheckDisplayStartup(DisplayConfig) == OSVR_RETURN_SUCCESS; if (!bDisplayConfigOK) { bFailure = osvrClientUpdate(osvrClientContext) == OSVR_RETURN_FAILURE; if (bFailure) { UE_LOG(OSVRHMDLog, Warning, TEXT("osvrClientUpdate failed during startup. Treating this as \"HMD not connected\"")); break; } } FPlatformProcess::Sleep(0.2f); } bDisplayConfigOK = bDisplayConfigOK && !bFailure; if (!bDisplayConfigOK) { UE_LOG(OSVRHMDLog, Warning, TEXT("DisplayConfig failed to startup. This could mean that there is nothing mapped to /me/head. Treating this as if the HMD is not connected.")); } } } bool bDisplayConfigMatchesUnrealExpectations = false; if (bDisplayConfigOK) { bool bSuccess = HMDDescription.Init(osvrClientContext, DisplayConfig); if (bSuccess) { bDisplayConfigMatchesUnrealExpectations = HMDDescription.OSVRViewerFitsUnrealModel(DisplayConfig); if (!bDisplayConfigMatchesUnrealExpectations) { UE_LOG(OSVRHMDLog, Warning, TEXT("The OSVR display config does not match the expectations of Unreal. Possibly incompatible HMD configuration.")); } } else { UE_LOG(OSVRHMDLog, Warning, TEXT("Unable to initialize the HMDDescription. Possible failures during initialization.")); } } // our version of connected is that the client context is ok (server is running) // and the display config is ok (/me/head exists and received a pose) bHmdConnected = bClientContextOK && bDisplayConfigOK && bDisplayConfigMatchesUnrealExpectations; }