Beispiel #1
0
        private void UpdateObservedSurfaces()
        {
            var surfaces = spatialSurfaceObserver.GetObservedSurfaces();

            foreach (var spatialMeshObject in SpatialMeshObjects)
            {
                if (!surfaces.TryGetValue(spatialMeshObject.Key, out _))
                {
                    // We cannot call MeshInfo_Update since we no longer have a SpatialSurfaceInfo
                    RaiseMeshRemoved(spatialMeshObject.Value);
                }
            }

            foreach (var surface in surfaces)
            {
                var surfaceBounds       = surface.Value.TryGetBounds(WindowsMixedRealityUtilities.SpatialCoordinateSystem);
                var surfaceChangeStatus = SpatialMeshObjects.TryGetValue(surface.Key, out var spatialMeshObject)
                    ? SpatialObserverStatus.Updated
                    : SpatialObserverStatus.Added;

                if (surfaceBounds.HasValue)
                {
                    MeshInfo_Update(surface.Value, surfaceChangeStatus);
                }
                else
                {
                    if (surfaceChangeStatus == SpatialObserverStatus.Updated)
                    {
                        // Only remove if we've already created a mesh for it.
                        MeshInfo_Update(surface.Value, SpatialObserverStatus.Removed);
                    }
                }
            }
        }
    /// <summary>
    /// Handler for RequestMeshAsync which will be used to set the material on the resulting mesh
    /// </summary>
    /// <param name="bakedData">The resulting data from the RequestMeshAsync call</param>
    /// <param name="outputWritten">Whether or not the output was written</param>
    /// <param name="elapsedBakeTimeSeconds">How long the baking took in seconds</param>
    protected override void SurfaceObserver_OnDataReady(SurfaceData bakedData, bool outputWritten, float elapsedBakeTimeSeconds)
    {
        if (bakedData.outputMesh != null)
        {
            GameObject go;
            if (SpatialMeshObjects.TryGetValue(bakedData.id, out go) && go != null)
            {
                if (go.GetComponent <MeshRenderer>() == null)
                {
                    MeshRenderer meshRenderer = go.AddComponent <MeshRenderer>();
                    meshRenderer.receiveShadows    = false;
                    meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
                }

                ApplyRenderingSetting(bakedData.outputMesh.GetComponent <MeshRenderer>());
            }
        }
    }
Beispiel #3
0
        private async void MeshInfo_Update(SpatialSurfaceInfo meshInfo, SpatialObserverStatus statusType)
        {
            if (statusType == SpatialObserverStatus.Removed)
            {
                if (SpatialMeshObjects.TryGetValue(meshInfo.Id, out var removedMeshObject))
                {
                    RaiseMeshRemoved(removedMeshObject);
                }

                return;
            }

            var spatialMeshObject = await RequestSpatialMeshObject(meshInfo.Id);

            if (meshInfo.UpdateTime.ToUniversalTime() <= spatialMeshObject.LastUpdated.ToUniversalTime())
            {
                // No updates
                return;
            }

            try
            {
                await GenerateMeshAsync(meshInfo, spatialMeshObject);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                RaiseMeshRemoved(spatialMeshObject);
                return;
            }

            if (!SpatialMeshObjects.TryGetValue(meshInfo.Id, out var meshObject))
            {
                Debug.LogWarning($"Failed to find a spatial mesh object for {meshInfo.Id}!");
                // 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;
            }

            if (!meshObject.GameObject.activeInHierarchy)
            {
                meshObject.GameObject.SetActive(true);
            }

            switch (statusType)
            {
            case SpatialObserverStatus.Added:
                RaiseMeshAdded(meshObject);
                break;

            case SpatialObserverStatus.Updated:
                RaiseMeshUpdated(meshObject);
                break;

            default:
                throw new ArgumentOutOfRangeException($"{nameof(SpatialObserverStatus)}.{statusType} was not handled!");
            }
        }
Beispiel #4
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="surfaceId">The identifier assigned to the surface which has changed.</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="bounds">The bounds of the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        private async void SurfaceObserver_OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            // If we're adding or updating a mesh
            if (changeType != SurfaceChange.Removed)
            {
                var spatialMeshObject = await RequestSpatialMeshObject(surfaceId.handle);

                spatialMeshObject.GameObject.name = $"SpatialMesh_{surfaceId.handle.ToString()}";
                var worldAnchor = spatialMeshObject.GameObject.EnsureComponent <WorldAnchor>();
                var surfaceData = new SurfaceData(surfaceId, spatialMeshObject.Filter, worldAnchor, spatialMeshObject.Collider, MeshTrianglesPerCubicMeter, true);

                if (!observer.RequestMeshAsync(surfaceData, OnDataReady))
                {
                    Debug.LogError($"Mesh request failed for spatial observer with Id {surfaceId.handle.ToString()}");
                    RaiseMeshRemoved(spatialMeshObject);
                }

                void OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
                {
                    if (!outputWritten)
                    {
                        Debug.LogWarning($"No output for {cookedData.id.handle}");
                        return;
                    }

                    if (!SpatialMeshObjects.TryGetValue(cookedData.id.handle, out SpatialMeshObject meshObject))
                    {
                        // Likely it was removed before data could be cooked.
                        return;
                    }

                    // Apply the appropriate material to the mesh.
                    SpatialMeshDisplayOptions displayOption = MeshDisplayOption;

                    if (displayOption != SpatialMeshDisplayOptions.None)
                    {
                        meshObject.Renderer.enabled        = true;
                        meshObject.Renderer.sharedMaterial = (displayOption == SpatialMeshDisplayOptions.Visible)
                            ? MeshVisibleMaterial
                            : MeshOcclusionMaterial;
                    }
                    else
                    {
                        meshObject.Renderer.enabled = false;
                    }

                    // Recalculate the mesh normals if requested.
                    if (MeshRecalculateNormals)
                    {
                        meshObject.Filter.sharedMesh.RecalculateNormals();
                    }

                    meshObject.GameObject.SetActive(true);

                    switch (changeType)
                    {
                    case SurfaceChange.Added:
                        RaiseMeshAdded(meshObject);
                        break;

                    case SurfaceChange.Updated:
                        RaiseMeshUpdated(meshObject);
                        break;
                    }
                }
            }
            else if (SpatialMeshObjects.TryGetValue(surfaceId.handle, out SpatialMeshObject meshObject))
            {
                RaiseMeshRemoved(meshObject);
            }
        }
        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);
            }
        }
Beispiel #6
0
        private async void MeshInfo_Update(MlMeshing2.MLMeshingBlockInfo meshInfo)
        {
            if (meshInfo.state == MlMeshing2.MLMeshingMeshState.Unchanged)
            {
                return;
            }

            // If we're adding or updating a mesh
            if (meshInfo.state != MlMeshing2.MLMeshingMeshState.Deleted)
            {
                var spatialMeshObject = await RequestSpatialMeshObject(meshInfo.id.ToGuid());

                MeshGenerationResult meshResult;

                try
                {
                    meshResult = await GenerateMeshAsync(meshInfo, spatialMeshObject);
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                    RaiseMeshRemoved(spatialMeshObject);
                    return;
                }

                if (meshResult.Status == MlMeshing2.MLMeshingResult.Pending)
                {
                    return;
                }

                if (meshResult.Status != MlMeshing2.MLMeshingResult.Success)
                {
                    Debug.LogWarning($"No output for {meshResult.Id} | {meshResult.Status}");
                    RaiseMeshRemoved(spatialMeshObject);
                    return;
                }

                if (!SpatialMeshObjects.TryGetValue(meshResult.Id.ToGuid(), out var meshObject))
                {
                    Debug.LogWarning($"Failed to find a spatial mesh object for {meshResult.Id}!");
                    // 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;
                }

                if (!meshObject.GameObject.activeInHierarchy)
                {
                    meshObject.GameObject.SetActive(true);
                }

                switch (meshInfo.state)
                {
                case MlMeshing2.MLMeshingMeshState.New:
                    RaiseMeshAdded(meshObject);
                    break;

                case MlMeshing2.MLMeshingMeshState.Updated:
                    RaiseMeshUpdated(meshObject);
                    break;
                }
            }
            else if (SpatialMeshObjects.TryGetValue(meshInfo.id.ToGuid(), out var meshObject))
            {
                RaiseMeshRemoved(meshObject);
            }
        }