Example #1
0
        /// <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);
                }

                XRSubsystemHelpers.MeshSubsystem.GenerateMeshAsync(meshId, newMesh.Filter.mesh, newMesh.Collider, MeshVertexAttributes.Normals, (MeshGenerationResult meshGenerationResult) => MeshGenerationAction(meshGenerationResult));
                outstandingMeshObject = newMesh;
            }
        }
Example #2
0
        /// <inheritdoc/>
        public override void Suspend()
        {
#if UNITY_WSA
            if (!IsRunning)
            {
                Debug.LogWarning("The Windows Mixed Reality spatial observer is currently stopped.");
                return;
            }

            using (SuspendPerfMarker.Auto())
            {
                // UpdateObserver keys off of this value to stop observing.
                IsRunning = false;

                // Halt any outstanding work.
                if (outstandingMeshObject != null)
                {
                    ReclaimMeshObject(outstandingMeshObject);
                    outstandingMeshObject = null;
                }

                // Clear any pending work.
                meshWorkQueue.Clear();
            }
#endif // UNITY_WSA
        }
        /// <summary>
        /// Reclaims the <see cref="SpatialAwarenessMeshObject"/> to allow for later reuse.
        /// </summary>
        protected void ReclaimMeshObject(SpatialAwarenessMeshObject availableMeshObject)
        {
            using (ReclaimMeshObjectPerfMarker.Auto())
            {
                if (spareMeshObject == null)
                {
                    // Cleanup the mesh object.
                    // Do not destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(availableMeshObject, false);

                    if (availableMeshObject.GameObject != null)
                    {
                        availableMeshObject.GameObject.name = "Unused Spatial Mesh";
                        availableMeshObject.GameObject.SetActive(false);
                    }

                    spareMeshObject = availableMeshObject;
                }
                else
                {
                    // Cleanup the mesh object.
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(availableMeshObject);
                }
            }
        }
        /// <summary>
        /// Sends the observations using the mesh data contained within the configured 3D model.
        /// </summary>
        private void SendMeshObjects()
        {
            if (!sendObservations)
            {
                return;
            }

            if (spatialMeshObject != null)
            {
                MeshFilter[] meshFilters = spatialMeshObject.GetComponentsInChildren <MeshFilter>();
                for (int i = 0; i < meshFilters.Length; i++)
                {
                    SpatialAwarenessMeshObject meshObject = SpatialAwarenessMeshObject.Create(
                        meshFilters[i].sharedMesh,
                        MeshPhysicsLayer,
                        $"Spatial Object Mesh {currentMeshId}",
                        currentMeshId,
                        ObservedObjectParent);

                    meshObject.GameObject.transform.localPosition = meshFilters[i].transform.position;
                    meshObject.GameObject.transform.localRotation = meshFilters[i].transform.rotation;

                    ApplyMeshMaterial(meshObject);

                    meshes.Add(currentMeshId, meshObject);

                    meshEventData.Initialize(this, currentMeshId, meshObject);
                    SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);

                    currentMeshId++;
                }
            }

            sendObservations = false;
        }
Example #5
0
        /// <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());

                    GameObject anchorHolder = new GameObject(meshName + "_anchor");
                    anchorHolder.AddComponent <PlayspaceAdapter>();
                    // Right now, we don't add an anchor to the mesh. This may be resolved with the AnchorSubsystem.
                    anchorHolder.transform.SetParent(newMesh.GameObject.transform, false);
                }
                else
                {
                    newMesh         = spareMeshObject;
                    spareMeshObject = null;

                    newMesh.GameObject.name = meshName;
                    newMesh.Id = meshId.GetHashCode();
                    newMesh.GameObject.SetActive(true);
                }

                XRSubsystemHelpers.MeshSubsystem.GenerateMeshAsync(meshId, newMesh.Filter.mesh, newMesh.Collider, MeshVertexAttributes.Normals, (MeshGenerationResult meshGenerationResult) => MeshGenerationAction(meshGenerationResult));
                outstandingMeshObject = newMesh;
            }
        }
        /// <summary>
        /// Issue a request to the Surface Observer to begin baking the mesh.
        /// </summary>
        /// <param name="surfaceId">ID of the mesh to bake.</param>
        private void RequestMesh(SurfaceId surfaceId)
        {
            string meshName = ("SpatialMesh - " + surfaceId.handle);

            SpatialAwarenessMeshObject newMesh;
            WorldAnchor worldAnchor;

            if (spareMeshObject == null)
            {
                newMesh = SpatialAwarenessMeshObject.Create(null, MeshPhysicsLayer, meshName, surfaceId.handle);

                // The WorldAnchor component places its object where the anchor is in the same space as the camera.
                // But since the camera is repositioned by the MixedRealityPlayspace's transform, the meshes' transforms
                // should also the WorldAnchor position repositioned by the MixedRealityPlayspace's transform.
                // So rather than put the WorldAnchor on the mesh's GameObject, the WorldAnchor is placed out of the way in the scene,
                // and its transform is concatenated with the Playspace transform to compute the transform on the mesh's object.
                // That adapting the WorldAnchor's transform into playspace is done by the internal PlayspaceAdapter component.
                // The GameObject the WorldAnchor is placed on is unimportant, but it is convenient for cleanup to make it a child
                // of the GameObject whose transform will track it.
                GameObject anchorHolder = new GameObject(meshName + "_anchor");
                anchorHolder.AddComponent <PlayspaceAdapter>();          // replace with required component?
                worldAnchor = anchorHolder.AddComponent <WorldAnchor>(); // replace with required component and GetComponent()?
                anchorHolder.transform.SetParent(newMesh.GameObject.transform, false);
            }
            else
            {
                newMesh         = spareMeshObject;
                spareMeshObject = null;

                newMesh.GameObject.name = meshName;
                newMesh.Id = surfaceId.handle;
                newMesh.GameObject.SetActive(true);

                // There should be exactly one child on the newMesh.GameObject, and that is the GameObject added above
                // to hold the WorldAnchor component and adapter.
                Debug.Assert(newMesh.GameObject.transform.childCount == 1, "Expecting a single child holding the WorldAnchor");
                worldAnchor = newMesh.GameObject.transform.GetChild(0).gameObject.GetComponent <WorldAnchor>();
            }

            Debug.Assert(worldAnchor != null);

            SurfaceData surfaceData = new SurfaceData(
                surfaceId,
                newMesh.Filter,
                worldAnchor,
                newMesh.Collider,
                TrianglesPerCubicMeter,
                true);

            if (observer.RequestMeshAsync(surfaceData, SurfaceObserver_OnDataReady))
            {
                outstandingMeshObject = newMesh;
            }
            else
            {
                Debug.LogError($"Mesh request failed for Id == surfaceId.handle");
                outstandingMeshObject = null;
                ReclaimMeshObject(newMesh);
            }
        }
 public MeshData(SpatialAwarenessMeshObject aMesh)
 {
     if (aMesh != null)
     {
         data      = MeshSerializer.SerializeMesh(aMesh.Filter.sharedMesh);
         transform = new TransformS(aMesh.Renderer.transform);
     }
     else
     {
         data      = new byte[0];
         transform = new TransformS(null);
     }
 }
        /// <summary>
        /// Removes an observation.
        /// </summary>
        private void RemoveMeshObject(int meshId)
        {
            if (meshes.TryGetValue(meshId, out SpatialAwarenessMeshObject meshObject))
            {
                // Remove the mesh object from the collection.
                meshes.Remove(meshId);
                if (meshObject != null)
                {
                    SpatialAwarenessMeshObject.Cleanup(meshObject);
                }

                // Send the mesh removed event
                meshEventData.Initialize(this, meshId, null);
                SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshRemoved);
            }
        }
        /// <summary>
        /// Issue a request to the Surface Observer to begin baking the mesh.
        /// </summary>
        /// <param name="surfaceId">ID of the mesh to bake.</param>
        private void RequestMesh(SurfaceId surfaceId)
        {
            string meshName = ("SpatialMesh - " + surfaceId.handle);

            SpatialAwarenessMeshObject newMesh;
            WorldAnchor worldAnchor;

            if (spareMeshObject == null)
            {
                newMesh = SpatialAwarenessMeshObject.Create(null, MeshPhysicsLayer, meshName, surfaceId.handle);

                worldAnchor = newMesh.GameObject.AddComponent <WorldAnchor>();
            }
            else
            {
                newMesh         = spareMeshObject;
                spareMeshObject = null;

                newMesh.GameObject.name = meshName;
                newMesh.Id = surfaceId.handle;
                newMesh.GameObject.SetActive(true);

                worldAnchor = newMesh.GameObject.GetComponent <WorldAnchor>();
            }

            Debug.Assert(worldAnchor != null);

            SurfaceData surfaceData = new SurfaceData(
                surfaceId,
                newMesh.Filter,
                worldAnchor,
                newMesh.Collider,
                TrianglesPerCubicMeter,
                true);

            if (observer.RequestMeshAsync(surfaceData, SurfaceObserver_OnDataReady))
            {
                outstandingMeshObject = newMesh;
            }
            else
            {
                Debug.LogError($"Mesh request failed for Id == surfaceId.handle");
                outstandingMeshObject = null;
                ReclaimMeshObject(newMesh);
            }
        }
Example #10
0
        /// <summary>
        /// Applies the appropriate material, based on the current of the <see cref="SpatialAwarenessMeshDisplayOptions"/> property. 
        /// </summary>
        /// <param name="meshObject">The <see cref="SpatialAwarenessMeshObject"/> for which the material is to be applied.</param>
        private void ApplyMeshMaterial(SpatialAwarenessMeshObject meshObject)
        {
            if (meshObject?.Renderer == null) { return; }

            bool enable = (DisplayOption != SpatialAwarenessMeshDisplayOptions.None);

            if (enable)
            {
                meshObject.Renderer.sharedMaterial = (DisplayOption == SpatialAwarenessMeshDisplayOptions.Visible) ?
                    VisibleMaterial :
                    OcclusionMaterial;

                meshObject.Collider.material = PhysicsMaterial;
            }

            meshObject.Renderer.enabled = enable;
        }
Example #11
0
        /// <inheritdoc />
        public override void ClearObservations()
        {
            using (ClearObservationsPerfMarker.Auto())
            {
                bool wasRunning = false;

                if (IsRunning)
                {
                    wasRunning = true;
                    Debug.Log("Cannot clear observations while the observer is running. Suspending this observer.");
                    Suspend();
                }

                IReadOnlyList <int> observations = new List <int>(Meshes.Keys);
                foreach (int meshId in observations)
                {
                    RemoveMeshObject(meshId);
                }

                // Cleanup the outstanding mesh object.
                if (outstandingMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(outstandingMeshObject);
                    outstandingMeshObject = null;
                }

                // Cleanup the spare mesh object
                if (spareMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(spareMeshObject);
                    spareMeshObject = null;
                }

                if (wasRunning)
                {
                    Resume();
                }
            }
        }
        /// <summary>
        /// Cleans up the objects created during observation.
        /// </summary>
        private void CleanupObservedObjects()
        {
            if (Application.isPlaying)
            {
                // Cleanup the scene objects are managing
                if (observedObjectParent != null)
                {
                    observedObjectParent.transform.DetachChildren();
                }

                foreach (SpatialAwarenessMeshObject meshObject in meshes.Values)
                {
                    if (meshObject != null)
                    {
                        // Destroy the game object, destroy the meshes.
                        SpatialAwarenessMeshObject.Cleanup(meshObject);
                    }
                }
                meshes.Clear();

                // Cleanup the outstanding mesh object.
                if (outstandingMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(outstandingMeshObject);
                    outstandingMeshObject = null;
                }

                // Cleanup the spare mesh object
                if (spareMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(spareMeshObject);
                    spareMeshObject = null;
                }
            }
        }
Example #13
0
        private void MeshGenerationAction(MeshGenerationResult meshGenerationResult)
        {
            if (!IsRunning)
            {
                return;
            }

            using (MeshGenerationActionPerfMarker.Auto())
            {
                if (outstandingMeshObject == null)
                {
                    Debug.LogWarning($"MeshGenerationAction called for mesh id {meshGenerationResult.MeshId} while no request was outstanding.");
                    return;
                }

                switch (meshGenerationResult.Status)
                {
                case MeshGenerationStatus.InvalidMeshId:
                case MeshGenerationStatus.Canceled:
                case MeshGenerationStatus.UnknownError:
                    outstandingMeshObject = null;
                    break;

                case MeshGenerationStatus.Success:
                    // Since there is only one outstanding mesh object, update the id to match
                    // the one received after baking.
                    SpatialAwarenessMeshObject meshObject = outstandingMeshObject;
                    meshObject.Id         = meshGenerationResult.MeshId.GetHashCode();
                    outstandingMeshObject = null;

                    // Apply the appropriate material to the mesh.
                    SpatialAwarenessMeshDisplayOptions displayOption = DisplayOption;
                    if (displayOption != SpatialAwarenessMeshDisplayOptions.None)
                    {
                        meshObject.Renderer.enabled        = true;
                        meshObject.Renderer.sharedMaterial = (displayOption == SpatialAwarenessMeshDisplayOptions.Visible) ?
                                                             VisibleMaterial :
                                                             OcclusionMaterial;
                        meshObject.Collider.material = PhysicsMaterial;
                    }
                    else
                    {
                        meshObject.Renderer.enabled = false;
                    }

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

                    // Add / update the mesh to our collection
                    bool sendUpdatedEvent = false;
                    if (meshes.ContainsKey(meshObject.Id))
                    {
                        // Reclaim the old mesh object for future use.
                        ReclaimMeshObject(meshes[meshObject.Id]);
                        meshes.Remove(meshObject.Id);

                        sendUpdatedEvent = true;
                    }
                    meshes.Add(meshObject.Id, meshObject);

                    meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ? ObservedObjectParent.transform : null;

                    meshEventData.Initialize(this, meshObject.Id, meshObject);
                    if (sendUpdatedEvent)
                    {
                        SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated);
                    }
                    else
                    {
                        SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);
                    }
                    break;
                }
            }
        }
        /// <summary>
        /// Handles the SurfaceObserver's OnDataReady event.
        /// </summary>
        /// <param name="cookedData">Struct containing output data.</param>
        /// <param name="outputWritten">Set to true if output has been written.</param>
        /// <param name="elapsedCookTimeSeconds">Seconds between mesh cook request and propagation of this event.</param>
        private void SurfaceObserver_OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
        {
            if (!IsRunning)
            {
                return;
            }

            using (OnDataReadyPerfMarker.Auto())
            {
                if (outstandingMeshObject == null)
                {
                    return;
                }

                if (!outputWritten)
                {
                    ReclaimMeshObject(outstandingMeshObject);
                    outstandingMeshObject = null;
                    return;
                }

                // Since there is only one outstanding mesh object, update the id to match
                // the one received after baking.
                SpatialAwarenessMeshObject meshObject = outstandingMeshObject;
                meshObject.Id         = cookedData.id.handle;
                outstandingMeshObject = null;

                // Check to see if this is a new or updated mesh.
                bool isMeshUpdate = meshes.ContainsKey(meshObject.Id);

                // We presume that if the display option is not occlusion, that we should
                // default to the visible material.
                // Note: We check explicitly for a display option of none later in this method.
                Material material = (DisplayOption == SpatialAwarenessMeshDisplayOptions.Occlusion) ?
                                    OcclusionMaterial : VisibleMaterial;

                // If this is a mesh update, we want to preserve the mesh's previous material.
                material = isMeshUpdate ? meshes[meshObject.Id].Renderer.sharedMaterial : material;

                // Apply the appropriate material.
                meshObject.Renderer.sharedMaterial = material;

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

                // Check to see if the display option is set to none. If so, we disable
                // the renderer.
                meshObject.Renderer.enabled = (DisplayOption != SpatialAwarenessMeshDisplayOptions.None);

                // Set the physics material
                if (meshObject.Renderer.enabled)
                {
                    meshObject.Collider.material = PhysicsMaterial;
                }

                // Add / update the mesh to our collection
                if (isMeshUpdate)
                {
                    // Reclaim the old mesh object for future use.
                    ReclaimMeshObject(meshes[meshObject.Id]);
                    meshes.Remove(meshObject.Id);
                }
                meshes.Add(meshObject.Id, meshObject);

                // Preserve local transform relative to parent.
                meshObject.GameObject.transform.SetParent(ObservedObjectParent != null ?
                                                          ObservedObjectParent.transform: null, false);

                meshEventData.Initialize(this, meshObject.Id, meshObject);
                if (isMeshUpdate)
                {
                    SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated);
                }
                else
                {
                    SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);
                }
            }
        }
        /// <summary>
        /// Handles the SurfaceObserver's OnDataReady event.
        /// </summary>
        /// <param name="cookedData">Struct containing output data.</param>
        /// <param name="outputWritten">Set to true if output has been written.</param>
        /// <param name="elapsedCookTimeSeconds">Seconds between mesh cook request and propagation of this event.</param>
        private void SurfaceObserver_OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
        {
            if (!IsRunning)
            {
                return;
            }

            if (outstandingMeshObject == null)
            {
                return;
            }

            if (!outputWritten)
            {
                ReclaimMeshObject(outstandingMeshObject);
                outstandingMeshObject = null;
                return;
            }

            // Since there is only one outstanding mesh object, update the id to match
            // the one received after baking.
            SpatialAwarenessMeshObject meshObject = outstandingMeshObject;

            meshObject.Id         = cookedData.id.handle;
            outstandingMeshObject = null;

            // Apply the appropriate material to the mesh.
            SpatialAwarenessMeshDisplayOptions displayOption = DisplayOption;

            if (displayOption != SpatialAwarenessMeshDisplayOptions.None)
            {
                meshObject.Renderer.enabled        = true;
                meshObject.Renderer.sharedMaterial = (displayOption == SpatialAwarenessMeshDisplayOptions.Visible) ?
                                                     VisibleMaterial :
                                                     OcclusionMaterial;
            }
            else
            {
                meshObject.Renderer.enabled = false;
            }

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

            // Add / update the mesh to our collection
            bool sendUpdatedEvent = false;

            if (meshes.ContainsKey(cookedData.id.handle))
            {
                // Reclaim the old mesh object for future use.
                ReclaimMeshObject(meshes[cookedData.id.handle]);
                meshes.Remove(cookedData.id.handle);

                sendUpdatedEvent = true;
            }
            meshes.Add(cookedData.id.handle, meshObject);

            meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ? ObservedObjectParent.transform : null;

            meshEventData.Initialize(this, cookedData.id.handle, meshObject);
            if (sendUpdatedEvent)
            {
                SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated);
            }
            else
            {
                SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);
            }
        }
Example #16
0
        private void MeshGenerationAction(MeshGenerationResult meshGenerationResult)
        {
            if (!IsRunning)
            {
                return;
            }

            using (MeshGenerationActionPerfMarker.Auto())
            {
                if (outstandingMeshObject == null)
                {
                    Debug.LogWarning($"MeshGenerationAction called for mesh id {meshGenerationResult.MeshId} while no request was outstanding.");
                    return;
                }

                switch (meshGenerationResult.Status)
                {
                case MeshGenerationStatus.InvalidMeshId:
                case MeshGenerationStatus.Canceled:
                case MeshGenerationStatus.UnknownError:
                    outstandingMeshObject = null;
                    break;

                case MeshGenerationStatus.Success:
                    // Since there is only one outstanding mesh object, update the id to match
                    // the one received after baking.
                    SpatialAwarenessMeshObject meshObject = outstandingMeshObject;
                    meshObject.Id         = meshGenerationResult.MeshId.GetHashCode();
                    outstandingMeshObject = null;

                    // Check to see if this is a new or updated mesh.
                    bool isMeshUpdate = meshes.ContainsKey(meshObject.Id);

                    // We presume that if the display option is not occlusion, that we should
                    // default to the visible material.
                    // Note: We check explicitly for a display option of none later in this method.
                    Material material = (DisplayOption == SpatialAwarenessMeshDisplayOptions.Occlusion) ?
                                        OcclusionMaterial : VisibleMaterial;

                    // If this is a mesh update, we want to preserve the mesh's previous material.
                    material = isMeshUpdate ? meshes[meshObject.Id].Renderer.sharedMaterial : material;

                    // Apply the appropriate material.
                    meshObject.Renderer.sharedMaterial = material;

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

                    // Check to see if the display option is set to none. If so, we disable
                    // the renderer.
                    meshObject.Renderer.enabled = (DisplayOption != SpatialAwarenessMeshDisplayOptions.None);

                    // Set the physics material
                    if (meshObject.Renderer.enabled)
                    {
                        meshObject.Collider.material = PhysicsMaterial;
                    }

                    // Add / update the mesh to our collection
                    if (isMeshUpdate)
                    {
                        // Reclaim the old mesh object for future use.
                        ReclaimMeshObject(meshes[meshObject.Id]);
                        meshes.Remove(meshObject.Id);
                    }
                    meshes.Add(meshObject.Id, meshObject);

                    meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ?
                                                             ObservedObjectParent.transform : null;

                    meshEventData.Initialize(this, meshObject.Id, meshObject);
                    if (isMeshUpdate)
                    {
                        SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated);
                    }
                    else
                    {
                        SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);
                    }
                    break;
                }
            }
        }
Example #17
0
 /// <inheritdoc />
 public void RaiseMeshUpdated(IMixedRealitySpatialAwarenessObserver observer, int meshId, SpatialAwarenessMeshObject meshObject)
 {
     meshEventData.Initialize(observer, meshId, meshObject);
     HandleEvent(meshEventData, OnMeshUpdated);
 }