private void UpdateCameras()
        {
            if (needsCameraConfigure)
            {
                // Check presence of any VR display which would take care of the configuration automatically
                if (XRDevice.isPresent)
                {
                    Debug.Log("VR Display: " + XRDevice.model);
                    needsCameraConfigure = false;
                }
            }

            if (needsCameraConfigure)
            {
                // Is there at least one camera component in the children?
                Camera camera = GetComponentInChildren <Camera>();
                if (camera == null)
                {
                    Debug.LogError("No camera component(s) found in node or in children.");
                    return;
                }

                // is this a HMD type?
                if (config is HMD_Config)
                {
                    HMD_Config hmdConfig = (HMD_Config)config;

                    // use that game object as template for left/right eye
                    cameraNode                             = camera.gameObject;
                    leftCameraNode                         = GameObject.Instantiate(cameraNode);
                    leftCameraNode.name                    = "Left Eye Camera";
                    leftCameraNode.transform.parent        = cameraNode.transform.parent;
                    leftCameraNode.transform.localRotation = cameraNode.transform.localRotation;
                    leftCameraNode.transform.localScale    = Vector3.one;
                    ConfigureCamera(leftCameraNode, XRNode.LeftEye, hmdConfig);
                    AudioListener alLeft = leftCameraNode.GetComponentInChildren <AudioListener>();

                    rightCameraNode                         = GameObject.Instantiate(cameraNode);
                    rightCameraNode.name                    = "Right Eye Camera";
                    rightCameraNode.transform.parent        = cameraNode.transform.parent;
                    rightCameraNode.transform.localRotation = cameraNode.transform.localRotation;
                    rightCameraNode.transform.localScale    = Vector3.one;
                    ConfigureCamera(rightCameraNode, XRNode.RightEye, hmdConfig);
                    AudioListener alRight = rightCameraNode.GetComponentInChildren <AudioListener>();

                    // there can only be one listener
                    if ((alLeft != null) && (alRight != null))
                    {
                        Component.DestroyImmediate(alRight);
                    }

                    leftCameraNode.SetActive(true);
                    rightCameraNode.SetActive(true);
                    cameraNode.SetActive(false);
                }

                needsCameraConfigure = false;
            }
        }
        private void ConfigureCamera(GameObject node, XRNode eye, HMD_Config hmdConfig)
        {
            // adjust camera X-positions based on IPD
            float xDir = 0;

            if (eye == XRNode.LeftEye)
            {
                xDir = -1;
            }
            else if (eye == XRNode.RightEye)
            {
                xDir = +1;
            }

            // shift camera sideways considering any offset orientation
            node.transform.localPosition = (node.transform.localRotation * Vector3.right) * ((hmdConfig.IPD / 2) * xDir);
            node.transform.localRotation = Quaternion.identity;

            foreach (Camera cam in node.GetComponents <Camera>())
            {
                // Setup perspective projection, with aspect ratio matches viewport
                float top    = (float)Mathf.Tan(Mathf.Deg2Rad * hmdConfig.FieldOfView / 2) * cam.nearClipPlane;
                float bottom = -top;
                float left   = cam.aspect * bottom / 2;
                float right  = -left;

                // apply centre offset and adapt viewport
                float offX = hmdConfig.xOffset * (left - right) / 2;
                if (eye == XRNode.LeftEye)
                {
                    cam.rect = new Rect(0.0f, 0, 0.5f, 1);
                }
                else if (eye == XRNode.RightEye)
                {
                    cam.rect = new Rect(0.5f, 0, 0.5f, 1); offX = -offX;
                }
                else
                {
                    cam.rect = new Rect(0.0f, 0, 1.0f, 1); offX = 0;
                }

                // calculate off-centre projection matrix
                Matrix4x4 projectionMatrix = cam.projectionMatrix;
                CalculateProjectionMatrix(ref projectionMatrix, left + offX, right + offX, top, bottom, cam.nearClipPlane, cam.farClipPlane);
                cam.projectionMatrix = projectionMatrix;

                // add distortion filter
                LensDistortion distortion = cam.GetComponent <LensDistortion>();
                if (distortion == null)
                {
                    distortion = cam.gameObject.AddComponent <LensDistortion>();
                }
                distortion.ApplyConfig(hmdConfig);
            }
        }
		/// <summary>
		/// Copy parameters from the VR Display configuration structure to the shader.
		/// </summary>
		/// <param name="config">the VR Display configuration structure to copy from</param>
		/// 
		public void ApplyConfig(HMD_Config config)
		{
			for (int i = 0; i < 4; i++)
			{
				DistortionCoefficients[i] = config.LensDistortionParameters[i];
			}

			for (int i = 0; i < 2; i++)
			{
				// from two [2] arrays to one [4] vector
				ChromaticAberration[i + 0] = config.ChromaticAberrationParametersRed[i];
				ChromaticAberration[i + 2] = config.ChromaticAberrationParametersBlue[i];
			}
		}
Exemplo n.º 4
0
        /// <summary>
        /// Copy parameters from the VR Display configuration structure to the shader.
        /// </summary>
        /// <param name="config">the VR Display configuration structure to copy from</param>
        ///
        public void ApplyConfig(HMD_Config config)
        {
            for (int i = 0; i < 4; i++)
            {
                DistortionCoefficients[i] = config.LensDistortionParameters[i];
            }

            for (int i = 0; i < 2; i++)
            {
                // from two [2] arrays to one [4] vector
                ChromaticAberration[i + 0] = config.ChromaticAberrationParametersRed[i];
                ChromaticAberration[i + 2] = config.ChromaticAberrationParametersBlue[i];
            }

            ScaleIn  = config.ScaleIn;
            ScaleOut = config.ScaleOut;
        }
		private void ConfigureCamera(GameObject node, VRNode eye, HMD_Config hmdConfig)
		{
			// adjust camera X-positions based on IPD
			float xDir = 0;
			if (eye == VRNode.LeftEye) { xDir = -1; }
			else if (eye == VRNode.RightEye) { xDir = +1; }

			// shift camera sideways considering any offset orientation
			node.transform.localPosition = (node.transform.localRotation * Vector3.right) * ((hmdConfig.IPD / 2) * xDir);

			foreach (Camera cam in node.GetComponents<Camera>())
			{
				// Setup perspective projection, with aspect ratio matches viewport
				float top = (float)Mathf.Tan(Mathf.Deg2Rad * hmdConfig.FieldOfView / 2) * cam.nearClipPlane;
				float bottom = -top;
				float left = cam.aspect * bottom / 2;
				float right = -left;

				// apply centre offset and adapt viewport
				float offX = hmdConfig.xOffset * (left - right) / 2;
				if (eye == VRNode.LeftEye) { cam.rect = new Rect(0.0f, 0, 0.5f, 1); }
				else if (eye == VRNode.RightEye) { cam.rect = new Rect(0.5f, 0, 0.5f, 1); offX = -offX; }
				else { cam.rect = new Rect(0.0f, 0, 1.0f, 1); offX = 0; }

				// calculate off-centre projection matrix
				Matrix4x4 projectionMatrix = cam.projectionMatrix;
				CalculateProjectionMatrix(ref projectionMatrix, left + offX, right + offX, top, bottom, cam.nearClipPlane, cam.farClipPlane);
				cam.projectionMatrix = projectionMatrix;

				// add distortion filter
				LensDistortion distortion = cam.GetComponent<LensDistortion>();
				if (distortion == null)
				{
					distortion = cam.gameObject.AddComponent<LensDistortion>();
					distortion.DistortionShader = Shader.Find("VR/LensDistortion");
				}
				distortion.ApplyConfig(hmdConfig);
				distortion.ScaleIn = 1.1f;  // TODO: Hardcoded values > calculate automatically
				distortion.ScaleOut = 0.82f; // TODO: Hardcoded values > calculate automatically
			}
		}