// 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); }
/// <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 ); } }