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; }
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()); } }
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); }