@@ -41,7 +41,44 @@ public GenericXRSDKSpatialMeshObserver(
4141 BaseMixedRealityProfile profile = null ) : base ( spatialAwarenessSystem , name , priority , profile )
4242 { }
4343
44- protected virtual bool ? IsActiveLoader => true ;
44+ private IReadOnlyList < GenericXRSDKSpatialMeshObserver > observersCache ;
45+
46+ protected virtual bool ? IsActiveLoader
47+ {
48+ get
49+ {
50+ #if XR_MANAGEMENT_ENABLED
51+ if ( XRGeneralSettings . Instance != null
52+ && XRGeneralSettings . Instance . Manager != null
53+ && XRGeneralSettings . Instance . Manager . activeLoader != null )
54+ {
55+ if ( ( observersCache == null || observersCache . Count == 0 )
56+ && Service is IMixedRealityDataProviderAccess spatialAwarenessDataProviderAccess
57+ && Service is IMixedRealityServiceState spatialAwarenessState
58+ && spatialAwarenessState . IsInitialized )
59+ {
60+ observersCache = spatialAwarenessDataProviderAccess . GetDataProviders < GenericXRSDKSpatialMeshObserver > ( ) ;
61+ }
62+
63+ // Don't report ourselves as active if another observer is handling this platform
64+ for ( int i = 0 ; i < observersCache ? . Count ; i ++ )
65+ {
66+ GenericXRSDKSpatialMeshObserver observer = observersCache [ i ] ;
67+ if ( observer != this && ( observer . IsActiveLoader ?? false ) )
68+ {
69+ return false ;
70+ }
71+ }
72+
73+ return true ;
74+ }
75+
76+ return null ;
77+ #else
78+ return false ;
79+ #endif
80+ }
81+ }
4582
4683 /// <inheritdoc />
4784 public override void Enable ( )
@@ -58,6 +95,7 @@ public override void Enable()
5895 return ;
5996 }
6097
98+ ConfigureObserverVolume ( ) ;
6199 base . Enable ( ) ;
62100 }
63101
@@ -73,30 +111,16 @@ private async void EnableIfLoaderBecomesActive()
73111 #region BaseSpatialObserver Implementation
74112
75113 private XRMeshSubsystem meshSubsystem ;
76-
77- /// <summary>
78- /// Creates the XRMeshSubsystem and handles the desired startup behavior.
79- /// </summary>
80- protected override void CreateObserver ( )
81- {
82- if ( Service == null
114+ private XRMeshSubsystem MeshSubsystem => meshSubsystem != null && meshSubsystem . running
115+ ? meshSubsystem :
83116#if XR_MANAGEMENT_ENABLED
84- || XRGeneralSettings . Instance == null || XRGeneralSettings . Instance . Manager == null || XRGeneralSettings . Instance . Manager . activeLoader == null
85- #endif // XR_MANAGEMENT_ENABLED
86- ) { return ; }
87-
88- #if XR_MANAGEMENT_ENABLED
89- meshSubsystem = XRGeneralSettings . Instance . Manager . activeLoader . GetLoadedSubsystem < XRMeshSubsystem > ( ) ;
117+ meshSubsystem = IsActiveLoader ?? false
118+ ? XRGeneralSettings . Instance . Manager . activeLoader . GetLoadedSubsystem < XRMeshSubsystem > ( )
119+ : null ;
90120#else
91121 meshSubsystem = XRSubsystemHelpers . MeshSubsystem ;
92122#endif // XR_MANAGEMENT_ENABLED
93123
94- if ( meshSubsystem != null )
95- {
96- ConfigureObserverVolume ( ) ;
97- }
98- }
99-
100124 /// <summary>
101125 /// Implements proper cleanup of the SurfaceObserver.
102126 /// </summary>
@@ -119,15 +143,15 @@ protected override int LookupTriangleDensity(SpatialAwarenessMeshLevelOfDetail l
119143 {
120144 // For non-custom levels, the enum value is the appropriate triangles per cubic meter.
121145 int level = ( int ) levelOfDetail ;
122- if ( meshSubsystem != null )
146+ if ( MeshSubsystem != null )
123147 {
124148 if ( levelOfDetail == SpatialAwarenessMeshLevelOfDetail . Unlimited )
125149 {
126- meshSubsystem . meshDensity = 1 ;
150+ MeshSubsystem . meshDensity = 1 ;
127151 }
128152 else
129153 {
130- meshSubsystem . meshDensity = level / ( float ) SpatialAwarenessMeshLevelOfDetail . Fine ; // For now, map Coarse to 0.0 and Fine to 1.0
154+ MeshSubsystem . meshDensity = level / ( float ) SpatialAwarenessMeshLevelOfDetail . Fine ; // For now, map Coarse to 0.0 and Fine to 1.0
131155 }
132156 }
133157 return level ;
@@ -215,9 +239,9 @@ public override void Resume()
215239
216240 using ( ResumePerfMarker . Auto ( ) )
217241 {
218- if ( meshSubsystem != null && ! meshSubsystem . running )
242+ if ( MeshSubsystem != null && ! MeshSubsystem . running )
219243 {
220- meshSubsystem . Start ( ) ;
244+ MeshSubsystem . Start ( ) ;
221245 }
222246
223247 // We want the first update immediately.
@@ -241,9 +265,9 @@ public override void Suspend()
241265
242266 using ( SuspendPerfMarker . Auto ( ) )
243267 {
244- if ( meshSubsystem != null && meshSubsystem . running )
268+ if ( MeshSubsystem != null && MeshSubsystem . running )
245269 {
246- meshSubsystem . Stop ( ) ;
270+ MeshSubsystem . Stop ( ) ;
247271 }
248272
249273 // UpdateObserver keys off of this value to stop observing.
@@ -293,7 +317,7 @@ public override void ClearObservations()
293317 /// </summary>
294318 private void UpdateObserver ( )
295319 {
296- if ( Service == null || meshSubsystem == null ) { return ; }
320+ if ( Service == null || MeshSubsystem == null ) { return ; }
297321
298322 using ( UpdateObserverPerfMarker . Auto ( ) )
299323 {
@@ -325,7 +349,7 @@ private void UpdateObserver()
325349 // The application can update the observer volume at any time, make sure we are using the latest.
326350 ConfigureObserverVolume ( ) ;
327351
328- if ( meshSubsystem . TryGetMeshInfos ( meshInfos ) )
352+ if ( MeshSubsystem . TryGetMeshInfos ( meshInfos ) )
329353 {
330354 UpdateMeshes ( meshInfos ) ;
331355 }
@@ -368,7 +392,7 @@ private void RequestMesh(MeshId meshId)
368392 newMesh . GameObject . SetActive ( true ) ;
369393 }
370394
371- meshSubsystem . GenerateMeshAsync ( meshId , newMesh . Filter . mesh , newMesh . Collider , MeshVertexAttributes . Normals , ( MeshGenerationResult meshGenerationResult ) => MeshGenerationAction ( meshGenerationResult ) ) ;
395+ MeshSubsystem . GenerateMeshAsync ( meshId , newMesh . Filter . mesh , newMesh . Collider , MeshVertexAttributes . Normals , ( MeshGenerationResult meshGenerationResult ) => MeshGenerationAction ( meshGenerationResult ) ) ;
372396 outstandingMeshObject = newMesh ;
373397 }
374398 }
@@ -439,7 +463,7 @@ protected void ReclaimMeshObject(SpatialAwarenessMeshObject availableMeshObject)
439463 /// </summary>
440464 protected virtual void ConfigureObserverVolume ( )
441465 {
442- if ( meshSubsystem == null
466+ if ( MeshSubsystem == null
443467 || ( oldObserverOrigin == ObserverOrigin
444468 && oldObservationExtents == ObservationExtents
445469 && oldObserverVolumeType == ObserverVolumeType ) )
@@ -453,7 +477,7 @@ protected virtual void ConfigureObserverVolume()
453477 switch ( ObserverVolumeType )
454478 {
455479 case VolumeType . AxisAlignedCube :
456- meshSubsystem . SetBoundingVolume ( ObserverOrigin , ObservationExtents ) ;
480+ MeshSubsystem . SetBoundingVolume ( ObserverOrigin , ObservationExtents ) ;
457481 break ;
458482
459483 default :
@@ -590,7 +614,7 @@ public override void Initialize()
590614 {
591615 base . Initialize ( ) ;
592616
593- if ( Service == null || meshSubsystem == null ) { return ; }
617+ if ( Service == null || MeshSubsystem == null ) { return ; }
594618
595619 if ( RuntimeSpatialMeshPrefab != null )
596620 {
0 commit comments