public static ShowAndroidToastMessage ( string message ) : void | ||
message | string | Message string to show in the toast. |
Résultat | void |
private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { if (permissionsGranted && !m_alreadyInitialized) { Debug.Log("SampleController._OnApplicationPermissionsEvent()"); m_shouldInitTango = true; } else if (!permissionsGranted) { AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); } if (permissionsGranted && m_alreadyInitialized) { m_tangoApplication.ConnectToService(); } }
/// <summary> /// This callback function is called after user appoved or declined the permission to use Motion Tracking. /// </summary> /// <param name="permissionsGranted">If the permissions were granted.</param> private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { if (permissionsGranted) { m_tangoApplication.InitApplication(); m_tangoApplication.InitProviders(string.Empty); m_tangoApplication.ConnectToService(); // Ask ARScreen to query the camera intrinsics from Tango Service. _SetCameraIntrinsics(); _SetCameraExtrinsics(); } else { AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); } }
/// <summary> /// Validate the TangoService version is supported. /// </summary> private void _CheckTangoVersion() { int tangoVersion = _GetTangoAPIVersion(); if (tangoVersion < MINIMUM_API_VERSION) { Debug.Log(string.Format(CLASS_NAME + ".Initialize() Invalid API version {0}. Please update Project Tango Core to at least {1}.", tangoVersion, MINIMUM_API_VERSION)); if (!m_allowOutOfDateTangoAPI) { AndroidHelper.ShowAndroidToastMessage("Please update Tango Core", false); return; } } m_isServiceInitialized = true; Debug.Log(CLASS_NAME + ".Initialize() Tango was initialized!"); }
/// <summary> /// This is called when the permission granting process is finished. /// </summary> /// <param name="permissionsGranted"><c>true</c> if permissions were granted, otherwise <c>false</c>.</param> public void OnTangoPermissions(bool permissionsGranted) { if (permissionsGranted) { if (m_tangoApplication.m_enableADFLoading && m_areaDescription != null) { m_tangoApplication.Startup(m_areaDescription); } else { m_tangoApplication.Startup(null); } } else { AndroidHelper.ShowAndroidToastMessage("Motion Tracking Permissions Needed", true); } }
/// <summary> /// Internal callback when a permissions event happens. /// </summary> /// <param name="permissionsGranted">If set to <c>true</c> permissions granted.</param> private void _OnTangoApplicationPermissionsEvent(bool permissionsGranted) { if (permissionsGranted) { m_tangoApplication.InitApplication(); // Load the most recent ADF. PoseProvider.RefreshADFList(); string uuid = PoseProvider.GetLatestADFUUID().GetStringDataUUID(); m_tangoApplication.InitProviders(uuid); m_tangoApplication.ConnectToService(); } else { AndroidHelper.ShowAndroidToastMessage("Motion Tracking and Area Learning Permissions Needed", true); } }
/// <summary> /// Start the game. /// /// This will start the service connection, and start pose estimation from Tango Service. /// </summary> /// <param name="isNewAreaDescription">If set to <c>true</c> game with start to learn a new Area /// Description.</param> public void StartGame(bool isNewAreaDescription) { // The game has to be started with an Area Description. if (!isNewAreaDescription) { if (string.IsNullOrEmpty(m_curAreaDescriptionUUID)) { AndroidHelper.ShowAndroidToastMessage("Please choose an Area Description."); return; } } else { m_curAreaDescriptionUUID = null; } // Dismiss Area Description list, footer and header UI panel. gameObject.SetActive(false); if (isNewAreaDescription) { // Completely new area description. m_deltaPoseController.m_areaDescription = null; m_deltaPoseController.m_useAreaDescriptionPose = false; m_guiController.m_curAreaDescription = null; m_tangoApplication.m_enableAreaLearning = true; } else { // Load up an Area Description. Delta pose controller will take the current Area Description and listen // to the Device with respect Area Description pose. AreaDescription areaDescription = AreaDescription.ForUUID(m_curAreaDescriptionUUID); m_deltaPoseController.m_areaDescription = areaDescription; m_deltaPoseController.m_useAreaDescriptionPose = true; m_guiController.m_curAreaDescription = areaDescription; m_tangoApplication.m_enableAreaLearning = m_enableLearningToggle.isOn; } // Enable GUI controller to allow user tap and interactive with the environment. m_deltaPoseController.enabled = true; m_guiController.enabled = true; m_gameControlPanel.SetActive(true); }
/// <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 (!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_findingFloor = false; // Place the marker at the center of the screen at the found floor height. m_marker.SetActive(true); Vector3 target; RaycastHit hitInfo; if (Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f)), out hitInfo)) { // 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); } 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; } m_marker.transform.position = target; AndroidHelper.ShowAndroidToastMessage(string.Format("Floor found. Unity world height = {0}", m_pointCloudFloor.transform.position.y.ToString())); } }
/// <summary> /// Remove xml description via path if exists. /// </summary> /// <param name="path">Path to xml definition.</param> /// <returns>If removing was successfull.</returns> private bool _DeleteXMLFile(string path) { if (!File.Exists(path)) { AndroidHelper.ShowAndroidToastMessage("XML description doesn't exist."); return(true); } File.Delete(path); if (File.Exists(path)) { AndroidHelper.ShowAndroidToastMessage("Removing of XML was unsuccessfull."); return(false); } AndroidHelper.ShowAndroidToastMessage("Removing XML definition was successful."); return(true); }
/// <summary> /// Create evaluated graph by distances. /// </summary> /// <param name="m_markerDictionary">Dictionary with markers.</param> public void CreateEvaluatedGraph(Dictionary <int, GameObject> m_markerDictionary) { int maxId = m_markerDictionary.Keys.Max() + 1; graph2D = new double[maxId, maxId]; markersPositions = new Dictionary <int, Vector3>(); foreach (KeyValuePair <int, GameObject> marker in m_markerDictionary) { int markerId = marker.Key; Dictionary <int, GameObject> renderers = marker.Value.GetComponent <ARMarker>().GetRendersDictionary(); markersPositions.Add(marker.Key, marker.Value.transform.position); foreach (KeyValuePair <int, GameObject> rendererObj in renderers) { // get points of line from renderer (it contains marker and neighbour poisition) int neighbourId = rendererObj.Key; Line renderer = rendererObj.Value.GetComponent <Line>(); Vector3[] neighbourPositions = new Vector3 [renderer.GetNumPositions()]; renderer.GetPositions(neighbourPositions); // fill marker and neighbour position if (neighbourPositions.Length < 2) { AndroidHelper.ShowAndroidToastMessage("Positions of marker " + markerId + " are EMPTY!"); return; } Vector3 markerPosition = neighbourPositions[0]; Vector3 neighbourPosition = neighbourPositions[1]; // compute distance between both markers double distance = Vector3.Distance(markerPosition, neighbourPosition); // filled for markers in both directions graph2D[markerId, neighbourId] = distance; graph2D[neighbourId, markerId] = distance; } } AndroidHelper.ShowAndroidToastMessage("Evaluated graph was created!"); }
/// <summary> /// Remove area description with xml if exists. /// </summary> public void RemoveAreaDescription() { if (m_curAreaDescriptionUUID != null) { string path = Application.persistentDataPath + "/" + m_curAreaDescriptionUUID + ".xml"; if (!_DeleteXMLFile(path)) { return; } AreaDescription areaDescription = AreaDescription.ForUUID(m_curAreaDescriptionUUID); areaDescription.Delete(); _PopulateList(); m_curAreaDescriptionUUID = null; } else { AndroidHelper.ShowAndroidToastMessage("Please, choose an area description in list."); } }
/// <summary> /// Start the game. /// /// This will start the service connection, and start pose estimation from Tango Service. /// </summary> /// <param name="isNewAreaDescription">If set to <c>true</c> game with start to learn a new Area /// Description.</param> public void StartGame(bool isNewAreaDescription) { // The game has to be started with an Area Description. if (!isNewAreaDescription) { if (string.IsNullOrEmpty(m_curAreaDescriptionUUID)) { AndroidHelper.ShowAndroidToastMessage("탈출로를 선택해주세요!"); return; } GameObject.Find("Background").SetActive(false); } else { m_curAreaDescriptionUUID = null; } // Dismiss Area Description list, footer and header UI panel. gameObject.SetActive(false); if (isNewAreaDescription) { // Completely new area description. m_guiController.m_curAreaDescription = null; m_tangoApplication.m_areaDescriptionLearningMode = true; } else { // Load up an existing Area Description. AreaDescription areaDescription = AreaDescription.ForUUID(m_curAreaDescriptionUUID); m_guiController.m_curAreaDescription = areaDescription; m_tangoApplication.m_areaDescriptionLearningMode = m_enableLearningToggle.isOn; } m_tangoApplication.Startup(m_guiController.m_curAreaDescription); // Enable GUI controller to allow user tap and interactive with the environment. m_poseController.gameObject.SetActive(true); m_guiController.enabled = true; m_gameControlPanel.SetActive(true); }
public bool StartGame() //需要不停探测,直到打开一个区域,或者由界面打开 { if (!m_needNewAreaDescription) { if (string.IsNullOrEmpty(m_curAreaDescriptionUUID)) { AndroidHelper.ShowAndroidToastMessage("没有区域描述."); return(false); } } else { m_curAreaDescriptionUUID = null; } // Dismiss Area Description list, footer and header UI panel. //gameObject.SetActive(false); if (m_needNewAreaDescription) { // Completely new area description. //m_guiController.m_curAreaDescription = null; TangoManager.Instance.m_curAreaDescription = null; m_tangoApplication.m_areaDescriptionLearningMode = true; } else { // Load up an existing Area Description. AreaDescription areaDescription = AreaDescription.ForUUID(m_curAreaDescriptionUUID); TangoManager.Instance.m_curAreaDescription = areaDescription; m_tangoApplication.m_areaDescriptionLearningMode = m_enableLearningToggle; } m_tangoApplication.Startup(TangoManager.Instance.m_curAreaDescription); // Enable GUI controller to allow user tap and interactive with the environment. m_poseController.gameObject.SetActive(true); return(true); //m_guiController.enabled = true; //m_gameControlPanel.SetActive(true); }
/// <summary> /// This is called when the permission granting process is finished. /// </summary> /// <param name="permissionsGranted"><c>true</c> if permissions were granted, otherwise <c>false</c>.</param> public void OnTangoPermissions(bool permissionsGranted) { if (permissionsGranted) { _PopulateList(); if (!PhotonNetwork.connected) { PhotonNetwork.ConnectUsingSettings("0.1"); } if (PhotonNetwork.inRoom) { PhotonNetwork.LeaveRoom(); } } else { AndroidHelper.ShowAndroidToastMessage("Tango permission needed"); Application.Quit(); } }
/// <summary> /// Update is called once per frame. /// </summary> public void Update() { if (Input.GetKey(KeyCode.Escape)) { Application.Quit(); } 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; //DropMarker(); showMarkerMenu = true; AndroidHelper.ShowAndroidToastMessage(string.Format("Floor found. Unity world height = {0}", m_pointCloudFloor.transform.position.y.ToString())); } }
// Update is called once per frame void Update() { if (!tinfo.PoseOk) { return; } if (Input.GetMouseButtonDown(0)) { Vector3 cpos = Input.mousePosition; RaycastHit hitInfo; if (Physics.Raycast(Camera.main.ScreenPointToRay(cpos), out hitInfo, Mathf.Infinity, 1 << LayerMask.NameToLayer("TangoMesh"))) { this.transform.position = hitInfo.point + new Vector3(0, 1, 0); ap.p = this.transform.position; udp.SendPose(ap); } else { AndroidHelper.ShowAndroidToastMessage("Not Recognized Area", AndroidHelper.ToastLength.SHORT); } } }
/// <summary> /// Called when a JoinRoom() call failed. The parameter provides ErrorCode and message (as array). /// </summary> /// <remarks> /// Most likely error is that the room does not exist or the room is full (some other client was faster than you). /// PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational. /// </remarks> /// <param name="codeAndMsg">CodeAndMsg[0] is short ErrorCode. codeAndMsg[1] is string debug msg.</param> public override void OnPhotonJoinRoomFailed(object[] codeAndMsg) { AndroidHelper.ShowAndroidToastMessage("Join room failed"); Debug.Log("Join room failed" + Environment.StackTrace); _QuitGame(); }
/// <summary> /// Exports the constructed mesh to an OBJ file format. The file will include info /// based on the enabled options in TangoApplication. /// </summary> /// <param name="filepath">File path to output the OBJ.</param> public void ExportMeshToObj(string filepath) { AndroidHelper.ShowAndroidToastMessage("Exporting mesh..."); StringBuilder sb = new StringBuilder(); int startVertex = 0; foreach (TangoSingleDynamicMesh tmesh in m_meshes.Values) { Mesh mesh = tmesh.m_mesh; int meshVertices = 0; sb.Append(string.Format("g {0}\n", tmesh.name)); // Vertices. for (int i = 0; i < mesh.vertices.Length; i++) { meshVertices++; Vector3 v = tmesh.transform.TransformPoint(mesh.vertices[i]); // Include vertex colors as part of vertex point for applications that support it. if (mesh.colors32.Length > 0) { float r = mesh.colors32[i].r / 255.0f; float g = mesh.colors32[i].g / 255.0f; float b = mesh.colors32[i].b / 255.0f; sb.Append(string.Format("v {0} {1} {2} {3} {4} {5} 1.0\n", v.x, v.y, -v.z, r, g, b)); } else { sb.Append(string.Format("v {0} {1} {2} 1.0\n", v.x, v.y, -v.z)); } } sb.Append("\n"); // Normals. if (mesh.normals.Length > 0) { foreach (Vector3 n in mesh.normals) { sb.Append(string.Format("vn {0} {1} {2}\n", n.x, n.y, -n.z)); } sb.Append("\n"); } // Texture coordinates. if (mesh.uv.Length > 0) { foreach (Vector3 uv in mesh.uv) { sb.Append(string.Format("vt {0} {1}\n", uv.x, uv.y)); } sb.Append("\n"); } // Faces. int[] triangles = mesh.triangles; for (int j = 0; j < triangles.Length; j += 3) { sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", triangles[j + 2] + 1 + startVertex, triangles[j + 1] + 1 + startVertex, triangles[j] + 1 + startVertex)); } sb.Append("\n"); startVertex += meshVertices; } StreamWriter sw = new StreamWriter(filepath); sw.AutoFlush = true; sw.Write(sb.ToString()); AndroidHelper.ShowAndroidToastMessage(string.Format("Exported: {0}", filepath)); }
/// <summary> /// From button press: start the game by loading the mesh and the Area Description. /// /// Generate a new mesh from the saved area definition mesh data linked to the selected Area Description. /// </summary> public void Button_StartAreaDescriptionMesh() { if (string.IsNullOrEmpty(m_savedUUID)) { AndroidHelper.ShowAndroidToastMessage("Please choose an Area Description."); return; } if (!File.Exists(m_meshSavePath + "/" + m_savedUUID)) { AndroidHelper.ShowAndroidToastMessage("Please choose an Area Description with mesh data."); return; } m_3dReconstruction = false; m_menuOpen = false; // Enable objects needed to use Area Description and mesh for occlusion. m_arPoseController.gameObject.SetActive(true); m_arPoseController.m_useAreaDescriptionPose = true; m_mapObjectsContainer.gameObject.SetActive(true); // Disable unused components in tango application. m_tangoApplication.m_areaDescriptionLearningMode = false; m_tangoApplication.m_enableDepth = false; // Set UI panel to the mesh interaction panel. m_relocalizeImage.gameObject.SetActive(true); m_areaDescriptionLoaderPanel.SetActive(false); m_meshBuildPanel.SetActive(false); m_meshInteractionPanel.SetActive(true); // Set the player to be the car we just created m_playerContainer.transform.DetachChildren(); Transform myCar = m_builderObjectsContainer.transform.GetChild(0); myCar.SetParent(m_playerContainer.transform); myCar.gameObject.SetActive(true); //Destroy(myCar.GetChild(myCar.childCount - 1).gameObject); // Load mesh. AreaDescriptionMesh mesh = _DeserializeAreaDescriptionMesh(m_savedUUID); if (mesh == null) { return; } // Create GameObject container with mesh components for the loaded mesh. m_meshFromFile = new GameObject(); MeshFilter mf = m_meshFromFile.AddComponent <MeshFilter>(); mf.mesh = _AreaDescriptionMeshToUnityMesh(mesh); MeshRenderer mr = m_meshFromFile.AddComponent <MeshRenderer>(); mr.material = m_depthMaskMat; m_meshFromFile.AddComponent <MeshCollider>(); m_meshFromFile.layer = LayerMask.NameToLayer("Occlusion"); Vector3 bottomPoint = mr.bounds.min; m_mapObjectsContainer.transform.GetChild(0).position = bottomPoint; // Load Area Description file. m_curAreaDescription = AreaDescription.ForUUID(m_savedUUID); m_tangoApplication.Startup(m_curAreaDescription); }
/// <summary> /// Informs the user that they should install Tango Core via Android toast. /// </summary> /// <returns>IEnumerator used for coroutines.</returns> private IEnumerator _InformUserNoTangoCore() { AndroidHelper.ShowAndroidToastMessage("Please install Tango Core", false); yield return new WaitForSeconds(2.0f); Application.Quit(); }
/// <summary> /// Create the NavMesh and enable the navigation system. /// </summary> /// <returns>Coroutine IEnumerator.</returns> private IEnumerator DrawCorridorsRoutine() { // If the mesh hasn't been created yet then do it. if (!mesh.activeSelf) { if (!m_pointCloud.m_floorFound) { AndroidHelper.ShowAndroidToastMessage("Please, select first the floor"); yield break; } Debug.Log("Creating mesh..."); // Put the mesh at the floor level mesh.transform.Translate(Vector3.down * (mesh.transform.position.y - floor.floorCenter.y)); MeshCreator.CreateMesh(mesh, Application.persistentDataPath + "/" + m_curAreaDescription.m_uuid + "Marker.xml", Application.persistentDataPath + "/" + m_curAreaDescription.m_uuid + "Wall.xml", m_curAreaDescription.m_uuid); GameObject[] gs = GameObject.FindGameObjectsWithTag("CornersAndWalls"); // Hide all the markers. foreach (GameObject g in gs) { g.SetActive(false); } navPanel.SetActive(true); editPanel.SetActive(false); } // The mesh has been already created, then navigate. else { Debug.Log("Showing mesh..."); List <string> places = new List <string> (); foreach (Corner c in doors) { places.Add(c.point.name); } places.Sort(); // Show the destinations in a list. singleChoice.Show(places.ToArray()); singleChoice.OnResult.AddListener((value) => setDestination(value)); // Wait for the destination to be set. while (!currentDestSet) { yield return(null); } // Destroy the previous path GameObject[] gs = GameObject.FindGameObjectsWithTag("Path"); foreach (GameObject game in gs) { Destroy(game); } NavMeshPath path = new NavMeshPath(); NavMeshHit hit; NavMeshHit hit2; Vector3 startingPoint = m_poseController.transform.position; // The destination point isn't on the NavMesh, therefore we find the closest point to it on the mesh Debug.Log(NavMesh.SamplePosition(startingPoint, out hit, 5f, NavMesh.AllAreas)); Vector3 destPoint = doors[currentDestIndex].point.transform.position; Debug.Log(NavMesh.SamplePosition(destPoint, out hit2, 5f, NavMesh.AllAreas)); Debug.Log(NavMesh.CalculatePath(hit.position, hit2.position, NavMesh.AllAreas, path)); GameObject g = DrawLine(path.corners [0], path.corners [1], 9); LineRenderer lr = g.GetComponent <LineRenderer> (); Vector3[] newPath = new Vector3[path.corners.Length + 1]; path.corners.CopyTo(newPath, 0); newPath [newPath.Length - 1] = destPoint; lr.positionCount = newPath.Length; lr.SetPositions(newPath); lr.startColor = new Color32(252, 70, 107, 1); lr.endColor = new Color32(63, 94, 251, 1); //lr.material.color = Color.blue; lr.widthMultiplier = 10f; lr.tag = "Path"; currentDestSet = false; } yield break; }
/// <summary> /// Add or delete line in 2D. /// </summary> public void AddLineIn2D() { GameObject tmp; if (newSelectedID == -1) { return; } if (newSelectedID != -1 && connectMarkersId[0] == -1) { connectMarkersId[0] = newSelectedID; buttons.TryGetValue(connectMarkersId[0], out tmp); tmp.GetComponent <Image>().color = NEWLINE_BUTTON_COLOR; return; } if (newSelectedID != -1 && connectMarkersId[1] == -1 && connectMarkersId[0] != newSelectedID) { connectMarkersId[1] = newSelectedID; buttons.TryGetValue(connectMarkersId[1], out tmp); tmp.GetComponent <Image>().color = NEWLINE_BUTTON_COLOR; } else { AndroidHelper.ShowAndroidToastMessage("Select second marker!"); return; } // DELETE LINE if (connectMarkersId[0] != -1 && connectMarkersId[1] != -1 && graph2D[connectMarkersId[0], connectMarkersId[1]] != 0) { KeyPair tmpKeyPair = null; foreach (KeyValuePair <KeyPair, GameObject> renderer in lineRenderers) { if (renderer.Key.keys[0] == connectMarkersId[0] && renderer.Key.keys[1] == connectMarkersId[1]) { tmpKeyPair = renderer.Key; break; } } if (tmpKeyPair == null) { foreach (KeyValuePair <KeyPair, GameObject> renderer in lineRenderers) { if (renderer.Key.keys[0] == connectMarkersId[1] && renderer.Key.keys[1] == connectMarkersId[0]) { tmpKeyPair = renderer.Key; break; } } } if (tmpKeyPair != null) { GameObject tmpObject; lineRenderers.TryGetValue(tmpKeyPair, out tmpObject); Destroy(tmpObject); lineRenderers.Remove(tmpKeyPair); } areaLearning.RemoveLineBetweenMarkers(connectMarkersId[0], connectMarkersId[1]); graph2D[connectMarkersId[0], connectMarkersId[1]] = 0; graph2D[connectMarkersId[1], connectMarkersId[0]] = 0; ResetSelectedMarkers(); AndroidHelper.ShowAndroidToastMessage("Connecion is deleted."); return; } // CREATE LINE if (connectMarkersId[0] != -1 && connectMarkersId[1] != -1 && graph2D[connectMarkersId[0], connectMarkersId[1]] == 0) { Vector2 firstPosition; Vector2 secondPosition; newMarkersPosition.TryGetValue(connectMarkersId[0], out firstPosition); newMarkersPosition.TryGetValue(connectMarkersId[1], out secondPosition); _AddLine(firstPosition, secondPosition, connectMarkersId[0], connectMarkersId[1]); firstPosition = new Vector2(firstPosition.x / SCALING, firstPosition.y / SCALING); secondPosition = new Vector2(secondPosition.x / SCALING, secondPosition.y / SCALING); float distance = Vector2.Distance(firstPosition, secondPosition); graph2D[connectMarkersId[0], connectMarkersId[1]] = distance; graph2D[connectMarkersId[1], connectMarkersId[0]] = distance; areaLearning.AddLineWithIds(connectMarkersId[0], connectMarkersId[1]); ResetSelectedMarkers(); AndroidHelper.ShowAndroidToastMessage("Created is created."); } }
/// <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; } }
/// <summary> /// Function which will decide what to do with a collider hit. /// </summary> /// <param name="hitInfo">Information about the object we hit.</param> public void Marker(RaycastHit hitInfo) { Debug.Log(hitInfo.collider.GetType()); // I hit a marker so I have to create a wall in case it's the second marker I hit. if (prevTouchPos != null && hitInfo.collider.GetType() == typeof(MeshCollider)) { if (prevTouchPos.GetComponent <ARMarker> ().m_type == 0 && hitInfo.collider.gameObject.GetComponent <ARMarker> ().m_type == 0) { Vector3 startPos = prevTouchPos.transform.position; Vector3 endPos = hitInfo.collider.gameObject.transform.position; // Instantiate the line and add it to the list. GameObject g = DrawLine(startPos, endPos, 8); lines.Add(g); Wall wall = new Wall(corners.Find(x => x.point == prevTouchPos), corners.Find(x => x.point == hitInfo.collider.gameObject), g.GetInstanceID()); walls.Add(wall); } else { AndroidHelper.ShowAndroidToastMessage("You have to connect two corners"); } prevTouchPos = null; selectedLine = null; m_selectedMarker = null; return; } // Found a marker/line for the first time, select it (so long as it isn't disappearing)! GameObject tapped = hitInfo.collider.gameObject; // I hit a marker, so I select it. if (hitInfo.collider.GetType() == typeof(MeshCollider)) { // If there was no selected marker, select this; else it will be handled by OnGui() if (!tapped.GetComponent <Animation> ().isPlaying) { m_selectedMarker = tapped.GetComponent <ARMarker> (); prevTouchPos = tapped; selectedLine = null; } AndroidHelper.ShowAndroidToastMessage("Hide this corner or select another one to create a wall"); return; } // I hit a line else if (hitInfo.collider.GetType() == typeof(CapsuleCollider)) { // In this case I'm putting a door. Doors can be only on walls. if (m_currentMarkType == 1) { Wall w = walls.Find(x => x.lineID == hitInfo.collider.gameObject.GetInstanceID()); Debug.Log("Wall is from " + w.fromCorner.point.transform.position + " and you hit on " + hitInfo.point); StartCoroutine(_WaitForDepthAndFindPlane(Vector2.zero, ProjectPointOnLineSegment(w.fromCorner.point.transform.position, w.toCorner.point.transform.position, hitInfo.point), w, true)); return; } // If there was a selected line, remove it; else select it if (selectedLine == tapped) { walls.Remove(walls.Find(x => x.lineID == selectedLine.GetInstanceID())); lines.Remove(selectedLine); DestroyObject(tapped); prevTouchPos = null; selectedLine = null; m_selectedMarker = null; } else { selectedLine = tapped; prevTouchPos = null; m_selectedMarker = null; AndroidHelper.ShowAndroidToastMessage("Select the line again to delete it"); } } }
private void debugAndToast(string str) { JLog(str); AndroidHelper.ShowAndroidToastMessage(str); }