void FSimpleHMD::ModifyShowFlags(FEngineShowFlags& ShowFlags) { ShowFlags.MotionBlur = 0; ShowFlags.HMDDistortion = true; ShowFlags.ScreenPercentage = 1.0f; ShowFlags.StereoRendering = IsStereoEnabled(); }
void VimridViewer::Render() { this->GlutApplication::Render(); // Use dark gray which is good for stereo. glClearColor(0.2, 0.2, 0.2, 1.0); if (IsStereoEnabled()) { RenderStereoBuffer(GL_BACK_LEFT); RenderStereoBuffer(GL_BACK_RIGHT); } else { glDrawBuffer(GL_BACK); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set a normal frustum for non-stereo viewers. glFrustum( -1.0, 1.0, -GetAspectRatio(), GetAspectRatio(), GetFrustumNearClip(), GetFrustumFarClip()); RenderDelegate(); } FinishRender(); }
void FSimpleHMD::SetupViewFamily(FSceneViewFamily& InViewFamily) { InViewFamily.EngineShowFlags.MotionBlur = 0; InViewFamily.EngineShowFlags.HMDDistortion = true; InViewFamily.EngineShowFlags.ScreenPercentage = 1.0f; InViewFamily.EngineShowFlags.StereoRendering = IsStereoEnabled(); }
void FSteamVRHMD::UpdateViewport(bool bUseSeparateRenderTarget, const FViewport& InViewport, SViewport* ViewportWidget) { check(IsInGameThread()); FRHIViewport* const ViewportRHI = InViewport.GetViewportRHI().GetReference(); if (!IsStereoEnabled()) { if (!bUseSeparateRenderTarget) { ViewportRHI->SetCustomPresent(nullptr); } return; } GetActiveRHIBridgeImpl()->UpdateViewport(InViewport, ViewportRHI); }
bool FSteamVRHMD::NeedReAllocateViewportRenderTarget(const FViewport& Viewport) { check(IsInGameThread()); if (IsStereoEnabled()) { const uint32 InSizeX = Viewport.GetSizeXY().X; const uint32 InSizeY = Viewport.GetSizeXY().Y; FIntPoint RenderTargetSize; RenderTargetSize.X = Viewport.GetRenderTargetTexture()->GetSizeX(); RenderTargetSize.Y = Viewport.GetRenderTargetTexture()->GetSizeY(); uint32 NewSizeX = InSizeX, NewSizeY = InSizeY; CalculateRenderTargetSize(Viewport, NewSizeX, NewSizeY); if (NewSizeX != RenderTargetSize.X || NewSizeY != RenderTargetSize.Y) { return true; } } return false; }
FMatrix FSteamVRHMD::GetStereoProjectionMatrix(const enum EStereoscopicPass StereoPassType, const float FOV) const { check(IsStereoEnabled()); vr::Hmd_Eye HmdEye = (StereoPassType == eSSP_LEFT_EYE) ? vr::Eye_Left : vr::Eye_Right; float Left, Right, Top, Bottom; VRSystem->GetProjectionRaw(HmdEye, &Right, &Left, &Top, &Bottom); Bottom *= -1.0f; Top *= -1.0f; Right *= -1.0f; Left *= -1.0f; float ZNear = GNearClippingPlane; float SumRL = (Right + Left); float SumTB = (Top + Bottom); float InvRL = (1.0f / (Right - Left)); float InvTB = (1.0f / (Top - Bottom)); #if 1 FMatrix Mat = FMatrix( FPlane((2.0f * InvRL), 0.0f, 0.0f, 0.0f), FPlane(0.0f, (2.0f * InvTB), 0.0f, 0.0f), FPlane((SumRL * InvRL), (SumTB * InvTB), 0.0f, 1.0f), FPlane(0.0f, 0.0f, ZNear, 0.0f) ); #else vr::HmdMatrix44_t SteamMat = VRSystem->GetProjectionMatrix(HmdEye, ZNear, 10000.0f, vr::API_DirectX); FMatrix Mat = ToFMatrix(SteamMat); Mat.M[3][3] = 0.0f; Mat.M[2][3] = 1.0f; Mat.M[2][2] = 0.0f; Mat.M[3][2] = ZNear; #endif return Mat; }
void FOculusRiftHMD::DrawDebug(UCanvas* Canvas) { #if !UE_BUILD_SHIPPING check(IsInGameThread()); const auto frame = GetFrame(); if (frame) { FSettings* FrameSettings = frame->GetSettings(); if (FrameSettings->Flags.bDrawGrid) { bool bStereo = Canvas->Canvas->IsStereoRendering(); Canvas->Canvas->SetStereoRendering(false); bool bPopTransform = false; if (FrameSettings->EyeRenderDesc[0].DistortedViewport.Size.w != FMath::CeilToInt(Canvas->ClipX) || FrameSettings->EyeRenderDesc[0].DistortedViewport.Size.h != Canvas->ClipY) { // scale if resolution of the Canvas does not match the viewport bPopTransform = true; Canvas->Canvas->PushAbsoluteTransform(FScaleMatrix( FVector((Canvas->ClipX) / float(FrameSettings->EyeRenderDesc[0].DistortedViewport.Size.w), Canvas->ClipY / float(FrameSettings->EyeRenderDesc[0].DistortedViewport.Size.h), 1.0f))); } const FColor cNormal(255, 0, 0); const FColor cSpacer(255, 255, 0); const FColor cMid(0, 128, 255); for (int eye = 0; eye < 2; ++eye) { int lineStep = 1; int midX = 0; int midY = 0; int limitX = 0; int limitY = 0; int renderViewportX = FrameSettings->EyeRenderDesc[eye].DistortedViewport.Pos.x; int renderViewportY = FrameSettings->EyeRenderDesc[eye].DistortedViewport.Pos.y; int renderViewportW = FrameSettings->EyeRenderDesc[eye].DistortedViewport.Size.w; int renderViewportH = FrameSettings->EyeRenderDesc[eye].DistortedViewport.Size.h; lineStep = 48; OVR::Vector2f rendertargetNDC = OVR::FovPort(FrameSettings->EyeRenderDesc[eye].Fov).TanAngleToRendertargetNDC(OVR::Vector2f(0.0f)); midX = (int)((rendertargetNDC.x * 0.5f + 0.5f) * (float)renderViewportW + 0.5f); midY = (int)((rendertargetNDC.y * 0.5f + 0.5f) * (float)renderViewportH + 0.5f); limitX = FMath::Max(renderViewportW - midX, midX); limitY = FMath::Max(renderViewportH - midY, midY); int spacerMask = (lineStep << 1) - 1; for (int xp = 0; xp < limitX; xp += lineStep) { float x[4]; float y[4]; x[0] = (float)(midX + xp) + renderViewportX; y[0] = (float)0 + renderViewportY; x[1] = (float)(midX + xp) + renderViewportX; y[1] = (float)renderViewportH + renderViewportY; x[2] = (float)(midX - xp) + renderViewportX; y[2] = (float)0 + renderViewportY; x[3] = (float)(midX - xp) + renderViewportX; y[3] = (float)renderViewportH + renderViewportY; if (xp == 0) { RenderLines(Canvas->Canvas, 1, cMid, x, y); } else if ((xp & spacerMask) == 0) { RenderLines(Canvas->Canvas, 2, cSpacer, x, y); } else { RenderLines(Canvas->Canvas, 2, cNormal, x, y); } } for (int yp = 0; yp < limitY; yp += lineStep) { float x[4]; float y[4]; x[0] = (float)0 + renderViewportX; y[0] = (float)(midY + yp) + renderViewportY; x[1] = (float)renderViewportW + renderViewportX; y[1] = (float)(midY + yp) + renderViewportY; x[2] = (float)0 + renderViewportX; y[2] = (float)(midY - yp) + renderViewportY; x[3] = (float)renderViewportW + renderViewportX; y[3] = (float)(midY - yp) + renderViewportY; if (yp == 0) { RenderLines(Canvas->Canvas, 1, cMid, x, y); } else if ((yp & spacerMask) == 0) { RenderLines(Canvas->Canvas, 2, cSpacer, x, y); } else { RenderLines(Canvas->Canvas, 2, cNormal, x, y); } } } if (bPopTransform) { Canvas->Canvas->PopTransform(); // optional scaling } Canvas->Canvas->SetStereoRendering(bStereo); } if (IsStereoEnabled() && FrameSettings->Flags.bShowStats) { static const FColor TextColor(0,255,0); // Pick a larger font on console. UFont* const Font = FPlatformProperties::SupportsWindowedMode() ? GEngine->GetSmallFont() : GEngine->GetMediumFont(); const int32 RowHeight = FMath::TruncToInt(Font->GetMaxCharHeight() * 1.1f); float ClipX = Canvas->ClipX; float ClipY = Canvas->ClipY; float LeftPos = 0; ClipX -= 100; //ClipY = ClipY * 0.60; LeftPos = ClipX * 0.3f; float TopPos = ClipY * 0.4f; int32 X = (int32)LeftPos; int32 Y = (int32)TopPos; FString Str, StatusStr; // First row // Str = FString::Printf(TEXT("TimeWarp: %s"), (FrameSettings->Flags.bTimeWarp) ? TEXT("ON") : TEXT("OFF")); // Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); // // Y += RowHeight; //Str = FString::Printf(TEXT("VSync: %s"), (FrameSettings->Flags.bVSync) ? TEXT("ON") : TEXT("OFF")); //Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); //Y += RowHeight; Str = FString::Printf(TEXT("Upd on GT/RT: %s / %s"), (!FrameSettings->Flags.bDoNotUpdateOnGT) ? TEXT("ON") : TEXT("OFF"), (FrameSettings->Flags.bUpdateOnRT) ? TEXT("ON") : TEXT("OFF")); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; // static IConsoleVariable* CFinishFrameVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.FinishCurrentFrame")); // int finFr = CFinishFrameVar->GetInt(); // Str = FString::Printf(TEXT("FinFr: %s"), (finFr || FrameSettings->Flags.bTimeWarp) ? TEXT("ON") : TEXT("OFF")); // Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); // // Y += RowHeight; Str = FString::Printf(TEXT("PD: %.2f"), FrameSettings->PixelDensity); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; Str = FString::Printf(TEXT("QueueAhead: %s"), (FrameSettings->bQueueAheadEnabled) ? TEXT("ON") : TEXT("OFF")); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; Str = FString::Printf(TEXT("FOV V/H: %.2f / %.2f deg"), FMath::RadiansToDegrees(FrameSettings->VFOVInRadians), FMath::RadiansToDegrees(FrameSettings->HFOVInRadians)); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; Str = FString::Printf(TEXT("W-to-m scale: %.2f uu/m"), frame->WorldToMetersScale); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); if ((FrameSettings->SupportedHmdCaps & ovrHmdCap_DynamicPrediction) != 0) { float latencies[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; const int numOfEntries = sizeof(latencies) / sizeof(latencies[0]); if (ovrHmd_GetFloatArray(Hmd, "DK2Latency", latencies, numOfEntries) == numOfEntries) { Y += RowHeight; char buf[numOfEntries][20]; char destStr[100]; FCStringAnsi::Snprintf(destStr, sizeof(destStr), "Latency, ren: %s tw: %s pp: %s err: %s %s", FormatLatencyReading(buf[0], sizeof(buf[0]), latencies[0]), FormatLatencyReading(buf[1], sizeof(buf[1]), latencies[1]), FormatLatencyReading(buf[2], sizeof(buf[2]), latencies[2]), FormatLatencyReading(buf[3], sizeof(buf[3]), latencies[3]), FormatLatencyReading(buf[4], sizeof(buf[4]), latencies[4])); Str = ANSI_TO_TCHAR(destStr); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); } } // Second row X = (int32)LeftPos + 200; Y = (int32)TopPos; StatusStr = ((FrameSettings->SupportedTrackingCaps & ovrTrackingCap_Position) != 0) ? ((FrameSettings->Flags.bHmdPosTracking) ? TEXT("ON") : TEXT("OFF")) : TEXT("UNSUP"); Str = FString::Printf(TEXT("PosTr: %s"), *StatusStr); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; Str = FString::Printf(TEXT("Vision: %s"), (frame->Flags.bHaveVisionTracking) ? TEXT("ACQ") : TEXT("LOST")); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; Str = FString::Printf(TEXT("IPD: %.2f mm"), FrameSettings->InterpupillaryDistance*1000.f); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; StatusStr = ((FrameSettings->SupportedHmdCaps & ovrHmdCap_LowPersistence) != 0) ? ((FrameSettings->Flags.bLowPersistenceMode) ? TEXT("ON") : TEXT("OFF")) : TEXT("UNSUP"); Str = FString::Printf(TEXT("LowPers: %s"), *StatusStr); Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); Y += RowHeight; // StatusStr = ((FrameSettings->SupportedDistortionCaps & ovrDistortionCap_Overdrive) != 0) ? // ((FrameSettings->Flags.bOverdrive) ? TEXT("ON") : TEXT("OFF")) : TEXT("UNSUP"); // Str = FString::Printf(TEXT("Overdrive: %s"), *StatusStr); // Canvas->Canvas->DrawShadowedString(X, Y, *Str, Font, TextColor); // Y += RowHeight; } //TODO: Where can I get context!? UWorld* MyWorld = GWorld; if (FrameSettings->Flags.bDrawTrackingCameraFrustum) { DrawDebugTrackingCameraFrustum(MyWorld, Canvas->SceneView->ViewRotation, Canvas->SceneView->ViewLocation); } if (Canvas && Canvas->SceneView) { DrawSeaOfCubes(MyWorld, Canvas->SceneView->ViewLocation); } } #endif // #if !UE_BUILD_SHIPPING }
void FSteamVRHMD::SetupViewFamily(FSceneViewFamily& InViewFamily) { InViewFamily.EngineShowFlags.MotionBlur = 0; InViewFamily.EngineShowFlags.HMDDistortion = false; InViewFamily.EngineShowFlags.StereoRendering = IsStereoEnabled(); }
void VimridViewer::OnControlSelectRelease(Control &control) { // HACK: Comparing text when pointer should be compared. if ((control.GetName() == "loadDicomSet1Button") || (control.GetName() == "loadDicomSet2Button") || (control.GetName() == "loadDicomSet3Button") || (control.GetName() == "loadDicomSet4Button")) { const Button *buttonPtr = dynamic_cast<const Button*>(&control); mDicomClient.DownloadAsync(buttonPtr->GetText()); } // HACK: Comparing text when pointer should be compared. if (control.GetName() == "toggleStatusButton") { EnableRenderStatusText = !EnableRenderStatusText; } // Cancel loading of DICOM data. if (&control == mFilterLoadingScreenCancelButton) { mDicomLoadCancel = true; } // Turns transparency on and off. if (&control == mToggleAlphaButton) { mAlphaEnabled = !mAlphaEnabled; } if (&control == mFilterRestoreButton) { pthread_create(&mFilterRestoreThread, NULL, _filterRestore, NULL); } /* HACK: If any other button pressed, filter mode is reset. This * conveniently does the same thing as what the cancel button does * so it works fine for the time being, but this should only really * be reset on specific scenarios (such as cancel button press). */ mFilterMode = VV_FM_None; if (&control == mSobelXNormalButton) { mFilterMode = VV_FM_SobelXNormal; } else if (&control == mSobelYNormalButton) { mFilterMode = VV_FM_SobelYNormal; } else if (&control == mSobelXYNormalButton) { mFilterMode = VV_FM_SobelXYNormal; } else if (&control == mSobelXYScopedButton) { mFilterMode = VV_FM_SobelXYScoped; } // Once filter mode potentially set, check and if it is, process! if (mFilterMode != VV_FM_None) { pthread_create(&mProcessorThread, NULL, _processImages, NULL); } if (&control == mToggleStereoButton) { if (IsStereoEnabled()) { DisableStereo(); } else { EnableStereo(); } } if (&control == mToggleTrackdButton) { VimridMenu &mainMenu = *mMainMenu; if (GetUtility().IsTrackdEnabled()) { GetUtility().DisableTrackd(); GetUiContainer().ResetCursor(); if (mainMenu.HasToggleMode(UI_MTM_CENTRE_CURSOR)) { mainMenu.RemoveToggleMode(UI_MTM_CENTRE_CURSOR); } } else { GetUtility().EnableTrackd(); GetUiContainer().CentreCursor(*mMainMenu); if (!mainMenu.HasToggleMode(UI_MTM_CENTRE_CURSOR)) { mainMenu.AddToggleMode(UI_MTM_CENTRE_CURSOR); } } } if (&control == mExitVimridButton) { Exit(); } }
void VimridViewer::Update() { this->GlutApplication::Update(); // Calculate a general speed based on delta. VFloat deltaSpeed = GetUtility().GetDeltaTime() * 0.1; VPoint3f dragVector = getCameraDragVector(); VFloat mDragSpeed = 1; mCameraDragDelta = dragVector - mLastCameraDragVector; mCameraAnimationTarget += mCameraDragDelta * mDragSpeed * deltaSpeed; VFloat maximumY = 170.0; if (mCameraAnimationTarget.Y > maximumY) { mCameraAnimationTarget.Y = maximumY; } VFloat minimumY = 5.0; if (mCameraAnimationTarget.Y < minimumY) { mCameraAnimationTarget.Y = minimumY; } VFloat minZ = -25.0; if (mCameraAnimationTarget.Z < minZ) { mCameraAnimationTarget.Z = minZ; } VFloat maxZ = -7.5; if (mCameraAnimationTarget.Z > maxZ) { mCameraAnimationTarget.Z = maxZ; } const VFloat zSpeed = 0.03; const VFloat fpSpeed = 0.03; const VFloat esSpeed = 0.01; if (IsSpecialKeyPressed(GLUT_KEY_UP)) { mCameraAnimationTarget.Z += zSpeed * deltaSpeed; } if (IsSpecialKeyPressed(GLUT_KEY_DOWN)) { mCameraAnimationTarget.Z -= zSpeed * deltaSpeed; } if (IsSpecialKeyPressed(GLUT_KEY_PAGE_UP)) { GetFixationPoint() -= fpSpeed * deltaSpeed; } if (IsSpecialKeyPressed(GLUT_KEY_PAGE_DOWN)) { GetFixationPoint() += fpSpeed * deltaSpeed; } if (IsSpecialKeyPressed(GLUT_KEY_LEFT)) { GetEyeSeparation() -= esSpeed * deltaSpeed; } if (IsSpecialKeyPressed(GLUT_KEY_RIGHT)) { GetEyeSeparation() += esSpeed * deltaSpeed; } UpdateSprites(); GetMriVisualiser().Update(); // Keep checking to see if there are textures that need creating. if (GetTextureManager().IsCreatePending()) { GetTextureManager().CreateAll(); WRITE_DEBUG_TEXT("Textures were created."); } string te = (GetUtility().IsTrackdEnabled() ? "Enabled" : "Disabled"); string se = (IsStereoEnabled() ? "Enabled" : "Disabled"); ADD_STATUS_LINE( "[Motion Sensing: " << te << "] " << "[Stereography: " << se << "]"); VFloat fp = GetFixationPoint(); VFloat es = GetEyeSeparation(); ADD_STATUS_LINE( "[Fixation Point: " << fp << "] " << "[Eye Separation: " << es << "]"); ADD_STATUS_LINE("[Smooth Cursor: " << GetUtility().GetCursorPositionSmooth() << "]"); /* HACK: Big hack! This needs making more robust, currently it just * looks at the Y axis and the code is very difficult to modify. Should * also be abstracted out of this class. */ /*VFloat minimumY = 5.0; VFloat maximumY = 170.0; VPoint3f baseCamera = this->GlutApplication::GetCameraVector(); if (GetCameraVector().Y < minimumY) { // Only counter if the cursor was moved down. if ((mLastCameraVector.Y - GetCameraVector().Y) > 0) { // Record the amount that the user has over-stepped. mCameraCouteract.Y = baseCamera.Y - minimumY; } } if (GetCameraVector().Y > maximumY) { // Counter if moved upward. if ((mLastCameraVector.Y - GetCameraVector().Y) < 0) { mCameraCouteract.Y = baseCamera.Y - maximumY; } } ADD_STATUS_LINE("[Camera Counteract: " << mCameraCouteract << "]"); mLastCameraVector = GetCameraVector();*/ /* Smoothly move the camera toward the target based on delta time so * it's constant over all computers. Don't bother altering if the sync * is only off by 0.1 point (otherwise camera twich occurs). */ VPoint3f animateDistance = mCameraAnimationTarget - mCameraAnimationBuffer; //if ((trimSync > VPoint3f(0.1, 0.1, 0.1)) || (trimSync < VPoint3f(-0.1, -0.1, -0.1))) { const VFloat animateSpeed = 0.05; mCameraAnimationBuffer += animateDistance * animateSpeed * deltaSpeed; } mLastCameraDragVector = dragVector; if (!mMenuAutoShown) { // Reset cursor so it appears centered in menu. GetUtility().ResetCursor(); // Show during init to ensure UI container has been setup. mMainMenu->Show(); mMenuAutoShown = true; } }