void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination);

        if (_compositor == null)
        {
            return;
        }

        IntPtr texPtr = source.GetNativeTexturePtr();

        if (texPtr != IntPtr.Zero)
        {
            _layerSubmitInfo.pose = FoveInterface.GetLastPose();
            switch (whichEye)
            {
            case EFVR_Eye.Left:
                _layerSubmitInfo.left.texInfo.pTexture  = texPtr;
                _layerSubmitInfo.right.texInfo.pTexture = IntPtr.Zero;
                break;

            case EFVR_Eye.Right:
                _layerSubmitInfo.left.texInfo.pTexture  = IntPtr.Zero;
                _layerSubmitInfo.right.texInfo.pTexture = texPtr;
                break;

            default:
                Debug.LogError("[FOVE] Camera set to " + whichEye + " which isn't supported.");
                return;
            }

            var result = _compositor.Submit(ref _layerSubmitInfo);
            if (result != EFVR_ErrorCode.None)
            {
                Debug.LogWarning("[FOVE] Submit returned unexpected " + result);
            }

            GL.Flush();
        }
        else
        {
            Debug.LogWarning("RenderTexture native pointer is null; cannot submit null texture pointers.");
        }

        if (!suppressProjectionUpdates)
        {
            couldUseNewMatrices = true;
        }
    }
    // Update is called once per frame
    void Update()
    {
        Vector3 pos = transform.position;

        SFVR_Quaternion orientation = FoveInterface.GetLastPose().orientation;
        Quaternion      quat        = new Quaternion(orientation.x, orientation.y, orientation.z, orientation.w);
        Vector3         forwad      = quat * Vector3.forward;

        if (_shouldStop)
        {
            if (_shouldLeftEyeDark)
            {
                foveInterface.LeftFoveEye.ShouldDraw  = false;
                foveInterface.RightFoveEye.ShouldDraw = true;
            }
            else
            {
                foveInterface.LeftFoveEye.ShouldDraw  = true;
                foveInterface.RightFoveEye.ShouldDraw = false;
            }

            _shouldEyeDarkTimer += Time.deltaTime;

            if (_shouldEyeDarkTimer > 3.0f)
            {
                _shouldEyeDarkTimer = 0.0f;
                _shouldLeftEyeDark  = !_shouldLeftEyeDark;

                if (_shouldLeftEyeDark)
                {
                    print("left flick");
                }
                else
                {
                    print("right flick");
                }
            }
        }
        else
        {
            float speed = 20;

            distanceThreshold += speed * Time.deltaTime;

            if (goForward && distanceThreshold > speed * 5)
            {
                distanceThreshold = 0.0f;
                goForward         = false;
                _shouldStop       = true;
            }
            else if (!goForward && distanceThreshold > speed * 5)
            {
                distanceThreshold = 0.0f;
                goForward         = true;
            }

            if (goForward)
            {
                pos += forwad * speed * Time.deltaTime;
            }
            else
            {
                pos -= forwad * speed * Time.deltaTime;
            }
            transform.position = pos;
        }

        FoveInterfaceBase.EyeRays eyeRays = foveInterface.GetGazeRays();

        RaycastHit leftRaycastHit, rightRaycastHit;

        Physics.Raycast(eyeRays.left, out leftRaycastHit, Mathf.Infinity);
        if (leftRaycastHit.point != Vector3.zero)
        {
            leftEye.transform.position = leftRaycastHit.point;
        }
        else
        {
            leftEye.transform.position = eyeRays.left.GetPoint(3.0f);
        }
        _leftRecords.Add(new EyeTrackingRecord(Timer, eyeRays.left.origin, eyeRays.left.direction, leftEye.transform.position));

        Physics.Raycast(eyeRays.right, out rightRaycastHit, Mathf.Infinity);
        if (rightRaycastHit.point != Vector3.zero)
        {
            rightEye.transform.position = rightRaycastHit.point;
        }
        else
        {
            rightEye.transform.position = eyeRays.right.GetPoint(3.0f);
        }
        _rightRecords.Add(new EyeTrackingRecord(Timer, eyeRays.right.origin, eyeRays.right.direction, rightEye.transform.position));

        if (SaveTimer > 1.0f)
        {
            string             leftPath = LoggingManager.GetPath(dataFileID + "_left.csv");
            System.IO.FileInfo file     = new System.IO.FileInfo(leftPath);
            file.Directory.Create();
            using (var writer = new StreamWriter(leftPath, append: true))
            {
                foreach (EyeTrackingRecord record in _leftRecords)
                {
                    writer.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
                                     record.Timer,
                                     record.Origin.x,
                                     record.Origin.y,
                                     record.Origin.z,
                                     record.Direction.x,
                                     record.Direction.y,
                                     record.Direction.z,
                                     record.TouchedPosition.x,
                                     record.TouchedPosition.y,
                                     record.TouchedPosition.z
                                     );
                }

                writer.Flush();

                _leftRecords.Clear();
            }

            string rightPath = LoggingManager.GetPath(dataFileID + "_right.csv");
            file = new System.IO.FileInfo(rightPath);
            file.Directory.Create();
            using (var writer = new StreamWriter(rightPath, append: true))
            {
                foreach (EyeTrackingRecord record in _rightRecords)
                {
                    writer.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
                                     record.Timer,
                                     record.Origin.x,
                                     record.Origin.y,
                                     record.Origin.z,
                                     record.Direction.x,
                                     record.Direction.y,
                                     record.Direction.z,
                                     record.TouchedPosition.x,
                                     record.TouchedPosition.y,
                                     record.TouchedPosition.z
                                     );
                }

                writer.Flush();

                _rightRecords.Clear();
            }

            SaveTimer = 0.0f;
        }

        SaveTimer += Time.deltaTime;
        Timer     += Time.deltaTime;
    }
    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination);

        if (_compositor == null)
        {
            return;
        }

        IntPtr texPtr = IntPtr.Zero;

        UnityEngine.SceneManagement.Scene currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();

        if (currentScene.name == "Strabismus")
        {
            texPtr = TargetTexture == null?source.GetNativeTexturePtr() : TargetTexture.GetNativeTexturePtr();
        }
        else
        {
            texPtr = source.GetNativeTexturePtr();
        }

        if (texPtr != IntPtr.Zero)
        {
            _layerSubmitInfo.pose = FoveInterface.GetLastPose();

            switch (whichEye)
            {
            case EFVR_Eye.Left:
                if (currentScene.name == "Strabismus")
                {
                    if (ShouldDraw)
                    {
                        _layerSubmitInfo.left.texInfo.pTexture = texPtr;
                    }
                    else
                    {
                        _layerSubmitInfo.left.texInfo.pTexture = Texture2D.blackTexture.GetNativeTexturePtr();
                    }
                }
                else
                {
                    _layerSubmitInfo.left.texInfo.pTexture = texPtr;
                }

                _layerSubmitInfo.right.texInfo.pTexture = IntPtr.Zero;
                break;

            case EFVR_Eye.Right:
                _layerSubmitInfo.left.texInfo.pTexture = IntPtr.Zero;

                if (currentScene.name == "Strabismus")
                {
                    if (ShouldDraw)
                    {
                        _layerSubmitInfo.right.texInfo.pTexture = texPtr;
                    }
                    else
                    {
                        _layerSubmitInfo.right.texInfo.pTexture = Texture2D.blackTexture.GetNativeTexturePtr();
                    }
                }
                else
                {
                    _layerSubmitInfo.right.texInfo.pTexture = texPtr;
                }
                break;

            default:
                Debug.LogError("[FOVE] Camera set to " + whichEye + " which isn't supported.");
                return;
            }

            var result = _compositor.Submit(ref _layerSubmitInfo);
            if (result != EFVR_ErrorCode.None)
            {
                Debug.LogWarning("[FOVE] Submit returned unexpected " + result);
            }

            GL.Flush();
        }
        else
        {
            Debug.LogWarning("RenderTexture native pointer is null; cannot submit null texture pointers.");
        }

        if (!suppressProjectionUpdates)
        {
            couldUseNewMatrices = true;
        }
    }