/// <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; } } }