@@ -41,7 +41,44 @@ public GenericXRSDKSpatialMeshObserver(
41
41
BaseMixedRealityProfile profile = null ) : base ( spatialAwarenessSystem , name , priority , profile )
42
42
{ }
43
43
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
+ }
45
82
46
83
/// <inheritdoc />
47
84
public override void Enable ( )
@@ -58,6 +95,7 @@ public override void Enable()
58
95
return ;
59
96
}
60
97
98
+ ConfigureObserverVolume ( ) ;
61
99
base . Enable ( ) ;
62
100
}
63
101
@@ -73,30 +111,16 @@ private async void EnableIfLoaderBecomesActive()
73
111
#region BaseSpatialObserver Implementation
74
112
75
113
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 :
83
116
#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 ;
90
120
#else
91
121
meshSubsystem = XRSubsystemHelpers . MeshSubsystem ;
92
122
#endif // XR_MANAGEMENT_ENABLED
93
123
94
- if ( meshSubsystem != null )
95
- {
96
- ConfigureObserverVolume ( ) ;
97
- }
98
- }
99
-
100
124
/// <summary>
101
125
/// Implements proper cleanup of the SurfaceObserver.
102
126
/// </summary>
@@ -119,15 +143,15 @@ protected override int LookupTriangleDensity(SpatialAwarenessMeshLevelOfDetail l
119
143
{
120
144
// For non-custom levels, the enum value is the appropriate triangles per cubic meter.
121
145
int level = ( int ) levelOfDetail ;
122
- if ( meshSubsystem != null )
146
+ if ( MeshSubsystem != null )
123
147
{
124
148
if ( levelOfDetail == SpatialAwarenessMeshLevelOfDetail . Unlimited )
125
149
{
126
- meshSubsystem . meshDensity = 1 ;
150
+ MeshSubsystem . meshDensity = 1 ;
127
151
}
128
152
else
129
153
{
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
131
155
}
132
156
}
133
157
return level ;
@@ -215,9 +239,9 @@ public override void Resume()
215
239
216
240
using ( ResumePerfMarker . Auto ( ) )
217
241
{
218
- if ( meshSubsystem != null && ! meshSubsystem . running )
242
+ if ( MeshSubsystem != null && ! MeshSubsystem . running )
219
243
{
220
- meshSubsystem . Start ( ) ;
244
+ MeshSubsystem . Start ( ) ;
221
245
}
222
246
223
247
// We want the first update immediately.
@@ -241,9 +265,9 @@ public override void Suspend()
241
265
242
266
using ( SuspendPerfMarker . Auto ( ) )
243
267
{
244
- if ( meshSubsystem != null && meshSubsystem . running )
268
+ if ( MeshSubsystem != null && MeshSubsystem . running )
245
269
{
246
- meshSubsystem . Stop ( ) ;
270
+ MeshSubsystem . Stop ( ) ;
247
271
}
248
272
249
273
// UpdateObserver keys off of this value to stop observing.
@@ -293,7 +317,7 @@ public override void ClearObservations()
293
317
/// </summary>
294
318
private void UpdateObserver ( )
295
319
{
296
- if ( Service == null || meshSubsystem == null ) { return ; }
320
+ if ( Service == null || MeshSubsystem == null ) { return ; }
297
321
298
322
using ( UpdateObserverPerfMarker . Auto ( ) )
299
323
{
@@ -325,7 +349,7 @@ private void UpdateObserver()
325
349
// The application can update the observer volume at any time, make sure we are using the latest.
326
350
ConfigureObserverVolume ( ) ;
327
351
328
- if ( meshSubsystem . TryGetMeshInfos ( meshInfos ) )
352
+ if ( MeshSubsystem . TryGetMeshInfos ( meshInfos ) )
329
353
{
330
354
UpdateMeshes ( meshInfos ) ;
331
355
}
@@ -368,7 +392,7 @@ private void RequestMesh(MeshId meshId)
368
392
newMesh . GameObject . SetActive ( true ) ;
369
393
}
370
394
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 ) ) ;
372
396
outstandingMeshObject = newMesh ;
373
397
}
374
398
}
@@ -439,7 +463,7 @@ protected void ReclaimMeshObject(SpatialAwarenessMeshObject availableMeshObject)
439
463
/// </summary>
440
464
protected virtual void ConfigureObserverVolume ( )
441
465
{
442
- if ( meshSubsystem == null
466
+ if ( MeshSubsystem == null
443
467
|| ( oldObserverOrigin == ObserverOrigin
444
468
&& oldObservationExtents == ObservationExtents
445
469
&& oldObserverVolumeType == ObserverVolumeType ) )
@@ -453,7 +477,7 @@ protected virtual void ConfigureObserverVolume()
453
477
switch ( ObserverVolumeType )
454
478
{
455
479
case VolumeType . AxisAlignedCube :
456
- meshSubsystem . SetBoundingVolume ( ObserverOrigin , ObservationExtents ) ;
480
+ MeshSubsystem . SetBoundingVolume ( ObserverOrigin , ObservationExtents ) ;
457
481
break ;
458
482
459
483
default :
@@ -590,7 +614,7 @@ public override void Initialize()
590
614
{
591
615
base . Initialize ( ) ;
592
616
593
- if ( Service == null || meshSubsystem == null ) { return ; }
617
+ if ( Service == null || MeshSubsystem == null ) { return ; }
594
618
595
619
if ( RuntimeSpatialMeshPrefab != null )
596
620
{
0 commit comments