/// <summary> /// Updates the HMD. /// </summary> private void UpdateHMD() { CVRSystem hmd = Hmd; if (renderPoses.Length > 0) { ETrackingResult result = renderPoses[0].eTrackingResult; VRInitializing = result == ETrackingResult.Uninitialized; VRCalibrating = result == ETrackingResult.Calibrating_InProgress || result == ETrackingResult.Calibrating_OutOfRange; VROutOfRange = result == ETrackingResult.Running_OutOfRange || result == ETrackingResult.Calibrating_OutOfRange; if (result == ETrackingResult.Running_OK) { // Get poses for each eye (left, right, center) renderPoses[0].ToMatrix(out Matrix mCenter); mCenter.ToVRPose(out VRPose center); EyesProperties[2].Pose = center; for (int i = 0; i < 2; i++) { VREye eye = EyesProperties[i]; VREyeTexture texture = eye.Texture; hmd.GetProjectionMatrix((EVREye)i, texture.NearPlane, texture.FarPlane).ToMatrix(out Matrix projection); projection.Invert(); eye.Projection = projection; hmd.GetEyeToHeadTransform((EVREye)i).ToMatrix(out Matrix mOffset); mOffset *= mCenter; mOffset.ToVRPose(out VRPose pose); eye.Pose = pose; } } } }
/// <summary> /// Initializes the rendering stuff. /// </summary> private void InitRendering() { Debug.Log("[VR] rendering init begin"); // Get HMD display size uint w = 0; uint h = 0; Hmd.GetRecommendedRenderTargetSize(ref w, ref h); int width = (int)w; int height = (int)h; // Create RT for each eye //TODO: Combine two RTs to one with [w*2, h] leftEyeRenderTarget = RenderTarget.New(); leftEyeRenderTarget.Init(PixelFormat.R8G8B8A8_UNorm, width, height); rightEyeRenderTarget = RenderTarget.New(); rightEyeRenderTarget.Init(PixelFormat.R8G8B8A8_UNorm, width, height); // Create texture structs for OpenVR leftEyeTexture = new Texture_t { handle = leftEyeRenderTarget.NativePtr, eColorSpace = EColorSpace.Auto, eType = ETextureType.DirectX }; rightEyeTexture = new Texture_t { handle = rightEyeRenderTarget.NativePtr, eColorSpace = EColorSpace.Auto, eType = ETextureType.DirectX }; // Calculate bounds and FOV // bounds and FOV calculation could be replaced with uv [0,0] - [1,1] and custom projection matrix from eye.Projection float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; Hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; Hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); var tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); leftEyeTextureBounds = new VRTextureBounds_t { uMin = 0.5f + 0.5f * l_left / tanHalfFov.X, uMax = 0.5f + 0.5f * l_right / tanHalfFov.X, vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.Y, vMax = 0.5f - 0.5f * l_top / tanHalfFov.Y }; rightEyeTextureBounds = new VRTextureBounds_t { uMin = 0.5f + 0.5f * r_left / tanHalfFov.X, uMax = 0.5f + 0.5f * r_right / tanHalfFov.X, vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.Y, vMax = 0.5f - 0.5f * r_top / tanHalfFov.Y }; FieldOfView = 2.0f * Mathf.Atan(tanHalfFov.Y) * Mathf.Rad2Deg; /////// // Create Eye textures EyeTextures = new VREyeTexture[2]; EyeTextures[0] = new VREyeTexture { Viewport = new Viewport(0, 0, width, height), RenderTarget = leftEyeRenderTarget }; EyeTextures[1] = new VREyeTexture { Viewport = new Viewport(0, 0, width, height), RenderTarget = rightEyeRenderTarget }; // HMDMirrorRenderTarget = leftEyeRenderTarget; // Create render tasks leftEyeRenderTask = RenderTask.Create <SceneRenderTask>(); // Camera leftEyeRenderTask.Output = leftEyeRenderTarget; leftEyeRenderTask.End += (task, ctx) => { Submit(EVREye.Eye_Left, ref leftEyeTexture, ref leftEyeTextureBounds); }; rightEyeRenderTask = RenderTask.Create <SceneRenderTask>(); // Camera rightEyeRenderTask.Output = rightEyeRenderTarget; rightEyeRenderTask.End += (task, ctx) => { Submit(EVREye.Eye_Right, ref rightEyeTexture, ref rightEyeTextureBounds); }; // Create eyes EyesProperties = new VREye[3]; for (int i = 0; i < EyesProperties.Length; i++) { VREye eye = new VREye(); if (i < EyeTextures.Length) { eye.Texture = EyeTextures[i]; } EyesProperties[i] = eye; } Debug.Log("[VR] rendering init end"); IsConnected = true; }