Beispiel #1
0
        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!");
                    }
                }
            }
        }
Beispiel #2
0
        /// <inheritdoc />
        public override void Destroy()
        {
            base.Destroy();

            if (Application.isPlaying &&
                meshingClientHandle.IsValid &&
                !MlMeshing2.MLMeshingDestroyClient(ref meshingClientHandle).IsOk)
            {
                Debug.LogError("Failed to destroy meshing client!");
            }
        }
Beispiel #3
0
        /// <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!");
                }
            }
        }
Beispiel #4
0
        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));
        }