Exemplo n.º 1
0
        /// <summary>
        /// Returns the data that describes the convergence point of the eyes this frame. See the description of the
        /// `GazeConvergenceData` for more detail on how to use this information.
        /// </summary>
        /// <returns>A struct describing the gaze convergence in world space.</returns>
        public GazeConvergenceData GetGazeConvergence()
        {
            CheckStaticConcurrency();
            SFVR_GazeConvergenceData convergence;

            _sHeadset.GetGazeConvergence(out convergence);

            Vector3 origin    = FoveUnityUtils.GetUnityVector(convergence.ray.origin) + transform.position;
            Vector3 direction = transform.TransformDirection(FoveUnityUtils.GetUnityVector(convergence.ray.direction));
            Ray     worldRay  = new Ray(origin, direction);

            return(new GazeConvergenceData(worldRay, convergence.distance, convergence.accuracy));
        }
        void OnPreCull()
        {
            if (!_isAuthoritative)
            {
                return;
            }

            if (null == _compositor)
            {
                return;
            }

            if (_needsResolutionUpdate)
            {
                SetOptimalRenderScale();
            }

            WaitForRenderPose_IfNeeded();

            SFVR_Matrix44 lViewMat = new SFVR_Matrix44();
            SFVR_Matrix44 rViewMat = new SFVR_Matrix44();

            Matrix4x4 scale = Matrix4x4.Scale(new Vector3(worldScale, worldScale, worldScale));

            // Something about the camera projections or relative translations means that I have to swap what the
            // x-axis values so positive-x is left (not right, as it typically should be).
            Vector3 left_translation = new Vector3()
            {
                x = usedIOD * 0.5f,
                y = eyeHeight,
                z = eyeForward
            } *worldScale;

            Vector3 right_translation = new Vector3()
            {
                x = -usedIOD * 0.5f,
                y = eyeHeight,
                z = eyeForward
            } *worldScale;

            Matrix4x4 lxform = Matrix4x4.TRS(left_translation, Quaternion.identity, new Vector3(1, 1, -1));
            Matrix4x4 rxform = Matrix4x4.TRS(right_translation, Quaternion.identity, new Vector3(1, 1, -1));

            _camera.SetStereoViewMatrix(Camera.StereoscopicEye.Left, lxform * transform.worldToLocalMatrix);
            _camera.SetStereoViewMatrix(Camera.StereoscopicEye.Right, rxform * transform.worldToLocalMatrix);

            // Protection junk
            SFVR_Matrix44 lProjMat = new SFVR_Matrix44();
            SFVR_Matrix44 rProjMat = new SFVR_Matrix44();

            if (_projectionErrorFree && suppressProjectionUpdates)
            {
                return;
            }

            bool           foundProjectionErrors = false;
            EFVR_ErrorCode err;

            err = _sHeadset.GetEyeToHeadMatrices(out lViewMat, out rViewMat);
            foundProjectionErrors |= err != EFVR_ErrorCode.None;

            err = _sHeadset.GetProjectionMatricesRH(_camera.nearClipPlane, _camera.farClipPlane,
                                                    out lProjMat, out rProjMat);
            foundProjectionErrors |= err != EFVR_ErrorCode.None;

            if (foundProjectionErrors)
            {
                _projectionErrorFree = false;
                Debug.Log("Giving up on flawed projection matrices...");
                return;
            }
            _projectionErrorFree = true;

            _camera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left,
                                              FoveUnityUtils.GetUnityMx(lProjMat));
            _camera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right,
                                              FoveUnityUtils.GetUnityMx(rProjMat));
        }