/// <summary>
    /// Wait for the next depth update, then find the plane at the touch position.
    /// </summary>
    /// <returns>Coroutine IEnumerator.</returns>
    /// <param name="touchPosition">Touch position to find a plane at.</param>
    private IEnumerator _WaitForDepthAndFindPlane(Vector2 touchPosition)
    {
        m_findPlaneWaitingForDepth = true;

        // Turn on the camera and wait for a single depth update.
        m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM);
        while (m_findPlaneWaitingForDepth)
        {
            yield return(null);
        }

        m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.DISABLED);

        // Find the plane.
        Camera  cam = Camera.main;
        Vector3 planeCenter;
        Plane   plane;

        if (!m_pointCloud.FindPlane(cam, touchPosition, out planeCenter, out plane))
        {
            yield break;
        }

        // Ensure the location is always facing the camera.  This is like a LookRotation, but for the Y axis.
        Vector3 up = plane.normal;
        Vector3 forward;

        if (Vector3.Angle(plane.normal, cam.transform.forward) < 175)
        {
            Vector3 right = Vector3.Cross(up, cam.transform.forward).normalized;
            forward = Vector3.Cross(right, up).normalized;
        }
        else
        {
            // Normal is nearly parallel to camera look direction, the cross product would have too much
            // floating point error in it.
            forward = Vector3.Cross(up, cam.transform.right);
        }


        // Instantiate produce object.
        newProduceObject = Instantiate(m_producePrefabs[m_currentProduceType],
                                       planeCenter,
                                       Quaternion.LookRotation(forward, up)) as GameObject;

        ARProduce produceScript = newProduceObject.GetComponent <ARProduce>();

        produceScript.m_type      = m_currentProduceType;
        produceScript.m_timestamp = (float)m_poseController.LastPoseTimestamp;

        Matrix4x4 uwTDevice = Matrix4x4.TRS(m_poseController.transform.position,
                                            m_poseController.transform.rotation,
                                            Vector3.one);
        Matrix4x4 uwTProduce = Matrix4x4.TRS(newProduceObject.transform.position,
                                             newProduceObject.transform.rotation,
                                             Vector3.one);

        produceScript.m_deviceTProduce = Matrix4x4.Inverse(uwTDevice) * uwTProduce;

        m_produceList.Add(newProduceObject);

        m_selectedProduce = null;
    }
    /// <summary>
    /// Unity OnGUI function.
    ///
    /// Mainly for removing produce.
    /// </summary>
    public void OnGUI()
    {
        if (m_selectedProduce != null)
        {
            Renderer selectedRenderer = m_selectedProduce.GetComponent <Renderer>();

            // GUI's Y is flipped from the mouse's Y
            Rect  screenRect = Utils.worldBoundsToScreen(Camera.main, selectedRenderer.bounds);
            float yMin       = Screen.height - screenRect.yMin;
            float yMax       = Screen.height - screenRect.yMax;
            screenRect.yMin = Mathf.Min(yMin, yMax);
            screenRect.yMax = Mathf.Max(yMin, yMax);

            float halfWidth  = screenRect.width / 2;
            float halfHeight = screenRect.height / 2;

            GUI.BeginGroup(screenRect);
            // All rectangles are now adjusted to the group. (0,0) is the topleft corner of the group.
            GUI.Box(
                new Rect(0, 0, screenRect.width, halfHeight),
                "<size=30>" + Utils.RemoveClone(m_selectedProduce.gameObject.name) + "</size>",
                m_GUIstyle_information);

            string   buttonText;
            GUIStyle buttonStyle;
            if (m_seeOnly)
            {
                buttonText  = "Ok";
                buttonStyle = m_GUIstyle_buttonValid;
            }
            else
            {
                buttonText  = "X";
                buttonStyle = m_GUIstyle_buttonRemove;
            }

            if (GUI.Button(new Rect(0, halfHeight, screenRect.width, halfHeight), buttonText, buttonStyle))
            {
                m_produceList.Remove(m_selectedProduce.gameObject);
                m_selectedProduce.SendMessage("Hide");
                m_selectedProduce = null;
                m_selectedRect    = new Rect();
                m_totalProduces   = m_totalProduces - 1;
                if (m_seeOnly)
                {
                    refreshValidProduces();
                }
            }
            else
            {
                m_selectedRect = screenRect;
            }

            // End the group we started above.
            GUI.EndGroup();
        }
        else
        {
            m_selectedRect = new Rect();
        }
    }
    // Update is called once per frame
    void Update()
    {
        if (m_saveThread != null && m_saveThread.ThreadState != ThreadState.Running)
        {
            // After saving the scan, we reload the scene.
                        #pragma warning disable 618
            Application.LoadLevel(Application.loadedLevel);
                        #pragma warning restore 618
        }

        if (Input.GetKey(KeyCode.Escape))
        {
                        #pragma warning disable 618
            Application.LoadLevel(Application.loadedLevel);
                        #pragma warning restore 618
        }

        if (!m_initialized)
        {
            return;
        }

        if (EventSystem.current.IsPointerOverGameObject(0) || GUIUtility.hotControl != 0)
        {
            return;
        }


        if (Input.touchCount == 1)
        {
            Touch      t           = Input.GetTouch(0);
            Vector2    guiPosition = new Vector2(t.position.x, Screen.height - t.position.y);
            Camera     cam         = Camera.main;
            RaycastHit hitInfo;

            if (t.phase != TouchPhase.Began)
            {
                return;
            }

            if (m_selectedRect.Contains(guiPosition))
            {
                // do nothing, the button will handle it
            }
            else if (Physics.Raycast(cam.ScreenPointToRay(t.position), out hitInfo))
            {
                // Found a produce, select it (so long as it isn't disappearing)!
                GameObject tapped = hitInfo.collider.gameObject;
                if (!tapped.GetComponent <Animation>().isPlaying)
                {
                    m_selectedProduce = tapped.GetComponent <ARProduce>();
                }
            }
            else
            {
                if (m_seeOnly)
                {
                    return;
                }
                // Place a new point at that location, clear selection
                m_selectedProduce = null;
                StartCoroutine(_WaitForDepthAndFindPlane(t.position));

                // Because we may wait a small amount of time, this is a good place to play a small
                // animation so the user knows that their input was received.
                RectTransform touchEffectRectTransform = Instantiate(m_prefabTouchEffect) as RectTransform;
                touchEffectRectTransform.transform.SetParent(m_canvas.transform, false);
                Vector2 normalizedPosition = t.position;
                normalizedPosition.x /= Screen.width;
                normalizedPosition.y /= Screen.height;
                touchEffectRectTransform.anchorMin = touchEffectRectTransform.anchorMax = normalizedPosition;
            }
        }
    }