Example #1
0
void FSimpleHMD::ModifyShowFlags(FEngineShowFlags& ShowFlags)
{
	ShowFlags.MotionBlur = 0;
	ShowFlags.HMDDistortion = true;
	ShowFlags.ScreenPercentage = 1.0f;
	ShowFlags.StereoRendering = IsStereoEnabled();
}
Example #2
0
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();
}
Example #3
0
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();
}
Example #9
0
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();
	}
}
Example #10
0
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;
	}
}