/// <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
    }
Exemple #2
0
    /// <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
    }
Exemple #3
0
    /// <summary>
    /// Unity Update callback.
    /// </summary>
    public void Update()
    {
        List <Tango3DReconstruction.GridIndex> needsResize = new List <Tango3DReconstruction.GridIndex>();

        int it;
        int startTimeMS = (int)(Time.realtimeSinceStartup * 1000);

        for (it = 0; it < m_gridIndexToUpdate.Count; ++it)
        {
            Tango3DReconstruction.GridIndex gridIndex = m_gridIndexToUpdate[it];

            if ((Time.realtimeSinceStartup * 1000) - startTimeMS > TIME_BUDGET_MS)
            {
                Debug.Log(string.Format(
                              "TangoDynamicMesh.Update() ran over budget with {0}/{1} grid indexes processed.",
                              it, m_gridIndexToUpdate.Count));
                break;
            }

            TangoSingleDynamicMesh dynamicMesh;
            if (!m_meshes.TryGetValue(gridIndex, out dynamicMesh))
            {
                // build a dynamic mesh as a child of this game object.
                GameObject newObj = new GameObject();
                newObj.transform.parent = transform;
                newObj.name             = string.Format("{0},{1},{2}", gridIndex.x, gridIndex.y, gridIndex.z);
                dynamicMesh             = newObj.AddComponent <TangoSingleDynamicMesh>();
                dynamicMesh.m_vertices  = new Vector3[INITIAL_VERTEX_COUNT];
                if (m_tangoApplication.m_3drGenerateTexCoord)
                {
                    dynamicMesh.m_uv = new Vector2[INITIAL_VERTEX_COUNT];
                }

                if (m_tangoApplication.m_3drGenerateColor)
                {
                    dynamicMesh.m_colors = new Color32[INITIAL_VERTEX_COUNT];
                }

                dynamicMesh.m_triangles = new int[INITIAL_INDEX_COUNT];

                // Update debug info too.
                m_debugTotalVertices  = dynamicMesh.m_vertices.Length;
                m_debugTotalTriangles = dynamicMesh.m_triangles.Length;

                // Add the other necessary objects
                MeshFilter meshFilter = newObj.AddComponent <MeshFilter>();
                dynamicMesh.m_mesh = meshFilter.mesh;

                if (m_meshRenderer != null)
                {
                    MeshRenderer meshRenderer = newObj.AddComponent <MeshRenderer>();
#if UNITY_5
                    meshRenderer.shadowCastingMode    = m_meshRenderer.shadowCastingMode;
                    meshRenderer.receiveShadows       = m_meshRenderer.receiveShadows;
                    meshRenderer.sharedMaterials      = m_meshRenderer.sharedMaterials;
                    meshRenderer.useLightProbes       = m_meshRenderer.useLightProbes;
                    meshRenderer.reflectionProbeUsage = m_meshRenderer.reflectionProbeUsage;
                    meshRenderer.probeAnchor          = m_meshRenderer.probeAnchor;
#elif UNITY_4_6
                    meshRenderer.castShadows      = m_meshRenderer.castShadows;
                    meshRenderer.receiveShadows   = m_meshRenderer.receiveShadows;
                    meshRenderer.sharedMaterials  = m_meshRenderer.sharedMaterials;
                    meshRenderer.useLightProbes   = m_meshRenderer.useLightProbes;
                    meshRenderer.lightProbeAnchor = m_meshRenderer.lightProbeAnchor;
#endif
                }

                if (m_meshCollider != null)
                {
                    MeshCollider meshCollider = newObj.AddComponent <MeshCollider>();
                    meshCollider.convex         = m_meshCollider.convex;
                    meshCollider.isTrigger      = m_meshCollider.isTrigger;
                    meshCollider.sharedMaterial = m_meshCollider.sharedMaterial;
                    meshCollider.sharedMesh     = dynamicMesh.m_mesh;
                    dynamicMesh.m_meshCollider  = meshCollider;
                }

                m_meshes.Add(gridIndex, dynamicMesh);
            }

            // Last frame the mesh needed more space.  Give it more room now.
            if (dynamicMesh.m_needsToGrow)
            {
                int newVertexSize   = (int)(dynamicMesh.m_vertices.Length * GROWTH_FACTOR);
                int newTriangleSize = (int)(dynamicMesh.m_triangles.Length * GROWTH_FACTOR);
                newTriangleSize -= newTriangleSize % 3;

                // Remove the old size, add the new size.
                m_debugTotalVertices  += newVertexSize - dynamicMesh.m_vertices.Length;
                m_debugTotalTriangles += newTriangleSize - dynamicMesh.m_triangles.Length;

                dynamicMesh.m_vertices = new Vector3[newVertexSize];
                if (m_tangoApplication.m_3drGenerateTexCoord)
                {
                    dynamicMesh.m_uv = new Vector2[newVertexSize];
                }

                if (m_tangoApplication.m_3drGenerateColor)
                {
                    dynamicMesh.m_colors = new Color32[newVertexSize];
                }

                dynamicMesh.m_triangles   = new int[newTriangleSize];
                dynamicMesh.m_needsToGrow = false;
            }

            int numVertices;
            int numTriangles;
            Tango3DReconstruction.Status status = m_tangoApplication.Tango3DRExtractMeshSegment(
                gridIndex, dynamicMesh.m_vertices, null, dynamicMesh.m_colors, dynamicMesh.m_triangles,
                out numVertices, out numTriangles);
            if (status != Tango3DReconstruction.Status.INSUFFICIENT_SPACE &&
                status != Tango3DReconstruction.Status.SUCCESS)
            {
                Debug.Log("Tango3DR extraction failed, status code = " + status + Environment.StackTrace);
                continue;
            }
            else if (status == Tango3DReconstruction.Status.INSUFFICIENT_SPACE)
            {
                // We already spent the time extracting this mesh, let's not spend any more time this frame
                // to extract the mesh.
                Debug.Log(string.Format(
                              "TangoDynamicMesh.Update() extraction ran out of space with room for {0} vertexes, {1} indexes.",
                              dynamicMesh.m_vertices.Length, dynamicMesh.m_triangles.Length));
                dynamicMesh.m_needsToGrow = true;
                needsResize.Add(gridIndex);
            }

            // Make any leftover triangles degenerate.
            for (int triangleIt = numTriangles * 3; triangleIt < dynamicMesh.m_triangles.Length; ++triangleIt)
            {
                dynamicMesh.m_triangles[triangleIt] = 0;
            }

            if (dynamicMesh.m_uv != null)
            {
                // Add texture coordinates.
                for (int vertexIt = 0; vertexIt < numVertices; ++vertexIt)
                {
                    Vector3 vertex = dynamicMesh.m_vertices[vertexIt];
                    dynamicMesh.m_uv[vertexIt].x = vertex.x * UV_PER_METERS;
                    dynamicMesh.m_uv[vertexIt].y = (vertex.z + vertex.y) * UV_PER_METERS;
                }
            }

            dynamicMesh.m_mesh.Clear();
            dynamicMesh.m_mesh.vertices  = dynamicMesh.m_vertices;
            dynamicMesh.m_mesh.uv        = dynamicMesh.m_uv;
            dynamicMesh.m_mesh.colors32  = dynamicMesh.m_colors;
            dynamicMesh.m_mesh.triangles = dynamicMesh.m_triangles;
            if (m_tangoApplication.m_3drGenerateNormal)
            {
                dynamicMesh.m_mesh.RecalculateNormals();
            }

            if (dynamicMesh.m_meshCollider != null)
            {
                // Force the mesh collider to update too.
                dynamicMesh.m_meshCollider.sharedMesh = null;
                dynamicMesh.m_meshCollider.sharedMesh = dynamicMesh.m_mesh;
            }
        }

        m_debugRemeshingTime  = Time.realtimeSinceStartup - (startTimeMS * 0.001f);
        m_debugRemeshingCount = it;

        // Any leftover grid indices also need to get processed next frame.
        while (it < m_gridIndexToUpdate.Count)
        {
            needsResize.Add(m_gridIndexToUpdate[it]);
            ++it;
        }

        m_gridIndexToUpdate = needsResize;
    }
Exemple #4
0
    /// <summary>
    /// Extract and update (or create, if it doesn't exist) the mesh at the given grid index.
    /// </summary>
    /// <param name="gridIndex">Grid index.</param>
    /// <param name="needsResize">List to which indices needing a future resize will be added.</param>
    private void _UpdateMeshAtGridIndex(Tango3DReconstruction.GridIndex gridIndex, List <Tango3DReconstruction.GridIndex> needsResize)
    {
        TangoSingleDynamicMesh dynamicMesh;

        if (!m_meshes.TryGetValue(gridIndex, out dynamicMesh))
        {
            // build a dynamic mesh as a child of this game object.
            GameObject newObj = new GameObject();
            newObj.transform.parent = transform;
            newObj.name             = string.Format("{0},{1},{2}", gridIndex.x, gridIndex.y, gridIndex.z);
            newObj.layer            = gameObject.layer;
            dynamicMesh             = newObj.AddComponent <TangoSingleDynamicMesh>();
            dynamicMesh.m_vertices  = new Vector3[INITIAL_VERTEX_COUNT];
            dynamicMesh.boxes       = new GameObject[INITIAL_VERTEX_COUNT];

            if (m_tangoApplication.m_3drGenerateTexCoord)
            {
                dynamicMesh.m_uv = new Vector2[INITIAL_VERTEX_COUNT];
            }

            if (m_tangoApplication.m_3drGenerateColor)
            {
                dynamicMesh.m_colors = new Color32[INITIAL_VERTEX_COUNT];
            }

            dynamicMesh.m_triangles = new int[INITIAL_INDEX_COUNT];

            // Update debug info too.
            m_debugTotalVertices  = dynamicMesh.m_vertices.Length;
            m_debugTotalTriangles = dynamicMesh.m_triangles.Length;

            // Add the other necessary objects
            MeshFilter meshFilter = newObj.AddComponent <MeshFilter>();
            dynamicMesh.m_mesh = meshFilter.mesh;

            if (m_meshRenderer != null)
            {
                MeshRenderer meshRenderer = newObj.AddComponent <MeshRenderer>();
                #if UNITY_5
                meshRenderer.shadowCastingMode    = m_meshRenderer.shadowCastingMode;
                meshRenderer.receiveShadows       = m_meshRenderer.receiveShadows;
                meshRenderer.sharedMaterials      = m_meshRenderer.sharedMaterials;
                meshRenderer.useLightProbes       = m_meshRenderer.useLightProbes;
                meshRenderer.reflectionProbeUsage = m_meshRenderer.reflectionProbeUsage;
                meshRenderer.probeAnchor          = m_meshRenderer.probeAnchor;
                #elif UNITY_4_6
                meshRenderer.castShadows      = m_meshRenderer.castShadows;
                meshRenderer.receiveShadows   = m_meshRenderer.receiveShadows;
                meshRenderer.sharedMaterials  = m_meshRenderer.sharedMaterials;
                meshRenderer.useLightProbes   = m_meshRenderer.useLightProbes;
                meshRenderer.lightProbeAnchor = m_meshRenderer.lightProbeAnchor;
                #endif
            }

            if (m_meshCollider != null)
            {
                MeshCollider meshCollider = newObj.AddComponent <MeshCollider>();
                meshCollider.convex         = m_meshCollider.convex;
                meshCollider.isTrigger      = m_meshCollider.isTrigger;
                meshCollider.sharedMaterial = m_meshCollider.sharedMaterial;
                meshCollider.sharedMesh     = dynamicMesh.m_mesh;
                dynamicMesh.m_meshCollider  = meshCollider;
            }

            m_meshes.Add(gridIndex, dynamicMesh);
            _UpdateBounds(gridIndex);
        }

        // Skip updating this grid index if it is considered completed.
        if (m_enableSelectiveMeshing)
        {
            if (dynamicMesh.m_completed)
            {
                return;
            }

            _ObserveGridIndex(gridIndex, dynamicMesh);
        }

        // Last frame the mesh needed more space.  Give it more room now.
        if (dynamicMesh.m_needsToGrow)
        {
            int newVertexSize   = (int)(dynamicMesh.m_vertices.Length * GROWTH_FACTOR);
            int newTriangleSize = (int)(dynamicMesh.m_triangles.Length * GROWTH_FACTOR);
            newTriangleSize -= newTriangleSize % 3;

            // Remove the old size, add the new size.
            m_debugTotalVertices  += newVertexSize - dynamicMesh.m_vertices.Length;
            m_debugTotalTriangles += newTriangleSize - dynamicMesh.m_triangles.Length;

            dynamicMesh.m_vertices = new Vector3[newVertexSize];
            dynamicMesh.boxes      = new GameObject[newVertexSize];

            if (m_tangoApplication.m_3drGenerateTexCoord)
            {
                dynamicMesh.m_uv = new Vector2[newVertexSize];
            }

            if (m_tangoApplication.m_3drGenerateColor)
            {
                dynamicMesh.m_colors = new Color32[newVertexSize];
            }

            dynamicMesh.m_triangles   = new int[newTriangleSize];
            dynamicMesh.m_needsToGrow = false;
        }

        int numVertices;
        int numTriangles;


        Tango3DReconstruction.Status status = m_tangoApplication.Tango3DRExtractMeshSegment(
            gridIndex, dynamicMesh.m_vertices, null, dynamicMesh.m_colors, dynamicMesh.m_triangles,
            out numVertices, out numTriangles);
        if (status != Tango3DReconstruction.Status.INSUFFICIENT_SPACE &&
            status != Tango3DReconstruction.Status.SUCCESS)
        {
            Debug.Log("Tango3DR extraction failed, status code = " + status + Environment.StackTrace);
            return;
        }
        else if (status == Tango3DReconstruction.Status.INSUFFICIENT_SPACE)
        {
            // We already spent the time extracting this mesh, let's not spend any more time this frame
            // to extract the mesh.
            Debug.Log(string.Format(
                          "TangoDynamicMesh.Update() extraction ran out of space with room for {0} vertexes, {1} indexes.",
                          dynamicMesh.m_vertices.Length, dynamicMesh.m_triangles.Length));
            dynamicMesh.m_needsToGrow = true;
            needsResize.Add(gridIndex);
        }

        // Make any leftover triangles degenerate.
        for (int triangleIt = numTriangles * 3; triangleIt < dynamicMesh.m_triangles.Length; ++triangleIt)
        {
            dynamicMesh.m_triangles[triangleIt] = 0;
        }

        if (dynamicMesh.m_uv != null)
        {
            // Add texture coordinates.
            for (int vertexIt = 0; vertexIt < numVertices; ++vertexIt)
            {
                Vector3 vertex = dynamicMesh.m_vertices[vertexIt];
                dynamicMesh.m_uv[vertexIt].x = vertex.x * UV_PER_METERS;
                dynamicMesh.m_uv[vertexIt].y = (vertex.z + vertex.y) * UV_PER_METERS;
            }
        }


        for (int k = 0; k < dynamicMesh.m_vertices.Length; k++)
        {
            if (dynamicMesh.boxes [k] != null)
            {
                Destroy(dynamicMesh.boxes [k]);
            }

            dynamicMesh.boxes [k] = GameObject.CreatePrimitive(PrimitiveType.Cube);
            dynamicMesh.boxes [k].transform.position   = dynamicMesh.m_vertices [k];
            dynamicMesh.boxes [k].transform.localScale = new Vector3(0.02f, 0.02f, 0.02f);

            Color    ObjectColor     = Color.green;
            Material materialColored = new Material(Shader.Find("Diffuse"));
            materialColored.color = ObjectColor;

            dynamicMesh.boxes [k].GetComponent <Renderer> ().material = materialColored;
        }

        dynamicMesh.m_mesh.Clear();
        dynamicMesh.m_mesh.vertices  = dynamicMesh.m_vertices;
        dynamicMesh.m_mesh.uv        = dynamicMesh.m_uv;
        dynamicMesh.m_mesh.colors32  = dynamicMesh.m_colors;
        dynamicMesh.m_mesh.triangles = dynamicMesh.m_triangles;
        if (m_tangoApplication.m_3drGenerateNormal)
        {
            dynamicMesh.m_mesh.RecalculateNormals();
        }

        if (dynamicMesh.m_meshCollider != null)
        {
            // Force the mesh collider to update too.
            dynamicMesh.m_meshCollider.sharedMesh = null;
            dynamicMesh.m_meshCollider.sharedMesh = dynamicMesh.m_mesh;
        }
    }