private void ProcessPendingMeshInfoRequests() { for (var i = 0; i < meshInfoRequests.Count; i++) { var requestHandle = meshInfoRequests[i]; var meshInfoResult = MlMeshing2.MLMeshingGetMeshInfoResult(meshingClientHandle, requestHandle, out var meshInfo); if (meshInfoResult != MlApi.MLResult.Code.Pending) { if (meshInfoResult != MlApi.MLResult.Code.Ok) { meshInfoRequests.RemoveAt(i); Debug.LogError($"Failed to get mesh info result! {meshInfoResult}"); continue; } for (var j = 0; j < meshInfo.data_count; j++) { MeshInfo_Update(meshInfo.Data[j]); } meshInfoRequests.RemoveAt(i); if (!MlMeshing2.MLMeshingFreeResource(meshingClientHandle, in requestHandle).IsOk) { Debug.LogError("Failed to release mesh info result resource!"); } } } }
/// <inheritdoc /> public override void Destroy() { base.Destroy(); if (Application.isPlaying && meshingClientHandle.IsValid && !MlMeshing2.MLMeshingDestroyClient(ref meshingClientHandle).IsOk) { Debug.LogError("Failed to destroy meshing client!"); } }
/// <inheritdoc /> public override void Initialize() { base.Initialize(); if (!Application.isPlaying || Application.isEditor) { return; } if (!meshingClientHandle.IsValid) { if (!MlMeshing2.MLMeshingInitSettings(ref meshingSettings).IsOk) { Debug.LogError("Failed to initialize meshing settings!"); } if (!MlMeshing2.MLMeshingCreateClient(ref meshingClientHandle, meshingSettings).IsOk) { Debug.LogError("failed to create meshing client!"); } } }
private async Task <MeshGenerationResult> GenerateMeshAsync(MlMeshing2.MLMeshingBlockInfo meshInfo, SpatialMeshObject spatialMeshObject) { int levelOfDetail = (int)MeshLevelOfDetail; if (levelOfDetail < 0) { Debug.LogWarning($"{MeshLevelOfDetail} is unsupported! Falling back to low level of detail."); levelOfDetail = 0; } var blockRequest = new MlMeshing2.MLMeshingBlockRequest { id = meshInfo.id, level = (MlMeshing2.MLMeshingLOD)levelOfDetail }; var meshRequest = new MlMeshing2.MLMeshingMeshRequest { request_count = 1, data = blockRequest }; if (!MlMeshing2.MLMeshingRequestMesh(meshingClientHandle, in meshRequest, out var outRequestHandle).IsOk) { Debug.LogError("Failed to request a new mesh!"); return(new MeshGenerationResult(meshInfo.id, MlMeshing2.MLMeshingResult.Failed)); } var meshRequestResult = new MlApi.MLResult(MlApi.MLResult.Code.Pending); var outMeshResult = new MlMeshing2.MLMeshingMesh { result = MlMeshing2.MLMeshingResult.Pending }; await Awaiters.BackgroundThread; while (meshRequestResult.Value == MlApi.MLResult.Code.Pending) { meshRequestResult = MlMeshing2.MLMeshingGetMeshResult(meshingClientHandle, outRequestHandle, out outMeshResult); await Task.Delay(25); // TODO make this delay configurable? } await Awaiters.UnityMainThread; if (!meshRequestResult.IsOk || outMeshResult.result == MlMeshing2.MLMeshingResult.Failed || !MlMeshing2.MLMeshingFreeResource(meshingClientHandle, outRequestHandle).IsOk) { return(new MeshGenerationResult(meshInfo.id, MlMeshing2.MLMeshingResult.Failed)); } if (outMeshResult.data_count != meshRequest.request_count) { Debug.LogError($"Mesh Block count mismatch! Expected {meshRequest.request_count} but got {outMeshResult.data_count} blocks."); return(new MeshGenerationResult(meshInfo.id, MlMeshing2.MLMeshingResult.Failed)); } if (meshInfo.id != outMeshResult.data.id) { Debug.LogError($"Mesh info id mismatch!\n->{meshInfo.id}\n<-{outMeshResult.data.id}"); return(new MeshGenerationResult(meshInfo.id, MlMeshing2.MLMeshingResult.Failed)); } var mesh = spatialMeshObject.Mesh == null ? new Mesh() : spatialMeshObject.Mesh; mesh.name = $"Mesh_{meshInfo.id}"; if (outMeshResult.data.vertex_count == 0 || outMeshResult.data.vertex == null || outMeshResult.data.index_count == 0 || outMeshResult.data.index == null) { return(new MeshGenerationResult(meshInfo.id, outMeshResult.result)); } await Awaiters.BackgroundThread; if (MeshRecalculateNormals) { var normals = new NativeArray <VertexData>((int)outMeshResult.data.vertex_count, Allocator.None); for (int i = 0; i < normals.Length; i++) { normals[i] = new VertexData { Position = outMeshResult.data.vertex[i], Normal = outMeshResult.data.normal[i] }; } mesh.SetVertexBufferParams((int)outMeshResult.data.vertex_count, NormalsLayout); mesh.SetVertexBufferData(normals, 0, 0, (int)outMeshResult.data.vertex_count); normals.Dispose(); } else { var vertices = new NativeArray <Vector3>((int)outMeshResult.data.vertex_count, Allocator.None); for (int i = 0; i < vertices.Length; i++) { vertices[i] = outMeshResult.data.vertex[i]; } mesh.SetVertexBufferParams((int)outMeshResult.data.vertex_count, VertexLayout); mesh.SetVertexBufferData(vertices, 0, 0, (int)outMeshResult.data.vertex_count); vertices.Dispose(); } var indices = new NativeArray <short>(outMeshResult.data.index_count, Allocator.None); for (int i = 0; i < outMeshResult.data.index_count; i++) { indices[i] = (short)outMeshResult.data.index[i]; } mesh.SetIndexBufferParams(outMeshResult.data.index_count, IndexFormat.UInt16); mesh.SetIndexBufferData(indices, 0, 0, outMeshResult.data.index_count); indices.Dispose(); mesh.SetSubMesh(0, new SubMeshDescriptor(0, outMeshResult.data.index_count)); mesh.Optimize(); mesh.RecalculateBounds(); if (MeshRecalculateNormals) { mesh.RecalculateNormals(); } spatialMeshObject.Mesh = mesh; await Awaiters.UnityMainThread; return(new MeshGenerationResult(meshInfo.id, outMeshResult.result)); }