public override void DrawInspectorGUI(object target)
        {
            MixedRealitySpatialAwarenessSystem spatial = (MixedRealitySpatialAwarenessSystem)target;

            EditorGUILayout.LabelField("Observers", EditorStyles.boldLabel);
            int observerIndex = 0;

            foreach (IMixedRealitySpatialAwarenessObserver observer in spatial.GetObservers())
            {
                GUI.color = observer.IsRunning ? enabledColor : disabledColor;

                EditorGUILayout.BeginVertical(EditorStyles.helpBox);

                GUI.color = GetObserverColor(observerIndex);
                GUILayout.Button(observer.Name);
                GUI.color = observer.IsRunning ? enabledColor : disabledColor;

                EditorGUILayout.Toggle("Running", observer.IsRunning);
                EditorGUILayout.LabelField("Source", observer.SourceName);
                EditorGUILayout.Toggle("Is Stationary", observer.IsStationaryObserver);
                EditorGUILayout.FloatField("Update Interval", observer.UpdateInterval);

                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Volume Properties", EditorStyles.boldLabel);
                EditorGUILayout.EnumPopup("Volume Type", observer.ObserverVolumeType);
                EditorGUILayout.Vector3Field("Origin", observer.ObserverOrigin);
                EditorGUILayout.Vector3Field("Rotation", observer.ObserverRotation.eulerAngles);
                EditorGUILayout.Vector3Field("Extents", observer.ObservationExtents);

                EditorGUILayout.EndVertical();
                observerIndex++;
            }

            GUI.color = enabledColor;

            if (!Application.isPlaying)
            {
                EditorGUILayout.HelpBox("Observers will be populated once you enter play mode.", MessageType.Info);
            }
            else if (observerIndex == 0)
            {
                EditorGUILayout.LabelField("(None found)", EditorStyles.miniLabel);
            }

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Editor Options", EditorStyles.boldLabel);
            ShowObserverBoundary = SessionState.GetBool(ShowObserverBoundaryKey, false);
            ShowObserverBoundary = EditorGUILayout.Toggle("Show Observer Boundaries", ShowObserverBoundary);
            SessionState.SetBool(ShowObserverBoundaryKey, ShowObserverBoundary);

            ShowObserverOrigin = SessionState.GetBool(ShowObserverOriginKey, false);
            ShowObserverOrigin = EditorGUILayout.Toggle("Show Observer Origins", ShowObserverOrigin);
            SessionState.SetBool(ShowObserverOriginKey, ShowObserverOrigin);
        }
        public void TestDataProviderRegisteration()
        {
            TestUtilities.InitializeMixedRealityToolkitAndCreateScenes();
            MixedRealityToolkit.Instance.ActiveProfile.SpatialAwarenessSystemProfile = AssetDatabase.LoadAssetAtPath <MixedRealitySpatialAwarenessSystemProfile>(TestSpatialAwarenessSysteProfilePath);

            var spatialAwarenessSystem = new MixedRealitySpatialAwarenessSystem(MixedRealityToolkit.Instance.ActiveProfile.SpatialAwarenessSystemProfile);

            Assert.IsTrue(MixedRealityToolkit.Instance.RegisterService <IMixedRealitySpatialAwarenessSystem>(spatialAwarenessSystem));

            // Since EditMode, we have to auto-enable MRTK spatial awareness system ourselves
            MixedRealityToolkit.Instance.EnableAllServicesByType(typeof(IMixedRealitySpatialAwarenessSystem));

            Assert.AreEqual(1, MixedRealityServiceRegistry.GetAllServices().Count);
            Assert.IsNotNull(MixedRealityToolkit.Instance.GetService <IMixedRealitySpatialAwarenessSystem>());

            var dataProviderAccess = (spatialAwarenessSystem as IMixedRealityDataProviderAccess);

            Assert.IsNotNull(dataProviderAccess);

            var dataProvider = dataProviderAccess.GetDataProvider <TestSpatialAwarenessDataProvider>();

            Assert.IsNotNull(dataProvider);
            Assert.IsTrue(dataProvider.IsInitialized);
            Assert.IsTrue(dataProvider.IsEnabled);

            spatialAwarenessSystem.Disable();
            Assert.IsFalse(dataProvider.IsEnabled);

            spatialAwarenessSystem.Enable();
            // We still have reference to old dataprovider, check still disabled
            Assert.IsFalse(dataProvider.IsEnabled);

            // dataProvider has been unregistered in Disable and new one created by Enable.
            dataProvider = dataProviderAccess.GetDataProvider <TestSpatialAwarenessDataProvider>();
            Assert.IsNotNull(dataProvider);
            Assert.IsTrue(dataProvider.IsEnabled);

            spatialAwarenessSystem.Reset();
            LogAssert.Expect(LogType.Log, "TestDataProvider Reset");
            Assert.IsFalse(dataProvider.IsEnabled);

            // dataProvider has been unregistered and newly created in Reset
            dataProvider = dataProviderAccess.GetDataProvider <TestSpatialAwarenessDataProvider>();
            Assert.IsNotNull(dataProvider);
            Assert.IsTrue(dataProvider.IsInitialized);
        }
        public override void DrawGizmos(object target)
        {
            if (!(ShowObserverBoundary || ShowObserverOrigin))
            {
                return;
            }

            MixedRealitySpatialAwarenessSystem spatial = (MixedRealitySpatialAwarenessSystem)target;

            int observerIndex = 0;

            foreach (IMixedRealitySpatialAwarenessObserver observer in spatial.GetObservers())
            {
                Gizmos.color = GetObserverColor(observerIndex);

                if (ShowObserverBoundary)
                {
                    switch (observer.ObserverVolumeType)
                    {
                    case VolumeType.None:
                        break;

                    case VolumeType.AxisAlignedCube:
                        Gizmos.DrawWireCube(observer.ObserverOrigin, observer.ObservationExtents);
                        break;

                    case VolumeType.Sphere:
                        Gizmos.DrawWireSphere(observer.ObserverOrigin, observer.ObservationExtents.x);
                        break;

                    case VolumeType.UserAlignedCube:
                        Gizmos.DrawWireCube(observer.ObserverOrigin, observer.ObservationExtents);
                        break;
                    }
                }

                Gizmos.matrix = Matrix4x4.identity;

                if (ShowObserverOrigin)
                {
                    Gizmos.DrawSphere(observer.ObserverOrigin, 0.1f);
                }

                observerIndex++;
            }
        }