/// <summary> /// Issue a request to the Surface Observer to begin baking the mesh. /// </summary> /// <param name="meshId">ID of the mesh to bake.</param> private void RequestMesh(MeshId meshId) { using (RequestMeshPerfMarker.Auto()) { string meshName = ("SpatialMesh - " + meshId); SpatialAwarenessMeshObject newMesh; if (spareMeshObject == null) { newMesh = SpatialAwarenessMeshObject.Create( null, MeshPhysicsLayer, meshName, meshId.GetHashCode()); } else { newMesh = spareMeshObject; spareMeshObject = null; newMesh.GameObject.name = meshName; newMesh.Id = meshId.GetHashCode(); newMesh.GameObject.SetActive(true); } meshSubsystem.GenerateMeshAsync(meshId, newMesh.Filter.mesh, newMesh.Collider, MeshVertexAttributes.Normals, (MeshGenerationResult meshGenerationResult) => MeshGenerationAction(meshGenerationResult)); outstandingMeshObject = newMesh; } }
void Update() { if (s_MeshSubsystem.running && s_MeshSubsystem.TryGetMeshInfos(s_MeshInfos)) { foreach (var meshInfo in s_MeshInfos) { switch (meshInfo.ChangeState) { case MeshChangeState.Added: case MeshChangeState.Updated: if (!m_MeshIdToGo.TryGetValue(meshInfo.MeshId, out var go)) { go = Instantiate(emptyMeshPrefab, target, false); m_MeshIdToGo[meshInfo.MeshId] = go; } var mesh = go.GetComponent <MeshFilter>().mesh; var col = go.GetComponent <MeshCollider>(); s_MeshSubsystem.GenerateMeshAsync(meshInfo.MeshId, mesh, col, MeshVertexAttributes.Normals | MeshVertexAttributes.UVs, result => { Debug.Log("Mesh generated: " + result.Status); }); break; case MeshChangeState.Removed: if (m_MeshIdToGo.TryGetValue(meshInfo.MeshId, out var meshGo)) { Destroy(meshGo); m_MeshIdToGo.Remove(meshInfo.MeshId); } break; default: break; } } } }
void Update() { if (m_MeshSubsystem == null) { return; } if (!m_MeshSubsystem.running) { return; } if (m_initialized) { if (Time.time - m_lastMeshInfoUpdateTime < meshInfoUpdateInterval) { return; } if (m_MeshSubsystem.TryGetMeshInfos(m_MeshInfos)) { foreach (var meshInfo in m_MeshInfos) { switch (meshInfo.ChangeState) { case MeshChangeState.Added: case MeshChangeState.Updated: m_MeshesNeedingGeneration[meshInfo.MeshId] = meshInfo; break; case MeshChangeState.Removed: m_MeshesNeedingGeneration.Remove(meshInfo.MeshId); GameObject meshGameObject; if (meshIdToGameObjectMap.TryGetValue(meshInfo.MeshId, out meshGameObject)) { Destroy(meshGameObject); meshIdToGameObjectMap.Remove(meshInfo.MeshId); } break; default: break; } } } m_lastMeshInfoUpdateTime = Time.time; } while (m_MeshesBeingGenerated.Count < meshQueueSize && m_MeshesNeedingGeneration.Count > 0) { MeshId meshId; if (GetNextMeshToGenerate(out meshId)) { var meshGameObject = GetOrCreateGameObjectForMesh(meshId); var meshFilter = meshGameObject.GetComponent <MeshFilter>(); var mesh = GetOrCreateMesh(meshFilter); var meshAttributes = (MeshVertexAttributes.Normals | MeshVertexAttributes.Colors | MeshVertexAttributes.UVs); m_MeshSubsystem.GenerateMeshAsync(meshId, mesh, null, meshAttributes, OnMeshGenerated); m_MeshesBeingGenerated.Add(meshId, m_MeshesNeedingGeneration[meshId]); m_MeshesNeedingGeneration.Remove(meshId); } } }
private async void MeshInfo_Update(MeshInfo meshInfo) { if (meshInfo.ChangeState == MeshChangeState.Unchanged) { return; } // If we're adding or updating a mesh if (meshInfo.ChangeState != MeshChangeState.Removed) { var spatialMeshObject = await RequestSpatialMeshObject(meshInfo.MeshId.GetHashCode()); spatialMeshObject.GameObject.name = $"SpatialMesh_{meshInfo.MeshId.ToString()}"; var meshAttributes = MeshRecalculateNormals ? MeshVertexAttributes.Normals : MeshVertexAttributes.None; try { meshSubsystem.GenerateMeshAsync(meshInfo.MeshId, spatialMeshObject.Mesh, spatialMeshObject.Collider, meshAttributes, OnMeshGenerated); } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); } void OnMeshGenerated(MeshGenerationResult result) { if (result.Status == MeshGenerationStatus.GenerationAlreadyInProgress) { return; } if (result.Status != MeshGenerationStatus.Success) { Debug.LogWarning($"No output for {result.MeshId.ToString()} | {result.Status}"); RaiseMeshRemoved(spatialMeshObject); return; } if (!SpatialMeshObjects.TryGetValue(result.MeshId.GetHashCode(), out var meshObject)) { Debug.LogWarning($"Failed to find a spatial mesh object for {result.MeshId.ToString()}!"); // Likely it was removed before data could be cooked. return; } // Apply the appropriate material to the mesh. var displayOption = MeshDisplayOption; if (displayOption != SpatialMeshDisplayOptions.None) { meshObject.Collider.enabled = true; meshObject.Renderer.enabled = displayOption == SpatialMeshDisplayOptions.Visible || displayOption == SpatialMeshDisplayOptions.Occlusion; meshObject.Renderer.sharedMaterial = displayOption == SpatialMeshDisplayOptions.Visible ? MeshVisibleMaterial : MeshOcclusionMaterial; } else { meshObject.Renderer.enabled = false; meshObject.Collider.enabled = false; } // Recalculate the mesh normals if requested. if (MeshRecalculateNormals) { if (meshObject.Filter.sharedMesh != null) { meshObject.Filter.sharedMesh.RecalculateNormals(); } else { meshObject.Filter.mesh.RecalculateNormals(); } } meshObject.GameObject.SetActive(true); switch (meshInfo.ChangeState) { case MeshChangeState.Added: RaiseMeshAdded(meshObject); break; case MeshChangeState.Updated: RaiseMeshUpdated(meshObject); break; } } } else if (SpatialMeshObjects.TryGetValue(meshInfo.MeshId.GetHashCode(), out var meshObject)) { RaiseMeshRemoved(meshObject); } }