void FSteamVRHMD::PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& View) { check(IsInRenderingThread()); // The last view location used to set the view will be in BaseHmdOrientation. We need to calculate the delta from that, so that // cameras that rely on game objects (e.g. other components) for their positions don't need to be updated on the render thread. const FQuat DeltaOrient = View.BaseHmdOrientation.Inverse() * TrackingFrame.DeviceOrientation[vr::k_unTrackedDeviceIndex_Hmd]; View.ViewRotation = FRotator(View.ViewRotation.Quaternion() * DeltaOrient); View.UpdateViewMatrix(); }
void FViewExtension::PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& View) { check(IsInRenderingThread()); FViewExtension& RenderContext = *this; FGameFrame* CurrentFrame = static_cast<FGameFrame*>(RenderContext.RenderFrame.Get()); if (!RenderContext.ShowFlags.Rendering || !CurrentFrame || !CurrentFrame->Settings->IsStereoEnabled()) { return; } const ovrEyeType eyeIdx = (View.StereoPass == eSSP_LEFT_EYE) ? ovrEye_Left : ovrEye_Right; if (RenderContext.ShowFlags.Rendering && CurrentFrame->Settings->Flags.bUpdateOnRT) { FQuat CurrentEyeOrientation; FVector CurrentEyePosition; CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurEyeRenderPose[eyeIdx], CurrentEyeOrientation, CurrentEyePosition); FQuat ViewOrientation = View.ViewRotation.Quaternion(); // recalculate delta control orientation; it should match the one we used in CalculateStereoViewOffset on a game thread. FVector GameEyePosition; FQuat GameEyeOrient; CurrentFrame->PoseToOrientationAndPosition(CurrentFrame->EyeRenderPose[eyeIdx], GameEyeOrient, GameEyePosition); const FQuat DeltaControlOrientation = ViewOrientation * GameEyeOrient.Inverse(); // make sure we use the same viewrotation as we had on a game thread check(View.ViewRotation == CurrentFrame->CachedViewRotation[eyeIdx]); if (CurrentFrame->Flags.bOrientationChanged) { // Apply updated orientation to corresponding View at recalc matrices. // The updated position will be applied from inside of the UpdateViewMatrix() call. const FQuat DeltaOrient = View.BaseHmdOrientation.Inverse() * CurrentEyeOrientation; View.ViewRotation = FRotator(ViewOrientation * DeltaOrient); //UE_LOG(LogHMD, Log, TEXT("VIEWDLT: Yaw %.3f Pitch %.3f Roll %.3f"), DeltaOrient.Rotator().Yaw, DeltaOrient.Rotator().Pitch, DeltaOrient.Rotator().Roll); } if (!CurrentFrame->Flags.bPositionChanged) { // if no positional change applied then we still need to calculate proper stereo disparity. // use the current head pose for this calculation instead of the one that was saved on a game thread. FQuat HeadOrientation; CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurHeadPose, HeadOrientation, View.BaseHmdLocation); } // The HMDPosition already has HMD orientation applied. // Apply rotational difference between HMD orientation and ViewRotation // to HMDPosition vector. const FVector DeltaPosition = CurrentEyePosition - View.BaseHmdLocation; const FVector vEyePosition = DeltaControlOrientation.RotateVector(DeltaPosition) + CurrentFrame->Settings->PositionOffset; View.ViewLocation += vEyePosition; //UE_LOG(LogHMD, Log, TEXT("VDLTPOS: %.3f %.3f %.3f"), vEyePosition.X, vEyePosition.Y, vEyePosition.Z); if (CurrentFrame->Flags.bOrientationChanged || CurrentFrame->Flags.bPositionChanged) { View.UpdateViewMatrix(); } } FSettings* FrameSettings = CurrentFrame->GetSettings(); check(FrameSettings); FrameSettings->EyeLayer.EyeFov.RenderPose[eyeIdx] = RenderContext.CurEyeRenderPose[eyeIdx]; }