예제 #1
0
        public Pose3D GetEyePose(NvrViewer.Eye eye)
        {
            switch (eye)
            {
            case NvrViewer.Eye.Left:
                return(leftEyePose);

            case NvrViewer.Eye.Right:
                return(rightEyePose);

            default:
                return(null);
            }
        }
        // Helper routine for creation of a stereo eye.
        private void CreateEye(NvrViewer.Eye eye)
        {
            string     nm = name + (eye == NvrViewer.Eye.Left ? " Left" : " Right");
            GameObject go = new GameObject(nm);

            go.transform.SetParent(transform, false);
            go.AddComponent <Camera>().enabled = false;
            var NvrEye = go.AddComponent <NvrEye>();

            NvrEye.eye    = eye;
            NvrEye.parent = go;
            NvrEye.CopyCameraAndMakeSideBySide(this);
            NvrViewer.Instance.eyes[eye == NvrViewer.Eye.Left ? 0 : 1] = NvrEye;
        }
예제 #3
0
        public Rect GetViewport(NvrViewer.Eye eye,
                                NvrViewer.Distortion distortion = NvrViewer.Distortion.Distorted)
        {
            switch (eye)
            {
            case NvrViewer.Eye.Left:
                return(distortion == NvrViewer.Distortion.Distorted ?
                       leftEyeDistortedViewport : leftEyeUndistortedViewport);

            case NvrViewer.Eye.Right:
                return(distortion == NvrViewer.Distortion.Distorted ?
                       rightEyeDistortedViewport : rightEyeUndistortedViewport);

            default:
                return(new Rect());
            }
        }
예제 #4
0
        public Matrix4x4 GetProjection(NvrViewer.Eye eye,
                                       NvrViewer.Distortion distortion = NvrViewer.Distortion.Distorted)
        {
            switch (eye)
            {
            case NvrViewer.Eye.Left:
                return(distortion == NvrViewer.Distortion.Distorted ?
                       leftEyeDistortedProjection : leftEyeUndistortedProjection);

            case NvrViewer.Eye.Right:
                return(distortion == NvrViewer.Distortion.Distorted ?
                       rightEyeDistortedProjection : rightEyeUndistortedProjection);

            default:
                return(Matrix4x4.identity);
            }
        }
        /// Compute the position of one of the stereo eye cameras.  Accounts for both
        /// FOV matching and stereo comfort, if those features are enabled.  The input is
        /// the [1,1] entry of the eye camera's projection matrix, representing the vertical
        /// field of view, and the overall scale being applied to the Z axis.  Returns the
        /// position of the stereo eye camera in local coordinates.
        public Vector3 ComputeStereoEyePosition(NvrViewer.Eye eye, float proj11, float zScale)
        {
            if (centerOfInterest == null || !centerOfInterest.gameObject.activeInHierarchy)
            {
                return(NvrViewer.Instance.EyePose(eye).Position *stereoMultiplier);
            }

            // Distance of COI relative to head.
            float distance = centerOfInterest != null ?
                             (centerOfInterest.position - transform.position).magnitude : 0;

            // Size of the COI, clamped to [0..distance] for mathematical sanity in following equations.
            float radius = Mathf.Clamp(radiusOfInterest, 0, distance);

            // Move the eye so that COI has about the same size onscreen as in the mono camera FOV.
            // The radius affects the horizon location, which is where the screen-size matching has to
            // occur.
            float scale  = proj11 / cam.projectionMatrix[1, 1]; // vertical FOV
            float offset =
                Mathf.Sqrt(radius * radius + (distance * distance - radius * radius) * scale * scale);
            float eyeOffset = (distance - offset) * Mathf.Clamp01(matchMonoFOV) / zScale;

            float ipdScale = stereoMultiplier;

            if (checkStereoComfort)
            {
                // Manage IPD scale based on the distance to the COI.
                float minComfort = NvrViewer.Instance.ComfortableViewingRange.x;
                float maxComfort = NvrViewer.Instance.ComfortableViewingRange.y;
                if (minComfort < maxComfort)
                {  // Sanity check.
                   // If closer than the minimum comfort distance, IPD is scaled down.
                   // If farther than the maximum comfort distance, IPD is scaled up.
                   // The result is that parallax is clamped within a reasonable range.
                    float minDistance = (distance - radius) / zScale - eyeOffset;
                    ipdScale *= minDistance / Mathf.Clamp(minDistance, minComfort, maxComfort);
                }
            }

            return(ipdScale * NvrViewer.Instance.EyePose(eye).Position + eyeOffset * Vector3.forward);
        }