public IEnumerator Touch(Vector3 touchPosition, Action <Vector3, Quaternion, int> action) { _findPlaneWaitingForDepth = true; _tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM); while (_findPlaneWaitingForDepth) { // action (Vector3.zero, Quaternion.identity, false); yield return(null); } _tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.DISABLED); Vector3 planeCenter; Plane plane; if (_pointCloud.FindPlane(Camera.main, touchPosition, out planeCenter, out plane)) { if (Vector3.Angle(plane.normal, Vector3.up) < 30.0f) { var forward = CameraForwardOnPlane(plane); var lookToCamera = Quaternion.LookRotation(-forward, plane.normal); action(planeCenter, lookToCamera, 1); } else { action(Vector3.zero, Quaternion.identity, 0); } } else { action(Vector3.zero, Quaternion.identity, 2); } }
/// <summary> /// Wait for the next depth update, then find the nearest edge in the point /// cloud. /// </summary> /// <param name="touchPosition">Touch position on the screen.</param> /// <returns>Coroutine IEnumerator.</returns> private IEnumerator _WaitForDepth(Vector2 touchPosition) { m_waitingForDepth = true; // Turn on the camera and wait for a single depth update m_tangoApplication.SetDepthCameraRate( TangoEnums.TangoDepthCameraRate.MAXIMUM); while (m_waitingForDepth) { yield return(null); } m_tangoApplication.SetDepthCameraRate( TangoEnums.TangoDepthCameraRate.DISABLED); m_camera = Camera.main; int pointIndex = m_pointCloud.FindClosestPoint(m_camera, touchPosition, 10); if (pointIndex > -1) { m_currTouch = m_pointCloud.m_points[pointIndex]; //_RenderCustomize(m_currTouch, new Vector3(m_currTouch[0] + 0.005f, m_currTouch[1], m_currTouch[2])); Debug.Log("<<<<<<<<<<<<<<<< mouse position: " + m_currTouch[0] + ", " + m_currTouch[1] + ", " + m_currTouch[2]); } TangoSupport.TangoSupportEdge[] edges; int num_edges; bool edgeResult = m_pointCloud.FindEdges(m_imagebuffer, m_camera, touchPosition, out edges, out num_edges); Debug.Log("<<<<<<<<<<< Edge result: " + edgeResult); if (edgeResult == true) { m_edgeCount = num_edges; m_startPoint = new Vector3[num_edges]; m_endPoint = new Vector3[num_edges]; m_nearestPoint = new Vector3[num_edges]; for (int i = 0; i < num_edges; i++) { Debug.Log("<<<<<<<<< starting point's x: " + edges[i].end_points_x1); m_startPoint[i] = new Vector3(edges[i].end_points_x1, edges[i].end_points_y1, edges[i].end_points_z1); Debug.Log("<<<<<<<<<< " + m_startPoint[i][0] + ", " + m_startPoint[i][1] + ", " + m_startPoint[i][2]); m_endPoint[i] = new Vector3(edges[i].end_points_x2, edges[i].end_points_y2, edges[i].end_points_z2); Debug.Log("<<<<<<<<<< " + m_endPoint[i][0] + ", " + m_endPoint[i][1] + ", " + m_endPoint[i][2]); m_nearestPoint[i] = new Vector3(edges[i].closest_point_on_edge_x, edges[i].closest_point_on_edge_y, edges[i].closest_point_on_edge_z); Debug.Log("<<<<<<<<<< " + m_nearestPoint[i][0] + ", " + m_nearestPoint[i][1] + ", " + m_nearestPoint[i][2]); } _RenderLine(); } }
public void Update() { //update timer _time += Time.deltaTime; if (_time > RecordingSystem.FloorScanRate && _searchCompleted == true) //update and check for ongoing search { //reset timer _time = 0; //request new floor position from pointcloud _searchCompleted = false; floorFound = false; _tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM); _pointCloud.FindFloor(); } // If the point cloud has found the floor, adjust the position accordingly. if (_pointCloud.m_floorFound) { _searchCompleted = true; floorFound = true; if (transform.position.y != _pointCloud.m_floorPlaneY) transform.position = new Vector3(0.0f, _pointCloud.m_floorPlaneY, 0.0f); } }
/// <summary> /// OnGUI is called for rendering and handling GUI events. /// </summary> public void OnGUI() { GUI.color = Color.white; if (!m_findingFloor) { if (GUI.Button(new Rect(Screen.width - 220, 20, 200, 80), "<size=30>Find Floor</size>")) { if (m_pointCloud == null) { Debug.LogError("TangoPointCloud required to find floor."); return; } m_findingFloor = true; m_marker.SetActive(false); m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM); m_pointCloud.FindFloor(); } } else { GUI.Label(new Rect(0, Screen.height - 50, Screen.width, 50), "<size=30>Searching for floor position. Make sure the floor is visible.</size>"); } }
/// <summary> /// Update is called once per frame. /// </summary> public void Update() { // If the point cloud has found the floor, adjust the position accordingly. if (m_pointCloud.m_floorFound) { m_floorFound = true; if (transform.position.y != m_pointCloud.m_floorPlaneY) { transform.position = new Vector3(0.0f, m_pointCloud.m_floorPlaneY, 0.0f); foreach (Transform t in transform) { t.gameObject.SetActive(true); } } // Disable depth camera if requested and not already done. if (m_turnOffDepthCamera && !m_depthTriggered) { m_depthTriggered = true; m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.DISABLED); } } else { m_floorFound = false; m_depthTriggered = false; } }
/// <summary> /// This is called when successfully connected to the Tango service. /// </summary> public void OnTangoServiceConnected() { m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.DISABLED); }
/// <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; }
private IEnumerator _AddBalloon(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; // Ensure the location is always facing the camera. This is like a LookRotation, but for the Y axis. Vector3 up = Vector3.up; // plane.normal; Vector3 forward; if (Vector3.Angle(Vector3.up, 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); } Vector3 inFront = cam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.5f)); // Instantiate marker object. GameObject newMarkObject = Instantiate(m_marker, inFront, Quaternion.LookRotation(forward, Vector3.up) ) as GameObject; BloonMarker markerScript = newMarkObject.GetComponent <BloonMarker>(); // markerScript.m_type = m_currentMarkType; // markerScript.m_timestamp = (float)m_poseController.m_poseTimestamp; // Matrix4x4 uwTDevice = Matrix4x4.TRS(m_poseController.m_tangoPosition, // m_poseController.m_tangoRotation, // Vector3.one); // Matrix4x4 uwTMarker = Matrix4x4.TRS(newMarkObject.transform.position, // newMarkObject.transform.rotation, // Vector3.one); // markerScript.m_deviceTMarker = Matrix4x4.Inverse(uwTDevice) * uwTMarker; // m_markerList.Add(newMarkObject); m_balloonAddedListener(newMarkObject); m_currentMarker = markerScript; Debug.LogFormat("Balloon successfully Created: {0}", m_currentMarker); m_micHelper.StartRecording(m_currentMarker); }
/// <summary> /// OnGUI is called for rendering and handling GUI events. /// </summary> public void OnGUI() { GUI.skin = mySkin; if (!m_findingFloor && !showMarkerMenu) { if (GUI.Button(new Rect(Screen.width - 220, 20, 200, 80), "<size=30>Find Floor</size>")) { if (m_pointCloud == null) { Debug.LogError("TangoPointCloud required to find floor."); return; } m_findingFloor = true; m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM); m_pointCloud.FindFloor(); } } else if (showMarkerMenu) { if (GUI.Button(new Rect(Screen.width - buttonWidth * 6, 20, buttonWidth, 80), "<size=30>Marker 1</size>")) { PlaceMarker(0); } if (GUI.Button(new Rect(Screen.width - buttonWidth * 5, 20, buttonWidth, 80), "<size=30>Marker 2</size>")) { PlaceMarker(1); } if (GUI.Button(new Rect(Screen.width - buttonWidth * 4, 20, buttonWidth, 80), "<size=30>Marker 3</size>")) { PlaceMarker(2); } if (GUI.Button(new Rect(Screen.width - buttonWidth * 3, 20, buttonWidth, 80), "<size=30>Marker 4</size>")) { PlaceMarker(3); } if (GUI.Button(new Rect(Screen.width - buttonWidth * 2, 20, buttonWidth, 80), "<size=30>Marker 5</size>")) { PlaceMarker(4); } if (GUI.Button(new Rect(Screen.width - buttonWidth, 20, buttonWidth, 80), "<size=30>Marker 6</size>")) { PlaceMarker(5); copyPosition.UpdateTargetTransform(5, 0); PlaceMarker(6); copyPosition.UpdateTargetTransform(6, 0); PlaceMarker(5); } if (markerCount > 0) { if (theLatestButton != 2 && theLatestButton != 5 && theLatestButton != 6) { hSliderValue = GUI.HorizontalSlider(new Rect(25, 150, Screen.width / 2, Screen.height / 6), hSliderValue, 0.0F, 360.0F); scaleSliderValue = GUI.HorizontalSlider(new Rect(25, 350, Screen.width / 2, Screen.height / 6), scaleSliderValue, 0F, latestScaleValue * 2f); } Vector3 newAngle = new Vector3(0, hSliderValue, 0); markerDictionary[theLatestButton].transform.eulerAngles = newAngle; Vector3 newScale = new Vector3(scaleSliderValue, scaleSliderValue, scaleSliderValue); sceneDictionary[theLatestButton].transform.localScale = newScale; copyPosition.UpdateTargetTransform(theLatestButton, 2); } // Confirm Button if (showConfirm) { if (GUI.Button(new Rect(Screen.width - buttonWidth, 100, buttonWidth, 80), "<size=30>OK!</size>")) { this.gameObject.SetActive(false); showMarkerMenu = false; ShowOnFinish(); } } } else { GUI.Label(new Rect(0, Screen.height - 50, Screen.width, 50), "<size=30>Searching for floor position. Make sure the floor is visible.</size>"); } }
/// <summary> /// Update is called once per frame. /// </summary> public void Update() { if (Input.GetKey(KeyCode.Escape)) { // This is a fix for a lifecycle issue where calling // Application.Quit() here, and restarting the application // immediately results in a deadlocked app. AndroidHelper.AndroidQuit(); } if (isEnabled) { pollTimer += Time.deltaTime; //poll floor every 2 seconds if (pollTimer > 2) { pollTimer = 0; if (m_pointCloud == null) { Debug.LogError("TangoPointCloud required to find floor."); return; } m_findingFloor = true; //m_marker.SetActive(false); m_tangoApplication.SetDepthCameraRate(TangoEnums.TangoDepthCameraRate.MAXIMUM); m_pointCloud.FindFloor(); } //check if already found if (!m_findingFloor) { return; } // If the point cloud floor has found a new floor, place the marker at the found y position. if (m_pointCloudFloor.m_floorFound && m_pointCloud.m_floorFound) { m_findingFloor = false; // Place the marker at the center of the screen at the found floor height. Vector3 target; RaycastHit hitInfo; if (Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f)), out hitInfo)) { //create marker var marker = GameObject.Instantiate(m_marker); marker.transform.parent = gameObject.transform; // Limit distance of the marker position from the camera to the camera's far clip plane. This makes sure that the marker // is visible on screen when the floor is found. Vector3 cameraBase = new Vector3(Camera.main.transform.position.x, hitInfo.point.y, Camera.main.transform.position.z); //target = cameraBase + Vector3.ClampMagnitude(hitInfo.point - cameraBase, Camera.main.farClipPlane * 0.9f); marker.transform.position = cameraBase; } //else //{ // If no raycast hit, place marker in the camera's forward direction. //Vector3 dir = new Vector3(Camera.main.transform.forward.x, 0.0f, Camera.main.transform.forward.z); //target = dir.normalized * (Camera.main.farClipPlane * 0.9f); //target.y = m_pointCloudFloor.transform.position.y; //} //marker.transform.position = target; //AndroidHelper.ShowAndroidToastMessage(string.Format("Floor found. Unity world height = {0}", m_pointCloudFloor.transform.position.y.ToString())); } } }
/// <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> /// <param name="doorCorridorPosition">Door position where to put the door marker.</param> /// <param name="wall">Touch position to find a plane at.</param> /// <param name="doorCorridorBool">True if we are putting a door marker.</param> private IEnumerator _WaitForDepthAndFindPlane(Vector2 touchPosition, Vector3 doorCorridorPosition = new Vector3(), Wall wall = null, bool doorCorridorBool = false) { if (!doorCorridorBool) { if (m_currentMarkType == 1 || m_currentMarkType == 2) { AndroidHelper.ShowAndroidToastMessage("Door or corridors must be on walls"); yield break; } } 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 I'm selecting the floor, set the floor plane if (m_currentMarkType == 3) { if (!m_pointCloud.FindPlane(cam, touchPosition, out planeCenter, out plane)) { yield break; } m_pointCloud.FindFloor(); floor = new Floor(plane, planeCenter); Debug.Log("Height of the floor " + planeCenter.y); AndroidHelper.ShowAndroidToastMessage("Floor found!"); yield break; } else if (!m_pointCloud.m_floorFound) { AndroidHelper.ShowAndroidToastMessage("Please, select first the floor"); yield break; } // Find me the point I touched on screen on world coordinates if I'm not putting a door... if (!doorCorridorBool) { int i = m_pointCloud.FindClosestPoint(cam, touchPosition, 10); if (i < 0) { yield break; } planeCenter = m_pointCloud.m_points [i]; // Put the marker on the floor height planeCenter.y = floor.floorCenter.y; } //... else my door position is already set as parameter. else { planeCenter = doorCorridorPosition; } // Ensure the location is always facing the camera. This is like a LookRotation, but for the Y axis. Vector3 up = floor.floorPlane.normal; Vector3 forward; if (Vector3.Angle(floor.floorPlane.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 marker object. newMarkObject = Instantiate(m_markPrefabs [m_currentMarkType], planeCenter, Quaternion.LookRotation(forward, up)) as GameObject; newMarkObject.tag = "CornersAndWalls"; ARMarker markerScript = newMarkObject.GetComponent <ARMarker> (); markerScript.m_type = m_currentMarkType; markerScript.m_timestamp = (float)m_poseController.LastPoseTimestamp; Matrix4x4 uwTDevice = Matrix4x4.TRS(m_poseController.transform.position, m_poseController.transform.rotation, Vector3.one); Matrix4x4 uwTMarker = Matrix4x4.TRS(newMarkObject.transform.position, newMarkObject.transform.rotation, Vector3.one); markerScript.m_deviceTMarker = Matrix4x4.Inverse(uwTDevice) * uwTMarker; m_markerList.Add(newMarkObject); prevTouchPos = null; selectedLine = null; m_selectedMarker = null; switch (m_currentMarkType) { // Corner case. case 0: corners.Add(new Corner(newMarkObject)); break; // Door case. case 1: TouchScreenKeyboard kb = TouchScreenKeyboard.Open("", TouchScreenKeyboardType.Default, false, false, false, false, "Write the name for this destination marker"); while (!kb.done && !kb.wasCanceled) { yield return(null); } newMarkObject.name = kb.text; doors.Add(new Corner(newMarkObject, wall)); break; default: Debug.Log("No valid point inserted."); break; } }