Example #1
0
        /// <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;
                    }
                }
            }
        }
Example #2
0
        /// <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;
        }