AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
SpatialUnderstandingSourceMesh.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using System.Collections.Generic;
6 using UnityEngine;
8 
9 namespace HoloToolkit.Unity
10 {
17  public class SpatialUnderstandingSourceMesh : MonoBehaviour
18  {
19  // Privates
24  private readonly List<SpatialUnderstandingDll.MeshData> inputMeshList = new List<SpatialUnderstandingDll.MeshData>();
25 
26  // Functions
27  private void Start()
28  {
29  TryAttach(SpatialMappingManager.Instance.Source);
30  SpatialMappingManager.Instance.SourceChanged += HandleSpatialMappingSourceChanged;
31  }
32 
33  private void HandleSpatialMappingSourceChanged(object sender, PropertyChangedEventArgsEx<SpatialMappingSource> e)
34  {
35  Debug.Assert(object.ReferenceEquals(sender, SpatialMappingManager.Instance));
36 
37  TryDetach(e.OldValue);
38  TryAttach(e.NewValue);
39  }
40 
41  private void TryDetach(SpatialMappingSource spatialMappingSource)
42  {
43  if (spatialMappingSource != null)
44  {
45  spatialMappingSource.SurfaceAdded -= HandleSurfaceAdded;
46  spatialMappingSource.SurfaceUpdated -= HandleSurfaceUpdated;
47  spatialMappingSource.SurfaceRemoved -= HandleSurfaceRemoved;
48  spatialMappingSource.RemovingAllSurfaces -= HandleRemovingAllSurfaces;
49  }
50 
51  inputMeshList.Clear();
52  }
53 
54  private void TryAttach(SpatialMappingSource spatialMappingSource)
55  {
56  if (spatialMappingSource != null)
57  {
58  spatialMappingSource.SurfaceAdded += HandleSurfaceAdded;
59  spatialMappingSource.SurfaceUpdated += HandleSurfaceUpdated;
60  spatialMappingSource.SurfaceRemoved += HandleSurfaceRemoved;
61  spatialMappingSource.RemovingAllSurfaces += HandleRemovingAllSurfaces;
62 
63  Debug.Assert(inputMeshList.Count == 0);
64 
65  foreach (var surface in spatialMappingSource.SurfaceObjects)
66  {
67  inputMeshList.Add(CreateMeshData(surface, meshUpdateID: 0));
68  }
69  }
70  }
71 
72  private void HandleSurfaceAdded(object sender, DataEventArgs<SpatialMappingSource.SurfaceObject> e)
73  {
74  Debug.Assert(object.ReferenceEquals(sender, SpatialMappingManager.Instance.Source));
75  Debug.Assert(FindMeshIndexInInputMeshList(e.Data.ID) < 0);
76 
77  inputMeshList.Add(CreateMeshData(e.Data, meshUpdateID: 0));
78  }
79 
80  private void HandleSurfaceUpdated(object sender, DataEventArgs<SpatialMappingSource.SurfaceUpdate> e)
81  {
82  Debug.Assert(object.ReferenceEquals(sender, SpatialMappingManager.Instance.Source));
83  Debug.Assert(e.Data.Old.ID == e.Data.New.ID);
84 
85  int iMesh = FindMeshIndexInInputMeshList(e.Data.New.ID);
86  Debug.Assert(iMesh >= 0);
87 
88  inputMeshList[iMesh] = CreateMeshData(e.Data.New, (inputMeshList[iMesh].LastUpdateID + 1));
89  }
90 
91  private void HandleSurfaceRemoved(object sender, DataEventArgs<SpatialMappingSource.SurfaceObject> e)
92  {
93  Debug.Assert(object.ReferenceEquals(sender, SpatialMappingManager.Instance.Source));
94 
95  var iMesh = FindMeshIndexInInputMeshList(e.Data.ID);
96  Debug.Assert(iMesh >= 0);
97 
98  inputMeshList.RemoveAt(iMesh);
99  }
100 
101  private void HandleRemovingAllSurfaces(object sender, EventArgs e)
102  {
103  Debug.Assert(object.ReferenceEquals(sender, SpatialMappingManager.Instance.Source));
104 
105  inputMeshList.Clear();
106  }
107 
108  private int FindMeshIndexInInputMeshList(int meshID)
109  {
110  for (int i = 0; i < inputMeshList.Count; ++i)
111  {
112  if (inputMeshList[i].MeshID == meshID)
113  {
114  return i;
115  }
116  }
117  return -1;
118  }
119 
120  private static SpatialUnderstandingDll.MeshData CreateMeshData(SpatialMappingSource.SurfaceObject surface, int meshUpdateID)
121  {
122  MeshFilter meshFilter = surface.Filter;
124 
125  if ((meshFilter != null) &&
126  (meshFilter.mesh != null) &&
127  (meshFilter.mesh.triangles.Length > 0))
128  {
129  // Fix surface mesh normals so we can get correct plane orientation.
130  meshFilter.mesh.RecalculateNormals();
131 
132  // Convert
133  meshData.CopyFrom(meshFilter, surface.ID, meshUpdateID);
134  }
135  else
136  {
137  // No filter yet, add as an empty mesh (will be updated later in the update loop)
138  meshData.CopyFrom(null, surface.ID, meshUpdateID);
139  }
140 
141  return meshData;
142  }
143 
151  public bool GetInputMeshList(out int meshCount, out IntPtr meshList)
152  {
153  if (inputMeshList.Count == 0)
154  {
155  meshCount = 0;
156  meshList = IntPtr.Zero;
157  return false;
158  }
159 
160  // Convert to IntPtr
162  meshCount = inputMeshList.Count;
163  meshList = dll.PinMeshDataForMarshalling(inputMeshList);
164 
165  return true;
166  }
167  }
168 }
ReadOnlyCollection< SurfaceObject > SurfaceObjects
Collection of surface objects that have been created for this spatial mapping source.
IntPtr PinMeshDataForMarshalling(List< MeshData > meshes)
Copies the supplied mesh data into the reusedMeshesForMarhsalling array. All managed arrays are pinne...
EventHandler< DataEventArgs< SurfaceUpdate > > SurfaceUpdated
Encapsulates the primary DLL functions, including marshalling helper functions. The DLL functions are...
bool GetInputMeshList(out int meshCount, out IntPtr meshList)
Update the internal mesh list and provides an array pointer in the form the DLL will accept...
Representation of the mesh data to be passed to the understanding DLL. Used by SpatialUnderstandingSo...
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
The SpatialMappingManager class allows applications to use a SurfaceObserver or a stored Spatial Mapp...
Provides the input meshes to the spatial understanding DLL. The component relies on the spatial mappi...
The SpatialUnderstanding class controls the state and flow of the scanning process used in the unders...
EventHandler< DataEventArgs< SurfaceObject > > SurfaceRemoved
EventHandler< DataEventArgs< SurfaceObject > > SurfaceAdded
void CopyFrom(MeshFilter meshFilter, int meshID=0, int lastUpdateID=0)