/// <summary> /// Save the tango dynamic mesh. /// /// Process the mesh in 3 steps. /// 1. Extract the whole mesh from tango 3D Reconstruction. /// 2. Convert to a serializable format. /// 3. Serialize with XML on to the SD card. /// </summary> /// <returns>The coroutine IEnumerator.</returns> private IEnumerator _DoSaveTangoDynamicMesh() { m_savingText.gameObject.SetActive(true); m_savingText.text = "Extracting Whole Mesh..."; // Each list is filled out with values from extracting the whole mesh. List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); Tango3DReconstruction.Status status = m_tangoApplication.Tango3DRExtractWholeMesh(vertices, null, null, triangles); if (status != Tango3DReconstruction.Status.SUCCESS) { Debug.Log("Tango3DRExtractWholeMesh failed, status code = " + status); yield break; } Debug.Log("Tango3DRExtractWholeMesh finished"); Mesh extractedMesh = new Mesh(); extractedMesh.vertices = vertices.ToArray(); extractedMesh.triangles = triangles.ToArray(); // Save the generated unity mesh. m_savingText.text = "Saving Area Description Mesh..."; AreaDescriptionMesh mesh = _UnityMeshToAreaDescriptionMesh(m_savedUUID, extractedMesh); _SerializeAreaDescriptionMesh(mesh); // Restart scene after completion. #pragma warning disable 618 Application.LoadLevel(Application.loadedLevel); #pragma warning restore 618 }
/// <summary> /// Serialize an Area Description mesh to file. /// </summary> /// <param name="saveMesh">The Area Description mesh to serialize.</param> private void _SerializeAreaDescriptionMesh(AreaDescriptionMesh saveMesh) { XmlSerializer serializer = new XmlSerializer(typeof(AreaDescriptionMesh)); FileStream file = File.Create(m_meshSavePath + "/" + saveMesh.m_uuid); serializer.Serialize(file, saveMesh); file.Close(); }
/// <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; // Disable unused components in tango application. m_tangoApplication.m_areaDescriptionLearningMode = false; m_tangoApplication.m_enableDepth = false; m_relocalizeImage.gameObject.SetActive(true); // Set UI panel to the mesh interaction panel. m_areaDescriptionLoaderPanel.SetActive(false); m_meshBuildPanel.SetActive(false); m_meshInteractionPanel.SetActive(true); // 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>(); // Load Area Description file. m_curAreaDescription = AreaDescription.ForUUID(m_savedUUID); m_tangoApplication.Startup(m_curAreaDescription); }
/// <summary> /// Convert an Area Description mesh to a unity mesh. /// </summary> /// <returns>The unity mesh.</returns> /// <param name="saveMesh">The Area Description mesh.</param> private Mesh _AreaDescriptionMeshToUnityMesh(AreaDescriptionMesh saveMesh) { Mesh mesh = new Mesh(); mesh.vertices = saveMesh.m_vertices; mesh.triangles = saveMesh.m_triangles; mesh.RecalculateNormals(); return(mesh); }
/// <summary> /// Convert a unity mesh to an Area Description mesh. /// </summary> /// <returns>The Area Description mesh.</returns> /// <param name="uuid">The Area Description UUID.</param> /// <param name="mesh">The Unity mesh.</param> private AreaDescriptionMesh _UnityMeshToAreaDescriptionMesh(string uuid, Mesh mesh) { AreaDescriptionMesh saveMesh = new AreaDescriptionMesh(); saveMesh.m_uuid = m_savedUUID; saveMesh.m_vertices = mesh.vertices; saveMesh.m_triangles = mesh.triangles; return(saveMesh); }
/// <summary> /// Serialize an area description mesh to file. /// </summary> /// <param name="adfMesh">The area description mesh to serialize.</param> private void _SerializeAreaDescriptionMesh(AreaDescriptionMesh adfMesh) { BinaryFormatter bf = new BinaryFormatter(); Directory.CreateDirectory(m_adfMeshSavePath); FileStream file = File.Create(m_adfMeshSavePath + "/" + adfMesh.m_uuid); bf.Serialize(file, adfMesh); file.Close(); }
/// <summary> /// Deserialize an Area Description mesh from file. /// </summary> /// <returns>The loaded Area Description mesh.</returns> /// <param name="uuid">The UUID of the associated Area Description.</param> private AreaDescriptionMesh _DeserializeAreaDescriptionMesh(string uuid) { if (File.Exists(m_meshSavePath + "/" + uuid)) { XmlSerializer serializer = new XmlSerializer(typeof(AreaDescriptionMesh)); FileStream file = File.Open(m_meshSavePath + "/" + uuid, FileMode.Open); AreaDescriptionMesh saveMesh = serializer.Deserialize(file) as AreaDescriptionMesh; file.Close(); return(saveMesh); } return(null); }
/// <summary> /// Deserialize an area description mesh from file. /// </summary> /// <returns>The loaded area description mesh.</returns> /// <param name="uuid">The UUID of the associated area description.</param> private AreaDescriptionMesh _DeserializeAreaDescriptionMesh(string uuid) { if (File.Exists(m_adfMeshSavePath + "/" + uuid)) { BinaryFormatter bf = new BinaryFormatter(); FileStream file = File.Open(m_adfMeshSavePath + "/" + uuid, FileMode.Open); AreaDescriptionMesh adfMesh = (AreaDescriptionMesh)bf.Deserialize(file); file.Close(); return(adfMesh); } return(null); }
/// <summary> /// Convert a unity mesh to an area description mesh. /// </summary> /// <returns>The area description mesh.</returns> /// <param name="uuid">The area description UUID.</param> /// <param name="mesh">The Unity mesh.</param> private AreaDescriptionMesh _UnityMeshToAreaDescriptionMesh(string uuid, Mesh mesh) { AreaDescriptionMesh adfMesh = new AreaDescriptionMesh(); // Convert Vector3 vertices to serializable format. Vector3_Serializable[] adfVertices = new Vector3_Serializable[mesh.vertices.Length]; for (int i = 0; i < mesh.vertices.Length; i++) { Vector3 v = mesh.vertices[i]; adfVertices[i] = new Vector3_Serializable(v); } adfMesh.m_uuid = m_savedUUID; adfMesh.m_vertices = adfVertices; adfMesh.m_triangles = mesh.triangles; return(adfMesh); }
/// <summary> /// Convert an area description mesh to a unity mesh. /// </summary> /// <returns>The unity mesh.</returns> /// <param name="adfMesh">The area description mesh.</param> private Mesh _AreaDescriptionMeshToUnityMesh(AreaDescriptionMesh adfMesh) { Vector3[] vertices = new Vector3[adfMesh.m_vertices.Length]; int[] triangles = new int[adfMesh.m_triangles.Length]; // Convert serialized vertices back to Unity Vector3. for (int i = 0; i < adfMesh.m_vertices.Length; i++) { vertices[i] = adfMesh.m_vertices[i].ToVector3(); } triangles = adfMesh.m_triangles; Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); return(mesh); }
/// <summary> /// Save the tango dynamic mesh. /// /// Process the mesh in 3 steps. /// 1. Extract the whole mesh from tango 3D Reconstruction. /// 2. Convert to a serializable format. /// 3. Serialize with XML on to the SD card. /// </summary> /// <returns>The coroutine IEnumerator.</returns> private IEnumerator _DoSaveTangoDynamicMesh() { m_savingText.gameObject.SetActive(true); m_savingText.text = "Extracting Whole Mesh..."; Tango3DReconstruction.Status status = Tango3DReconstruction.Status.INVALID; bool needsToGrow = false; float growthFactor = 1.5f; // Each list is filled out with values from extracting the whole mesh. Vector3[] vertices = new Vector3[100]; int[] triangles = new int[99]; while (status != Tango3DReconstruction.Status.SUCCESS) { yield return(null); // Last frame the mesh needed more space. Give it more room now. if (needsToGrow) { int newVertexSize = (int)(vertices.Length * growthFactor); int newTriangleSize = (int)(triangles.Length * growthFactor); newTriangleSize -= newTriangleSize % 3; vertices = new Vector3[newVertexSize]; triangles = new int[newTriangleSize]; needsToGrow = false; } int numVertices; int numTriangles; status = m_tangoApplication.Tango3DRExtractWholeMesh(vertices, null, null, triangles, out numVertices, out numTriangles); if (status != Tango3DReconstruction.Status.INSUFFICIENT_SPACE && status != Tango3DReconstruction.Status.SUCCESS) { Debug.Log("Tango3DRExtractWholeMesh failed, status code = " + status); break; } else if (status == Tango3DReconstruction.Status.INSUFFICIENT_SPACE) { // After exceeding allocated space for vertices and triangles, continue extraction next frame. Debug.Log(string.Format("Tango3DRExtractWholeMesh ran out of space with room for {0} vertexes, {1} indexes.", vertices.Length, triangles.Length)); needsToGrow = true; } // Make any leftover triangles degenerate. for (int triangleIt = numTriangles * 3; triangleIt < triangles.Length; ++triangleIt) { triangles[triangleIt] = 0; } } Debug.Log("Tango3DRExtractWholeMesh finished"); Mesh extractedMesh = new Mesh(); extractedMesh.vertices = vertices; extractedMesh.triangles = triangles; // Save the generated unity mesh. m_savingText.text = "Saving Area Description Mesh..."; AreaDescriptionMesh mesh = _UnityMeshToAreaDescriptionMesh(m_savedUUID, extractedMesh); _SerializeAreaDescriptionMesh(mesh); // Restart scene after completion. #pragma warning disable 618 Application.LoadLevel(Application.loadedLevel); #pragma warning restore 618 }
/// <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> /// Convert an Area Description mesh to a unity mesh. /// </summary> /// <returns>The unity mesh.</returns> /// <param name="saveMesh">The Area Description mesh.</param> private Mesh _AreaDescriptionMeshToUnityMesh(AreaDescriptionMesh saveMesh) { Mesh mesh = new Mesh(); mesh.vertices = saveMesh.m_vertices; mesh.triangles = saveMesh.m_triangles; mesh.RecalculateNormals(); return mesh; }
/// <summary> /// Convert a unity mesh to an Area Description mesh. /// </summary> /// <returns>The Area Description mesh.</returns> /// <param name="uuid">The Area Description UUID.</param> /// <param name="mesh">The Unity mesh.</param> private AreaDescriptionMesh _UnityMeshToAreaDescriptionMesh(string uuid, Mesh mesh) { AreaDescriptionMesh saveMesh = new AreaDescriptionMesh(); saveMesh.m_uuid = m_savedUUID; saveMesh.m_vertices = mesh.vertices; saveMesh.m_triangles = mesh.triangles; return saveMesh; }