// Update is called once per frame
    void LateUpdate()
    {
        frameCount++;

#if UNITY_EDITOR
        if (Input.GetKeyDown(KeyCode.C))
        {
            occupancyManager.Clear();
        }

        if ((frameCount % 6) == 0)
        {
            float start = Time.realtimeSinceStartup;

            for (int i = 0; i < insertionCount; i++)
            {
                int x   = UnityEngine.Random.Range(0, Screen.width);
                int y   = UnityEngine.Random.Range(0, Screen.height);
                Ray ray = mainCamera.ScreenPointToRay(new Vector3(x, y, 0));
                if (Physics.Raycast(ray, out hitInfo, 4, virutalRoomLayer))
                {
                    occupancyManager.InsertPoint(hitInfo.point, ray.direction, 1.0f / (hitInfo.distance + 1));
                }
            }
            occupancyManager.QueueDirtyMeshesForRegeneration();

            float stop = Time.realtimeSinceStartup;
            occupancyManager.InsertionTime = occupancyManager.InsertionTime * occupancyManager.Smoothing + (1.0f - occupancyManager.Smoothing) * (stop - start);
        }
#endif
    }
    /// <summary>
    /// Generate synthetic test point cloud data for performance and debugging.
    /// </summary>
    public void GenerateTestData()
    {
        Debug.Log("Generating Test Data");

        Vector3 obs   = new Vector3(0, -1, 0);
        float   range = 6.0f;
        float   step  = 0.025f;

        for (float x = -range; x < range; x += step)
        {
            for (float z = -range; z < range; z += step)
            {
                float y = 0.5f * Mathf.Sin(2 * Mathf.Sqrt((x * x) + (z * z)));
                m_meshManager.InsertPoint(new Vector3(x, y, z + range), obs, 1.0f);
            }
        }

        m_meshManager.QueueDirtyMeshesForRegeneration();
    }
    /// <summary>
    /// Update is called once per frame.
    /// </summary>
    private void LateUpdate()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            m_pause = !m_pause;
        }

        if (Input.GetKeyDown(KeyCode.Slash))
        {
            m_step = true;
        }

        //history
        for (int i = 0; i < m_positionHistory.Count - 1; i++)
        {
            Debug.DrawLine(m_positionHistory[i], m_positionHistory[i + 1], Color.gray);
        }

        if (m_pause && !m_step)
        {
            DrawDebugLines();
            return;
        }

        m_step = false;

        if (m_playbackData)
        {
            ReadPoseFromFile(m_fileReader, ref m_poseAtDepthTimestamp);
            ReadDepthFromFile(m_fileReader, ref m_currTangoDepth, ref m_depthPoints);
            m_isDirty = true;
        }

        if (m_isDirty)
        {
            if (m_recordData)
            {
                WritePoseToFile(m_fileWriter, m_poseAtDepthTimestamp);
                WriteDepthToFile(m_fileWriter, m_currTangoDepth, m_depthPoints);
                m_debugText = "Recording Session: " + m_sessionTimestamp + " Points: " + m_currTangoDepth.m_timestamp;
            }
            ClearQuads();
            SetTransformUsingPose(transform, m_poseAtDepthTimestamp);

            if (m_playbackData)
            {
                m_mainCamera.transform.position = transform.position;
                m_mainCamera.transform.rotation = transform.rotation;
            }

            m_positionHistory.Add(transform.position);
            DrawDebugLines();
            float start = Time.realtimeSinceStartup;

            for (int i = 0; i < m_insertionCount; i++)
            {
                if (i > m_currTangoDepth.m_pointCount)
                {
                    break;
                }
                //randomly sub sample
                int index = i;
                //need to be more graceful than this, does not behave continuously
                if (m_insertionCount < m_currTangoDepth.m_pointCount)
                {
                    ;
                }
                index = UnityEngine.Random.Range(0, m_currTangoDepth.m_pointCount);

                Vector3 p = new Vector3(m_depthPoints[3 * index], -m_depthPoints[3 * index + 1], m_depthPoints[3 * index + 2]);

                Vector3 tp = transform.TransformPoint(p);

                float mag = Vector3.Magnitude(p);
                //less weight for things farther away, because of noise
                if (m_recordData)
                {
                    CreateQuad(p);
                }
                else
                {
                    m_occupancyManager.InsertPoint(tp, transform.forward, 0.2f / (mag + 1.0f));
                }
            }

            float stop = Time.realtimeSinceStartup;
            m_occupancyManager.InsertionTime = m_occupancyManager.InsertionTime * m_occupancyManager.Smoothing + (1.0f - m_occupancyManager.Smoothing) * (stop - start);
            m_occupancyManager.QueueDirtyMeshesForRegeneration();
            m_isDirty = false;
        }
    }