AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
SpatialMappingManager.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 System.Collections.ObjectModel;
7 using UnityEngine;
8 
9 namespace HoloToolkit.Unity.SpatialMapping
10 {
17  [RequireComponent(typeof(SpatialMappingObserver))]
18  public partial class SpatialMappingManager : Singleton<SpatialMappingManager>
19  {
20  [Tooltip("The physics layer for spatial mapping objects to be set to.")]
21  public int PhysicsLayer = 31;
22 
23  [Tooltip("The material to use for rendering spatial mapping data.")]
24  [SerializeField]
25  private Material surfaceMaterial;
26 
27  [Tooltip("Determines if the surface observer should be automatically started.")]
28  [SerializeField]
29  private bool autoStartObserver = true;
30 
31  [Tooltip("Determines if spatial mapping data will be rendered.")]
32  [SerializeField]
33  private bool drawVisualMeshes = false;
34 
35  [Tooltip("Determines if spatial mapping data will cast shadows.")]
36  [SerializeField]
37  private bool castShadows = false;
38 
42  private SpatialMappingObserver surfaceObserver;
43 
47  public float StartTime { get; private set; }
48 
52  public SpatialMappingObserver SurfaceObserver { get { return surfaceObserver; } }
53 
57  public SpatialMappingSource Source
58  {
59  get { return source; }
60 
61  private set
62  {
63  if (source != value)
64  {
65  UpdateRendering(false);
66 
67  var oldSource = source;
68  source = value;
69 
70  UpdateRendering(DrawVisualMeshes);
71 
72  var handlers = SourceChanged;
73  if (handlers != null)
74  {
75  handlers(this, PropertyChangedEventArgsEx.Create(() => Source, oldSource, source));
76  }
77  }
78  }
79  }
80  private SpatialMappingSource source;
81 
85  public event EventHandler<PropertyChangedEventArgsEx<SpatialMappingSource>> SourceChanged;
86 
87  // Called when the GameObject is first created.
88  protected override void Awake()
89  {
90  base.Awake();
91 
92  surfaceObserver = gameObject.GetComponent<SpatialMappingObserver>();
93  Source = surfaceObserver;
94  }
95 
96  // Use for initialization.
97  private void Start()
98  {
99  if (autoStartObserver)
100  {
101  StartObserver();
102  }
103  }
104 
108  public int LayerMask
109  {
110  get { return (1 << PhysicsLayer); }
111  }
112 
116  public Material SurfaceMaterial
117  {
118  get
119  {
120  return surfaceMaterial;
121  }
122  set
123  {
124  if (value != surfaceMaterial)
125  {
126  surfaceMaterial = value;
127  SetSurfaceMaterial(surfaceMaterial);
128  }
129  }
130  }
131 
135  public bool DrawVisualMeshes
136  {
137  get
138  {
139  return drawVisualMeshes;
140  }
141  set
142  {
143  if (value != drawVisualMeshes)
144  {
145  drawVisualMeshes = value;
146  UpdateRendering(drawVisualMeshes);
147  }
148  }
149  }
150 
154  public bool CastShadows
155  {
156  get
157  {
158  return castShadows;
159  }
160  set
161  {
162  if (value != castShadows)
163  {
164  castShadows = value;
165  SetShadowCasting(castShadows);
166  }
167  }
168  }
169 
175  {
176  Source = (mappingSource ?? surfaceObserver);
177  }
178 
183  public void SetSurfaceMaterial(Material setSurfaceMaterial)
184  {
185  SurfaceMaterial = setSurfaceMaterial;
186  if (DrawVisualMeshes)
187  {
188  foreach (MeshRenderer sourceRenderer in Source.GetMeshRenderers())
189  {
190  if (sourceRenderer != null)
191  {
192  sourceRenderer.sharedMaterial = setSurfaceMaterial;
193  }
194  }
195  }
196  }
197 
202  public bool IsObserverRunning()
203  {
204  return surfaceObserver.ObserverState == ObserverStates.Running;
205  }
206 
210  public void StartObserver()
211  {
212 #if UNITY_WSA
213  // Allow observing if a device is present (Holographic Remoting)
214 #if UNITY_2017_2_OR_NEWER
215  if (!UnityEngine.XR.XRDevice.isPresent) { return; }
216 #else
217  if (!UnityEngine.VR.VRDevice.isPresent) { return; }
218 #endif
219 #endif
220  if (!IsObserverRunning())
221  {
222  surfaceObserver.StartObserving();
223  StartTime = Time.unscaledTime;
224  }
225  }
226 
230  public void StopObserver()
231  {
232 #if UNITY_WSA
233  // Allow observing if a device is present (Holographic Remoting)
234 #if UNITY_2017_2_OR_NEWER
235  if (!UnityEngine.XR.XRDevice.isPresent) { return; }
236 #else
237  if (!UnityEngine.VR.VRDevice.isPresent) { return; }
238 #endif
239 #endif
240  if (IsObserverRunning())
241  {
242  surfaceObserver.StopObserving();
243  }
244  }
245 
249  public void CleanupObserver()
250  {
251  surfaceObserver.CleanupObserver();
252  }
253 
260  public List<Mesh> GetMeshes()
261  {
262  List<Mesh> meshes = new List<Mesh>();
263  List<MeshFilter> meshFilters = GetMeshFilters();
264 
265  // Get all valid mesh filters for observed surfaces.
266  for (int i = 0; i < meshFilters.Count; i++)
267  {
268  // GetMeshFilters ensures that both filter and filter.sharedMesh are not null.
269  meshes.Add(meshFilters[i].sharedMesh);
270  }
271 
272  return meshes;
273  }
274 
280  {
281  return Source.SurfaceObjects;
282  }
283 
288  public List<MeshFilter> GetMeshFilters()
289  {
290  return Source.GetMeshFilters();
291  }
292 
296  private void SetShadowCasting(bool canCastShadows)
297  {
298  CastShadows = canCastShadows;
299  foreach (MeshRenderer sourceRenderer in Source.GetMeshRenderers())
300  {
301  if (sourceRenderer != null)
302  {
303  if (canCastShadows)
304  {
305  sourceRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
306  }
307  else
308  {
309  sourceRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
310  }
311  }
312  }
313  }
314 
320  private void UpdateRendering(bool enable)
321  {
322  if (Source != null)
323  {
324  List<MeshRenderer> renderers = Source.GetMeshRenderers();
325  for (int index = 0; index < renderers.Count; index++)
326  {
327  if (renderers[index] != null)
328  {
329  renderers[index].enabled = enable;
330  if (enable)
331  {
332  renderers[index].sharedMaterial = SurfaceMaterial;
333  }
334  }
335  }
336  }
337  }
338  }
339 }
void CleanupObserver()
Instructs the SurfaceObserver to stop and cleanup all meshes.
ObserverStates ObserverState
Indicates the current state of the Surface Observer.
bool IsObserverRunning()
Checks to see if the SurfaceObserver is currently running.
EventHandler< PropertyChangedEventArgsEx< SpatialMappingSource > > SourceChanged
Occurs when Source changes.
void StopObserver()
Instructs the SurfaceObserver to stop updating the SpatialMapping mesh.
void StartObserver()
Instructs the SurfaceObserver to start updating the SpatialMapping mesh.
The SpatialMappingObserver class encapsulates the SurfaceObserver into an easy to use object that han...
List< MeshFilter > GetMeshFilters()
Gets all Mesh Filter objects associated with the Spatial Mapping mesh.
List< Mesh > GetMeshes()
Gets all meshes that are associated with the SpatialMapping mesh.
ReadOnlyCollection< SpatialMappingSource.SurfaceObject > GetSurfaceObjects()
Gets all the surface objects associated with the Spatial Mapping mesh.
void SetSpatialMappingSource(SpatialMappingSource mappingSource)
Sets the source of surface information.
ObserverStates
Spatial Mapping Observer states.
The SpatialMappingManager class allows applications to use a SurfaceObserver or a stored Spatial Mapp...
override void Awake()
Base Awake method that sets the Singleton&#39;s unique instance. Called by Unity when initializing a Mono...
void CleanupObserver()
Cleans up all memory and objects associated with the observer.
void SetSurfaceMaterial(Material setSurfaceMaterial)
Sets the material used by all Spatial Mapping meshes.
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14