// Functions
    protected override void Awake()
    {
        base.Awake();

        // Cache references to required component
        UnderstandingDLL        = new SpatialUnderstandingDll();
        UnderstandingSourceMesh = GetComponent <SpatialUnderstandingSourceMesh>();
        UnderstandingCustomMesh = GetComponent <SpatialUnderstandingCustomMesh>();
    }
    /// <summary>
    /// Update the internal mesh list and provides an array pointer in
    /// the form the dll will accept.
    /// </summary>
    /// <param name="meshCount">Number of meshes contains in the return mesh list</param>
    /// <param name="meshList">Marshalled mesh list pointer. Valid only with the caller's function context</param>
    /// <returns></returns>
    public bool GetInputMeshList(out int meshCount, out IntPtr meshList)
    {
        if (inputMeshList.Count == 0)
        {
            meshCount = 0;
            meshList  = IntPtr.Zero;
            return(false);
        }

        // Convert to IntPtr
        SpatialUnderstandingDll dll = SpatialUnderstanding.Instance.UnderstandingDLL;

        meshCount = inputMeshList.Count;
        meshList  = dll.PinMeshDataForMarshalling(inputMeshList);

        return(true);
    }
Пример #3
0
 // Use this for initialization
 void Start()
 {
     _understandingDll = SpatialUnderstanding.Instance.UnderstandingDLL;
     SpatialUnderstanding.Instance.ScanStateChanged += Init_Spawner;
 }
    /// <summary>
    /// Imports the custom mesh from the dll. This a a coroutine which will take multiple frames to complete.
    /// </summary>
    /// <returns></returns>
    public IEnumerator Import_UnderstandingMesh()
    {
        var stopwatch       = System.Diagnostics.Stopwatch.StartNew();
        int startFrameCount = Time.frameCount;

        if (!spatialUnderstanding.AllowSpatialUnderstanding || IsImportActive)
        {
            yield break;
        }

        IsImportActive = true;

        SpatialUnderstandingDll dll = spatialUnderstanding.UnderstandingDLL;

        Vector3[] meshVertices = null;
        Vector3[] meshNormals  = null;
        Int32[]   meshIndices  = null;

        // Pull the mesh - first get the size, then allocate and pull the data
        int vertCount;
        int idxCount;

        if ((SpatialUnderstandingDll.Imports.GeneratePlayspace_ExtractMesh_Setup(out vertCount, out idxCount) > 0) &&
            (vertCount > 0) &&
            (idxCount > 0))
        {
            meshVertices = new Vector3[vertCount];
            IntPtr vertPos = dll.PinObject(meshVertices);
            meshNormals = new Vector3[vertCount];
            IntPtr vertNorm = dll.PinObject(meshNormals);
            meshIndices = new Int32[idxCount];
            IntPtr indices = dll.PinObject(meshIndices);

            SpatialUnderstandingDll.Imports.GeneratePlayspace_ExtractMesh_Extract(vertCount, vertPos, vertNorm, idxCount, indices);
        }

        // Wait a frame
        stopwatch.Stop();
        yield return(null);

        stopwatch.Start();

        // Create output meshes
        if ((meshVertices != null) &&
            (meshVertices.Length > 0) &&
            (meshIndices != null) &&
            (meshIndices.Length > 0))
        {
            // first get all our mesh data containers ready for meshes.
            foreach (MeshData meshdata in meshSectors.Values)
            {
                meshdata.Reset();
            }

            float startTime = Time.realtimeSinceStartup;
            // first we need to split the playspace up into segments so we don't always
            // draw everything.  We can break things up in to cubic meters.
            for (int index = 0; index < meshIndices.Length; index += 3)
            {
                Vector3 firstVertex  = meshVertices[meshIndices[index]];
                Vector3 secondVertex = meshVertices[meshIndices[index + 1]];
                Vector3 thirdVertex  = meshVertices[meshIndices[index + 2]];

                // The triangle may belong to multiple sectors.  We will copy the whole triangle
                // to all of the sectors it belongs to.  This will fill in seams on sector edges
                // although it could cause some amount of visible z-fighting if rendering a wireframe.
                Vector3 firstSector = VectorToSector(firstVertex);

                AddTriangleToSector(firstSector, firstVertex, secondVertex, thirdVertex);

                // If the second sector doesn't match the first, copy the triangle to the second sector.
                Vector3 secondSector = VectorToSector(secondVertex);
                if (secondSector != firstSector)
                {
                    AddTriangleToSector(secondSector, firstVertex, secondVertex, thirdVertex);
                }

                // If the third sector matches neither the first nor second sector, copy the triangle to the
                // third sector.
                Vector3 thirdSector = VectorToSector(thirdVertex);
                if (thirdSector != firstSector && thirdSector != secondSector)
                {
                    AddTriangleToSector(thirdSector, firstVertex, secondVertex, thirdVertex);
                }

                // Limit our run time so that we don't cause too many frame drops.
                // Only checking every few iterations or so to prevent losing too much time to checking the clock.
                if ((index % 30 == 0) && ((Time.realtimeSinceStartup - startTime) > MaxFrameTimeInSeconds))
                {
                    //  Debug.LogFormat("{0} of {1} processed", index, meshIndices.Length);
                    stopwatch.Stop();
                    yield return(null);

                    stopwatch.Start();
                    startTime = Time.realtimeSinceStartup;
                }
            }

            startTime = Time.realtimeSinceStartup;

            // Now we have all of our triangles assigned to the correct mesh, we can make all of the meshes.
            // Each sector will have its own mesh.
            foreach (MeshData meshData in meshSectors.Values)
            {
                // Construct the mesh.
                meshData.Commit();

                // Make sure we don't build too many meshes in a single frame.
                if ((Time.realtimeSinceStartup - startTime) > MaxFrameTimeInSeconds)
                {
                    stopwatch.Stop();
                    yield return(null);

                    stopwatch.Start();
                    startTime = Time.realtimeSinceStartup;
                }
            }
        }

        // Wait a frame
        stopwatch.Stop();
        yield return(null);

        stopwatch.Start();

        // All done - can free up marshal pinned memory
        dll.UnpinAllObjects();

        // Done
        IsImportActive = false;

        // Mark the timestamp
        timeLastImportedMesh = Time.time;

        stopwatch.Stop();
        int deltaFrameCount = (Time.frameCount - startFrameCount + 1);

        if (stopwatch.Elapsed.TotalSeconds > 0.75)
        {
            Debug.LogWarningFormat("Import_UnderstandingMesh took {0:N0} frames ({1:N3} ms)",
                                   deltaFrameCount,
                                   stopwatch.Elapsed.TotalMilliseconds
                                   );
        }
    }