/// <summary>
 /// Called when a surface is going to be added, removed, or updated. 
 /// We only care about removal so we can remove our internal copy of the surface mesh.
 /// </summary>
 /// <param name="surfaceId">The surface ID that is being added/removed/updated</param>
 /// <param name="changeType">Added | Removed | Updated</param>
 /// <param name="bounds">The world volume the mesh is in.</param>
 /// <param name="updateTime">When the mesh was updated.</param>
 private void MappingObserver_SurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
 {
     // We only need to worry about removing meshes from our list.  Adding and updating is 
     // done when the mesh data is actually ready.
     if (changeType == SurfaceChange.Removed)
     {
         int meshIndex = FindMeshIndexInInputMeshList(surfaceId.handle);
         if(meshIndex >= 0)
         {
             inputMeshList.RemoveAt(meshIndex);
         }
     }
 }
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            if (!IsRunning)
            {
                return;
            }

            switch (changeType)
            {
            case SurfaceChange.Added:
            case SurfaceChange.Updated:
                meshWorkQueue.Enqueue(id);
                break;

            case SurfaceChange.Removed:
                RemoveMeshObject(id.handle);
                break;
            }
        }
        private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            // Find the surface
            List <SpatialMappingSource.SurfaceObject> surfaceObjects = SpatialMappingManager.Instance.GetSurfaceObjects();

            // Find it (in both lists)
            int surfaceObjectIndex = FindSurfaceIndexInList(surfaceId.handle, surfaceObjects);
            int meshDataIndex      = FindMeshIndexInInputMeshList(surfaceId.handle);

            // Deal with the change
            switch (changeType)
            {
            case SurfaceChange.Added:
            {
                if (surfaceObjectIndex >= 0 && surfaceObjectIndex < surfaceObjects.Count)
                {
                    AddOrUpdateMeshInList(surfaceId.handle, surfaceObjectIndex, surfaceObjects);
                }
            }
            break;

            case SurfaceChange.Removed:
            {
                if (meshDataIndex >= 0 && meshDataIndex < inputMeshList.Count)
                {
                    inputMeshList.RemoveAt(meshDataIndex);
                }
            }
            break;

            case SurfaceChange.Updated:
            {
                if ((surfaceObjectIndex >= 0 && surfaceObjectIndex < surfaceObjects.Count) &&
                    (meshDataIndex >= 0 && meshDataIndex < inputMeshList.Count))
                {
                    AddOrUpdateMeshInList(surfaceId.handle, surfaceObjectIndex, surfaceObjects, meshDataIndex);
                }
            }
            break;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            switch (changeType)
            {
            /// Interestingly, surface is pushed to queue only when it's updated but not added.

            case SurfaceChange.Added:
                //Debug.Log(System.String.Format("SurfaceObserver_OnSurfaceChanged:    ADDED id: {0}", id));
                surfaceAddCount += 1;
                break;

            case SurfaceChange.Updated:
                if (!isSurfaceObsolete(id) || SpatialMappingManager.Instance.isSurfaceNearCamera(bounds))
                {
                    surfaceWorkQueue.Enqueue(id);
                    //Debug.Log(System.String.Format("SurfaceObserver_OnSurfaceChanged:    UPDATED id: {0}", id));
                    surfaceUpdateCount += 1;
                }
                break;

            case SurfaceChange.Removed:
                Debug.Log(System.String.Format("SurfaceObserver_OnSurfaceChanged:    REMOVED id: {0}", id));
                surfaceRemoveCount += 1;
                SurfaceObject?removedSurface = RemoveSurfaceIfFound(id.handle, destroyGameObject: false);
                if (removedSurface != null)
                {
                    ReclaimSurface(removedSurface.Value);
                }
                break;

            default:
                Debug.LogErrorFormat("Unexpected {0} value: {1}.", changeType.GetType(), changeType);
                break;
            }
        }
        /// <summary>
        /// This method handles observed changes to surfaces (added, updated, or removed).
        /// These changes have their source in the update loop where the surface observer
        /// is updated.
        /// </summary>
        /// <param name="id">The unique id of the surface</param>
        /// <param name="changeType">Says if the surface has been added, updated, or removed</param>
        /// <param name="bounds">The axis aligned bounding box containing the surface</param>
        /// <param name="updateTime">Time of the update</param>
        private void SurfaceChangedHandler(SurfaceId id, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            ISpatialSurface surface = null;

            switch (changeType)
            {
            case SurfaceChange.Added:
            case SurfaceChange.Updated:
                if (_surfaceEntries.TryGetValue(id.handle, out surface))
                {
                    if (surface.MeshStatus == SurfaceMeshStatuses.UP_TO_DATE)
                    {
                        surface.MeshStatus = SurfaceMeshStatuses.OUTDATED;
                        surface.UpdateTime = updateTime;
                    }
                }
                else
                {
                    surface = _surfaceEntryFactory.Create(updateTime, id.handle, _castShadows, _recieveShadows, _meshMaterial, _addColliders, _physicMaterial);
                    surface.Instance.transform.SetParent(_meshParent != null ? _meshParent : transform, false);
                    _surfaceEntries[id.handle] = surface;
                }
                break;

            case SurfaceChange.Removed:
                if (_surfaceEntries.TryGetValue(id.handle, out surface))
                {
                    _surfaceEntries.Remove(id.handle);
                    Mesh mesh = surface.Mesh.mesh;
                    if (mesh)
                    {
                        Destroy(mesh);
                    }
                    Destroy(surface.Instance);
                }
                break;

            default:
                break;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            if (!WaitingForSceneObserverAccess)
            {
                return;
            }

            using (OnSurfaceChangedPerfMarker.Auto())
            {
                switch (changeType)
                {
                case SurfaceChange.Added:
                case SurfaceChange.Updated:
                    meshWorkQueue.Enqueue(id);
                    break;

                case SurfaceChange.Removed:
                    RemoveMeshObject(id.handle);
                    break;
                }
            }
        }
Ejemplo n.º 7
0
    private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
    {
        switch (changeType)
        {
        case (SurfaceChange.Added):
        case (SurfaceChange.Updated):
            if (!spatialMeshObjects.ContainsKey(surfaceId))
            {
                var meshPiece = new GameObject("spatial-mapping-" + surfaceId);
                meshPiece.transform.parent = transform;
                var pieceRenderer = meshPiece.AddComponent <MeshRenderer>();
                pieceRenderer.material        = surfaceMat;
                spatialMeshObjects[surfaceId] = meshPiece;
            }
            GameObject  target = spatialMeshObjects[surfaceId];
            SurfaceData sd     = new SurfaceData(
                surfaceId,
                target.GetComponent <MeshFilter>() ?? target.AddComponent <MeshFilter>(),
                target.GetComponent <WorldAnchor>() ?? target.AddComponent <WorldAnchor>(),
                target.GetComponent <MeshCollider>() ?? target.AddComponent <MeshCollider>(),
                256,
                true);
            observer.RequestMeshAsync(sd, OnDataReady);
            break;

        case (SurfaceChange.Removed):
            var obj = spatialMeshObjects[surfaceId];
            spatialMeshObjects.Remove(surfaceId);
            if (obj != null)
            {
                GameObject.Destroy(obj);
            }
            break;

        default:
            break;
        }
    }
    // This handler receives surface changed events and is propagated by the
    // Update method on SurfaceObserver.
    void SurfaceChangedHandler(SurfaceId id, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
    {
        SurfaceEntry entry;

        switch (changeType)
        {
        case SurfaceChange.Added:
        case SurfaceChange.Updated:
            if (m_Surfaces.TryGetValue(id.handle, out entry))
            {
                // If this surface has already been baked, mark it as needing bake
                // in addition to the update time so the "next surface to bake"
                // logic will order it correctly.
                if (entry.m_BakedState == BakedState.Baked)
                {
                    entry.m_BakedState = BakedState.UpdatePostBake;
                    entry.m_UpdateTime = updateTime;

                    //send mesh to the ground staton. //old way

                    /*
                     * NetworkMeshSource.getSingleton().sendMesh(entry.m_Surface.GetComponent<MeshFilter>().mesh,
                     *  entry.m_Surface.transform.position,
                     *  entry.m_Surface.transform.rotation);
                     */
                }
            }
            else
            {
                // This is a brand new surface so create an entry for it.
                entry = new SurfaceEntry();
                entry.m_BakedState = BakedState.NeverBaked;
                entry.m_UpdateTime = updateTime;
                entry.m_Id         = id.handle;
                entry.m_Surface    = new GameObject(System.String.Format("Surface-{0}", id.handle));
                entry.m_Surface.AddComponent <MeshFilter>();
                entry.m_Surface.AddComponent <MeshCollider>();
                MeshRenderer mr = entry.m_Surface.AddComponent <MeshRenderer>();
                mr.shadowCastingMode = ShadowCastingMode.Off;
                mr.receiveShadows    = false;
                entry.m_Surface.AddComponent <WorldAnchor>();
                entry.m_Surface.GetComponent <MeshRenderer>().sharedMaterial = m_drawMat;
                m_Surfaces[id.handle] = entry;
                if (!SurfacesList.Contains(entry))
                {
                    SurfacesList.Add(entry);
                }
            }
            break;

        case SurfaceChange.Removed:
            if (m_Surfaces.TryGetValue(id.handle, out entry))
            {
                m_Surfaces.Remove(id.handle);
                Mesh mesh = entry.m_Surface.GetComponent <MeshFilter>().mesh;
                if (mesh)
                {
                    Destroy(mesh);
                }
                Destroy(entry.m_Surface);
            }
            break;
        }
    }
Ejemplo n.º 9
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">The identifier assigned to the surface which has changed.</param>
        /// <param name="surface">The surface</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        protected virtual void OnSurfaceChanged(Guid id, SpatialMappingSurface surface, SurfaceChange changeType, DateTimeOffset updateTime)
        {
            WaveForegroundTask.Run(() =>
            {
                if (surface.Mesh == null)
                {
                    return;
                }

                Debug.WriteLine("OnSurfaceChanged [" + changeType + "] " + id);

                string entityId = this.GetEntityNameFromSurfaceId(id);

                switch (changeType)
                {
                case SurfaceChange.Added:
                case SurfaceChange.Updated:

                    var surfaceEntity = this.Owner.FindChild(entityId);
                    if (surfaceEntity == null)
                    {
                        surfaceEntity     = this.CreateNewSurfaceEntity(entityId, surface);
                        surfaceEntity.Tag = SurfaceEntityTag;

                        if (surfaceEntity != null)
                        {
                            this.Owner.AddChild(surfaceEntity);
                        }
                    }
                    else
                    {
                        this.RefreshModel(surface, surfaceEntity);
                        this.UpdateSurfaceEntity(surface, surfaceEntity);
                    }

                    break;

                case SurfaceChange.Removed:

                    // Remove the child entity
                    this.Owner.RemoveChild(entityId);

                    break;

                default:
                    break;
                }
            });
        }
Ejemplo n.º 10
0
 private static void InvokeSurfaceChangedEvent(SurfaceChangedDelegate onSurfaceChanged, int surfaceId, SurfaceChange changeType, Bounds bounds, long updateTime)
 {
     if (onSurfaceChanged != null)
     {
         SurfaceId id;
         id.handle = surfaceId;
         onSurfaceChanged(id, changeType, bounds, DateTime.FromFileTime(updateTime));
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            GameObject surface;

            switch (changeType)
            {
            // Adding and updating are nearly identical.  The only difference is if a new gameobject to contain
            // the surface needs to be created.
            case SurfaceChange.Added:
            case SurfaceChange.Updated:
                // Check to see if the surface is known to the observer.
                // If so, we want to add it for cleanup after we get new meshes
                // We do this because Unity doesn't properly cleanup baked collision data
                if (surfaces.TryGetValue(id.handle, out surface))
                {
                    pendingCleanup.Add(id.handle, surface);
                    surfaces.Remove(id.handle);
                }

                // Get an available surface object ready to be used
                surface = GetSurfaceObject(id.handle, transform);

                // Add the surface to our dictionary of known surfaces so
                // we can interact with it later.
                surfaces.Add(id.handle, surface);

                // Add the request to create the mesh for this surface to our work queue.
                QueueSurfaceDataRequest(id, surface);
                break;

            case SurfaceChange.Removed:
                // Always process surface removal events.
                // This code can be made more thread safe
                if (surfaces.TryGetValue(id.handle, out surface))
                {
                    surfaces.Remove(id.handle);
                    CleanupSurface(surface);
                    RemoveSurfaceObject(surface, false);
                }
                break;
            }

            //List<MeshFilter> filters = SpatialMappingManager.Instance.GetMeshFilters();

            //CombineInstance[] combine = new CombineInstance[filters.Count];

            //int i = 0;
            //while (i < filters.Count)
            //{
            //    combine[i].mesh = filters[i].mesh;
            //    combine[i].transform = filters[i].transform.localToWorldMatrix;
            //    i++;
            //}

            //Mesh mesh = new Mesh();

            //mesh.CombineMeshes(combine);

            //byte[] serialized = MeshSerializer.WriteMesh(mesh, true);

            //GameObject obj = PhotonView.Find("MyPrefabName");

            //PhotonView photonView = PhotonView.Get(obj);

            //if (photonView)
            //{
            //    photonView.RPC("GetStreamData", RpcTarget.All, serialized);
            //}


            // Event
            if (SurfaceChanged != null)
            {
                SurfaceChanged(id, changeType, bounds, updateTime);
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Handler for calling SurfaceObserver.Update which will then handle the changes
 /// 
 /// The actual changes will be handled via HandleAdd (for SurfaceChange.Added and SurfaceChange.Updated) and HandleDelete (for SurfaceChange.Removed)
 /// </summary>
 /// <param name="surfaceId">The identifier of the surface in question</param>
 /// <param name="changeType">What type of change this is (add, update, or remove)</param>
 /// <param name="bounds">The bounds of the mesh</param>
 /// <param name="updateTime">The time the update occurred</param>
 protected virtual void SurfaceObserver_OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
 {
     switch (changeType)
     {
         case SurfaceChange.Added:
         case SurfaceChange.Updated:
             HandleAdd(surfaceId, updateTime, bakeMeshes);
             break;
         case SurfaceChange.Removed:
             HandleDelete(surfaceId);
             break;
         default:
             break;
     }
 }
        /// <summary>
        /// This handler receives events when surfaces change, and propagates those events
        /// using the SurfaceObserver’s Update method
        /// </summary>
        /// <param name="id">Handle identifying the surface</param>
        /// <param name="changeType">Reason for update</param>
        /// <param name="bounds">New bounds of th esurface</param>
        /// <param name="updateTime">Time stamp of modification.</param>
        private void SurfaceChangedHandler(SurfaceId id, SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            SurfaceEntry entry;

            switch (changeType)
            {
            case SurfaceChange.Added:
            case SurfaceChange.Updated:
                if (surfaces.TryGetValue(id.handle, out entry))
                {
                    // If the system has already baked this Surface, lower its priority.
                    if (entry.currentState == BakedState.Baked)
                    {
                        entry.currentState = BakedState.UpdatePostBake;
                        entry.updateTime   = updateTime;
                    }
                }
                else
                {
                    // This is a brand new Surface so create an entry for it.
                    entry = new SurfaceEntry();
                    entry.currentState        = BakedState.NeverBaked;
                    entry.updateTime          = updateTime;
                    entry.handle              = id.handle;
                    entry.surfaceObject       = new GameObject(System.String.Format("Surface-{0}", id.handle));
                    entry.surfaceObject.layer = spatialMappingLayer;
                    if (HangerObject != null)
                    {
                        entry.surfaceObject.transform.SetParent(HangerObject, false);
                    }
                    entry.surfaceObject.AddComponent <MeshFilter>();
                    if (Collide)
                    {
                        entry.surfaceObject.AddComponent <MeshCollider>();
                    }
                    MeshRenderer mr = entry.surfaceObject.AddComponent <MeshRenderer>();
                    mr.shadowCastingMode   = ShadowCastingMode.Off;
                    mr.receiveShadows      = false;
                    mr.sharedMaterial      = DrawMaterial;
                    mr.enabled             = this.Display;
                    entry.worldAnchorChild = new GameObject(entry.surfaceObject.name + "WorldAnchor");
                    entry.worldAnchorChild.transform.SetParent(entry.surfaceObject.transform, false);
                    entry.worldAnchorChild.AddComponent <WorldAnchor>();
                    // Add an adapter component to keep the surface object where the WorldAnchor means it to be.
                    var adapter = entry.surfaceObject.AddComponent <WorldAnchorAdapter>();
                    adapter.TargetObject      = entry.surfaceObject.transform;
                    adapter.WorldAnchorObject = entry.worldAnchorChild;
                    surfaces[id.handle]       = entry;
                }
                break;

            case SurfaceChange.Removed:
                if (surfaces.TryGetValue(id.handle, out entry))
                {
                    surfaces.Remove(id.handle);
                    Destroy(entry.surfaceObject);
                    // Note entry.worldAnchorChild is child of surfaceObject, so will get destroyed
                    // along with components.
                }
                break;
            }
        }
Ejemplo n.º 14
0
 private static void InvokeSurfaceChangedEvent(SurfaceChangedDelegate onSurfaceChanged, int surfaceId, SurfaceChange changeType, Bounds bounds, long updateTime)
 {
     if (onSurfaceChanged != null)
     {
         SurfaceId id;
         id.handle = surfaceId;
         onSurfaceChanged(id, changeType, bounds, DateTime.FromFileTime(updateTime));
     }
 }
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            GameObject surface;

            switch (changeType)
            {
                // Adding and updating are nearly identical.  The only difference is if a new GameObject to contain
                // the surface needs to be created.
                case SurfaceChange.Added:
                case SurfaceChange.Updated:
                    // Check to see if the surface is known to the observer.
                    if (!surfaces.TryGetValue(id.handle, out surface))
                    {
                        // If we are adding a new surface, construct a GameObject
                        // to represent its state and attach some Mesh-related
                        // components to it.
                        surface = AddSurfaceObject(null, string.Format("Surface-{0}", id.handle), transform);

                        surface.AddComponent<WorldAnchor>();

                        // Add the surface to our dictionary of known surfaces so
                        // we can interact with it later.
                        surfaces.Add(id.handle, surface);
                    }

                    // Add the request to create the mesh for this surface to our work queue.
                    QueueSurfaceDataRequest(id, surface);
                    break;

                case SurfaceChange.Removed:
                    // Always process surface removal events.
                    if (surfaces.TryGetValue(id.handle, out surface))
                    {
                        RemoveSurfaceObject(surface);
                        surfaces.Remove(id.handle);
                    }
                    break;
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Process all spatial surfaces
        /// </summary>
        /// <param name="handler">The handler to receive the surface information</param>
        /// <param name="ignorePrevious">Ignore previous surfaces</param>
        public void UpdateSurfaces(OnSurfaceChangedHandler handler, bool ignorePrevious)
        {
            ////if (!this.pendingChanges && !ignorePrevious)
            ////{
            ////    return;
            ////}

            this.pendingChanges = false;

            lock (this)
            {
                if (this.updateSurfacesTask != null)
                {
                    return;
                }

                this.updateSurfacesTask = System.Threading.Tasks.Task.Run(() =>
                {
                    try
                    {
                        this.surfaceMeshOptions.IncludeVertexNormals = this.ObtainNormals;

                        var surfaceCollection = this.surfaceObserver.GetObservedSurfaces();

                        foreach (var pair in surfaceCollection)
                        {
                            // Gets the MixedReality surface
                            var id          = pair.Key;
                            var surfaceInfo = pair.Value;
                            SpatialMappingSurface surface;
                            SurfaceChange change = SurfaceChange.Updated;

                            if (!this.surfaces.TryGetValue(id, out surface))
                            {
                                surface = new SpatialMappingSurfaceInternal()
                                {
                                    Id = id
                                };

                                this.surfaces.Add(id, surface);
                                change = SurfaceChange.Added;
                            }

                            if (surface.UpdateTime < surfaceInfo.UpdateTime)
                            {
                                this.UpdateSurface(handler, change, surface as SpatialMappingSurfaceInternal, this.TrianglesPerCubicMeter, surfaceInfo, this.surfaceMeshOptions);
                            }
                            else if (ignorePrevious)
                            {
                                if (handler != null)
                                {
                                    handler(id, surface, SurfaceChange.Removed, surface.UpdateTime);
                                }
                            }
                        }

                        var surafacesToRemove = this.surfaces.Where(id => !surfaceCollection.ContainsKey(id.Key)).ToList();
                        foreach (var pair in surafacesToRemove)
                        {
                            var id      = pair.Key;
                            var surface = pair.Value;

                            this.surfaces.Remove(id);
                            surface.Dispose();

                            if (handler != null)
                            {
                                handler(id, surface, SurfaceChange.Removed, surface.UpdateTime);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e);
                    }

                    this.updateSurfacesTask = null;
                });
            }
        }
Ejemplo n.º 17
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);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event. 
        /// </summary>
        /// <param name="id">The identifier assigned to the surface which has changed.</param>
        /// <param name="surface">The surface</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        protected virtual void OnSurfaceChanged(Guid id, SpatialMappingSurface surface, SurfaceChange changeType, DateTimeOffset updateTime)
        {
            WaveServices.Dispatcher.RunOnWaveThread(() =>
            {
                if (surface.Mesh == null)
                {
                    return;
                }

                Debug.WriteLine("OnSurfaceChanged [" + changeType + "] " + id);

                string entityId = this.GetEntityNameFromSurfaceId(id);

                switch (changeType)
                {
                    case SurfaceChange.Added:
                    case SurfaceChange.Updated:

                        var surfaceEntity = this.Owner.FindChild(entityId);
                        if (surfaceEntity == null)
                        {
                            surfaceEntity = this.CreateNewSurfaceEntity(entityId, surface);
                            surfaceEntity.Tag = SurfaceEntityTag;

                            if (surfaceEntity != null)
                            {
                                this.Owner.AddChild(surfaceEntity);
                            }
                        }
                        else
                        {
                            this.RefreshModel(surface, surfaceEntity);
                            this.UpdateSurfaceEntity(surface, surfaceEntity);
                        }

                        break;

                    case SurfaceChange.Removed:

                        // Remove the child entity
                        this.Owner.RemoveChild(entityId);

                        break;

                    default:
                        break;
                }
            });
        }
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">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 void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            GameObject surface;

            switch (changeType)
            {
                // Adding and updating are nearly identical.  The only difference is if a new gameobject to contain
                // the surface needs to be created.
                case SurfaceChange.Added:
                case SurfaceChange.Updated:
                    // Check to see if the surface is known to the observer.
                    // If so, we want to add it for cleanup after we get new meshes
                    // We do this because Unity doesn't properly cleanup baked collision data
                    if (surfaces.TryGetValue(id.handle, out surface))
                    {
                        pendingCleanup.Add(id.handle, surface);
                        surfaces.Remove(id.handle);
                    }

                    // Get an available surface object ready to be used
                    surface = GetSurfaceObject(id.handle, transform);

                    // Add the surface to our dictionary of known surfaces so
                    // we can interact with it later.
                    surfaces.Add(id.handle, surface);

                    // Add the request to create the mesh for this surface to our work queue.
                    QueueSurfaceDataRequest(id, surface);
                    break;

                case SurfaceChange.Removed:
                    // Always process surface removal events.
                    // This code can be made more thread safe
                    if (surfaces.TryGetValue(id.handle, out surface))
                    {
                        surfaces.Remove(id.handle);
                        CleanupSurface(surface);
                        RemoveSurfaceObject(surface, false);
                    }
                    break;
            }

            // Event
            if (SurfaceChanged != null)
            {
                SurfaceChanged(id, changeType, bounds, updateTime);
            }
        }