public void DeleteBakedDataByName(string name, string prefix)
        {
            SteamAudioManager steamAudioManager = null;
            IntPtr            probeBox          = IntPtr.Zero;

            try
            {
                steamAudioManager = FindObjectOfType <SteamAudioManager>();
                if (steamAudioManager == null)
                {
                    throw new Exception("Phonon Manager Settings object not found in the scene! Click Window > Phonon");
                }

                var context = steamAudioManager.GameEngineState().Context();

                PhononCore.iplLoadProbeBox(context, probeBoxData, probeBoxData.Length, ref probeBox);
                PhononCore.iplDeleteBakedDataByName(probeBox, Common.HashStringForIdentifierWithPrefix(name, prefix));
                UpdateProbeDataMapping(name, prefix, -1);

                int probeBoxSize = PhononCore.iplSaveProbeBox(probeBox, null);
                probeBoxData = new byte[probeBoxSize];
                PhononCore.iplSaveProbeBox(probeBox, probeBoxData);
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
        }
        public void DeleteBakedDataByIdentifier(BakedDataIdentifier identifier)
        {
            SteamAudioManager steamAudioManager = null;
            IntPtr            probeBox          = IntPtr.Zero;

            try
            {
                steamAudioManager = FindObjectOfType <SteamAudioManager>();
                if (steamAudioManager == null)
                {
                    throw new Exception("Phonon Manager Settings object not found in the scene! Click Window > Phonon");
                }

                steamAudioManager.Initialize(GameEngineStateInitReason.EditingProbes);
                var context = steamAudioManager.GameEngineState().Context();

                byte[] probeBoxData = LoadData();
                PhononCore.iplLoadProbeBox(context, probeBoxData, probeBoxData.Length, ref probeBox);
                PhononCore.iplDeleteBakedDataByIdentifier(probeBox, identifier);
                RemoveLayer(identifier);

                int probeBoxSize = PhononCore.iplSaveProbeBox(probeBox, null);
                probeBoxData = new byte[probeBoxSize];
                PhononCore.iplSaveProbeBox(probeBox, probeBoxData);
                SaveData(probeBoxData);

                steamAudioManager.Destroy();
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
        }
        //
        // Draws the inspector.
        //
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            // Audio Engine
            GUI.enabled = !EditorApplication.isPlayingOrWillChangePlaymode;
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Audio Engine Integration", EditorStyles.boldLabel);
            string[] engines             = { "Unity", "FMOD Studio" };
            var      audioEngineProperty = serializedObject.FindProperty("audioEngine");

            audioEngineProperty.enumValueIndex = EditorGUILayout.Popup("Audio Engine",
                                                                       audioEngineProperty.enumValueIndex, engines);

            // Scene Settings
            SteamAudioManager steamAudioManager = ((SteamAudioManager)target);

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Global Material Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("materialPreset"));
            if (serializedObject.FindProperty("materialPreset").enumValueIndex < 11)
            {
                MaterialValue actualValue = steamAudioManager.materialValue;
                actualValue.CopyFrom(MaterialPresetList.PresetValue(
                                         serializedObject.FindProperty("materialPreset").enumValueIndex));
            }
            else
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("materialValue"));
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Scene Export", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel(" ");
            if (GUILayout.Button("Export to OBJ"))
            {
                steamAudioManager.ExportScene(true);
            }
            if (GUILayout.Button("Pre-Export Scene"))
            {
                steamAudioManager.ExportScene(false);
            }
            EditorGUILayout.EndHorizontal();

            // Simulation Settings
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Simulation Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("simulationPreset"));
            if (serializedObject.FindProperty("simulationPreset").enumValueIndex < 3)
            {
                SimulationSettingsValue actualValue = steamAudioManager.simulationValue;
                actualValue.CopyFrom(SimulationSettingsPresetList.PresetValue(
                                         serializedObject.FindProperty("simulationPreset").enumValueIndex));
            }
            else
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("simulationValue"));

                SimulationSettingsValue actualValue = steamAudioManager.simulationValue;

                if (actualValue.AmbisonicsOrder > 2)
                {
                    var numChannels = (actualValue.AmbisonicsOrder + 1) * (actualValue.AmbisonicsOrder + 1);
                    EditorGUILayout.HelpBox("Ambisonics order " + actualValue.AmbisonicsOrder.ToString() +
                                            " uses " + numChannels.ToString() + " channels per source for processing indirect sound. " +
                                            "This may significantly increase CPU usage. Consider reducing this value unless necessary.",
                                            MessageType.Warning);
                }

                if (Application.isEditor && EditorApplication.isPlayingOrWillChangePlaymode)
                {
                    IntPtr environment = steamAudioManager.GameEngineState().Environment().GetEnvironment();
                    if (environment != IntPtr.Zero)
                    {
                        PhononCore.iplSetNumBounces(environment, actualValue.RealtimeBounces);
                    }
                }
            }

            // Fold Out for Advanced Settings
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Advanced Options", EditorStyles.boldLabel);
            serializedObject.FindProperty("showLoadTimeOptions").boolValue =
                EditorGUILayout.Foldout(serializedObject.FindProperty("showLoadTimeOptions").boolValue,
                                        "Per Frame Query Optimization");

            if (steamAudioManager.showLoadTimeOptions)
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("updateComponents"));

                var updateComponents = serializedObject.FindProperty("updateComponents").boolValue;
                if (!updateComponents)
                {
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("currentAudioListener"));
                }
            }

            serializedObject.FindProperty("showMassBakingOptions").boolValue =
                EditorGUILayout.Foldout(serializedObject.FindProperty("showMassBakingOptions").boolValue,
                                        "Consolidated Baking Options");
            if (steamAudioManager.showMassBakingOptions)
            {
                bool noSettingMessage = false;
                noSettingMessage = ProbeGenerationGUI() || noSettingMessage;
                noSettingMessage = BakeAllGUI() || noSettingMessage;
                noSettingMessage = BakedSourcesGUI(steamAudioManager) || noSettingMessage;
                noSettingMessage = BakedStaticListenerNodeGUI(steamAudioManager) || noSettingMessage;
                noSettingMessage = BakedReverbGUI(steamAudioManager) || noSettingMessage;

                if (!noSettingMessage)
                {
                    EditorGUILayout.LabelField("Scene does not contain any baking related components.");
                }
            }

            GUI.enabled = true;
            EditorGUILayout.HelpBox("Do not manually add Steam Audio Manager component. " +
                                    "Click Window > Steam Audio.", MessageType.Info);

            EditorGUILayout.Space();
            serializedObject.ApplyModifiedProperties();
        }
        //
        // Draws the inspector.
        //
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            // Audio Engine
            GUI.enabled = !EditorApplication.isPlayingOrWillChangePlaymode;
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("Do not manually add Steam Audio Manager component. " +
                                    "Click Window > Steam Audio.", MessageType.Info);
            EditorGUILayout.LabelField("Audio Engine Integration", EditorStyles.boldLabel);
            string[] engines             = { "Unity", "FMOD Studio" };
            var      audioEngineProperty = serializedObject.FindProperty("audioEngine");

            audioEngineProperty.enumValueIndex = EditorGUILayout.Popup("Audio Engine",
                                                                       audioEngineProperty.enumValueIndex, engines);

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("HRTF Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("sofaFiles"), new GUIContent("SOFA Files"), true);

            SteamAudioManager steamAudioManager = (SteamAudioManager)target;

            var wasGUIEnabled = GUI.enabled;

            GUI.enabled = true;

            var sofaFiles = steamAudioManager.GetSOFAFileNames();

            if (sofaFiles != null)
            {
                var sofaFileNames = new string[sofaFiles.Length];
                for (var i = 0; i < sofaFileNames.Length; ++i)
                {
                    sofaFileNames[i] = sofaFiles[i];
                    if (sofaFileNames[i].Length == 0 || sofaFileNames[i] == "")
                    {
                        sofaFileNames[i] = "Default";
                    }
                }
                var currentSOFAFileProperty = serializedObject.FindProperty("currentSOFAFile");
                if (currentSOFAFileProperty.intValue >= sofaFiles.Length)
                {
                    currentSOFAFileProperty.intValue = 0;
                }
                currentSOFAFileProperty.intValue = EditorGUILayout.Popup("Current SOFA File",
                                                                         currentSOFAFileProperty.intValue, sofaFileNames);
            }

            GUI.enabled = wasGUIEnabled;

            // Scene Settings
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Global Material Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("materialPreset"));
            if (serializedObject.FindProperty("materialPreset").enumValueIndex < 11)
            {
                MaterialValue actualValue = steamAudioManager.materialValue;
                actualValue.CopyFrom(MaterialPresetList.PresetValue(
                                         serializedObject.FindProperty("materialPreset").enumValueIndex));
            }
            else
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("materialValue"));
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Scene Export", EditorStyles.boldLabel);
            if (GUILayout.Button("Pre-Export Scene"))
            {
                steamAudioManager.ExportScene(false);
            }
            if (GUILayout.Button("Export All Dynamic Objects"))
            {
                ExportAllDynamicObjects();
            }
            if (GUILayout.Button("Export to OBJ"))
            {
                steamAudioManager.ExportScene(true);
            }

            // Simulation Settings
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Simulation Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("simulationPreset"));
            if (serializedObject.FindProperty("simulationPreset").enumValueIndex < 3)
            {
                SimulationSettingsValue actualValue = steamAudioManager.simulationValue;
                actualValue.CopyFrom(SimulationSettingsPresetList.PresetValue(
                                         serializedObject.FindProperty("simulationPreset").enumValueIndex));

                EditorGUILayout.Space();
                UnityRayTracerGUI(true);
            }
            else
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("simulationValue"));

                SimulationSettingsValue actualValue = steamAudioManager.simulationValue;

                if (actualValue.AmbisonicsOrder > 2)
                {
                    var numChannels = (actualValue.AmbisonicsOrder + 1) * (actualValue.AmbisonicsOrder + 1);
                    EditorGUILayout.HelpBox("Ambisonics order " + actualValue.AmbisonicsOrder.ToString() +
                                            " uses " + numChannels.ToString() + " channels per source for processing indirect sound. " +
                                            "This may significantly increase CPU usage. Consider reducing this value unless necessary.",
                                            MessageType.Warning);
                }

                UnityRayTracerGUI(false);

                if (Application.isEditor && EditorApplication.isPlayingOrWillChangePlaymode)
                {
                    IntPtr environment = steamAudioManager.GameEngineState().Environment().GetEnvironment();
                    if (environment != IntPtr.Zero)
                    {
                        PhononCore.iplSetNumBounces(environment, actualValue.RealtimeBounces);
                    }
                }
            }

            // Display information message about CPU usage.
            int    realTimeThreads = (int)Mathf.Max(1, (steamAudioManager.simulationValue.RealtimeThreadsPercentage * SystemInfo.processorCount) / 100.0f);
            int    bakingThreads   = (int)Mathf.Max(1, (steamAudioManager.simulationValue.BakeThreadsPercentage * SystemInfo.processorCount) / 100.0f);
            string realTimeString  = (realTimeThreads == 1) ? "1 of " + SystemInfo.processorCount + " logical processor" :
                                     realTimeThreads + " of " + SystemInfo.processorCount + " logical processors";
            string bakingString = (bakingThreads == 1) ? "1 of " + SystemInfo.processorCount + " logical processor" :
                                  bakingThreads + " of " + SystemInfo.processorCount + " logical processors";

            EditorGUILayout.HelpBox("On this machine setting realtime CPU cores to " + steamAudioManager.simulationValue.RealtimeThreadsPercentage +
                                    "% will use " + realTimeString + " and setting baking CPU cores to " + steamAudioManager.simulationValue.BakeThreadsPercentage +
                                    "% will use " + bakingString + ". The number of logical processors used on an end user's machine might be different.", MessageType.Info);

            // Fold Out for Advanced Settings
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Advanced Options", EditorStyles.boldLabel);
            serializedObject.FindProperty("showLoadTimeOptions").boolValue =
                EditorGUILayout.Foldout(serializedObject.FindProperty("showLoadTimeOptions").boolValue,
                                        "Per Frame Query Optimization");

            if (steamAudioManager.showLoadTimeOptions)
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("updateComponents"));

                var updateComponents = serializedObject.FindProperty("updateComponents").boolValue;
                if (!updateComponents)
                {
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("currentAudioListener"));
                }
            }

            serializedObject.FindProperty("showMassBakingOptions").boolValue =
                EditorGUILayout.Foldout(serializedObject.FindProperty("showMassBakingOptions").boolValue,
                                        "Consolidated Baking Options");
            if (steamAudioManager.showMassBakingOptions)
            {
                bool noSettingMessage = false;
                noSettingMessage = ProbeGenerationGUI() || noSettingMessage;
                noSettingMessage = BakeAllGUI() || noSettingMessage;
                noSettingMessage = BakedSourcesGUI(steamAudioManager) || noSettingMessage;
                noSettingMessage = BakedStaticListenerNodeGUI(steamAudioManager) || noSettingMessage;
                noSettingMessage = BakedReverbGUI(steamAudioManager) || noSettingMessage;

                if (!noSettingMessage)
                {
                    EditorGUILayout.LabelField("Scene does not contain any baking related components.");
                }
            }

            GUI.enabled = true;
            EditorGUILayout.Space();
            serializedObject.ApplyModifiedProperties();
        }
        public void GenerateProbes()
        {
            ProbePlacementParameters placementParameters;

            placementParameters.placement         = placementStrategy;
            placementParameters.maxNumTriangles   = maxNumTriangles;
            placementParameters.maxOctreeDepth    = maxOctreeDepth;
            placementParameters.horizontalSpacing = horizontalSpacing;
            placementParameters.heightAboveFloor  = heightAboveFloor;

            // Initialize environment
            SteamAudioManager steamAudioManager = null;

            try
            {
                steamAudioManager = FindObjectOfType <SteamAudioManager>();
                if (steamAudioManager == null)
                {
                    throw new Exception("Phonon Manager Settings object not found in the scene! Click Window > Phonon");
                }

                steamAudioManager.Initialize(GameEngineStateInitReason.GeneratingProbes);

                if (steamAudioManager.GameEngineState().Scene().GetScene() == IntPtr.Zero)
                {
                    Debug.LogError("Scene not found. Make sure to pre-export the scene.");
                    steamAudioManager.Destroy();
                    return;
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
                return;
            }

            // Create bounding box for the probe.
            IntPtr probeBox = IntPtr.Zero;

            PhononCore.iplCreateProbeBox(steamAudioManager.GameEngineState().Context(), steamAudioManager.GameEngineState().Scene().GetScene(),
                                         Common.ConvertMatrix(gameObject.transform.localToWorldMatrix), placementParameters, null, ref probeBox);

            int numProbes = PhononCore.iplGetProbeSpheres(probeBox, null);

            probeSpherePoints = new float[3 * numProbes];
            probeSphereRadii  = new float[numProbes];

            Sphere[] probeSpheres = new Sphere[numProbes];
            PhononCore.iplGetProbeSpheres(probeBox, probeSpheres);
            for (int i = 0; i < numProbes; ++i)
            {
                probeSpherePoints[3 * i + 0] = probeSpheres[i].centerx;
                probeSpherePoints[3 * i + 1] = probeSpheres[i].centery;
                probeSpherePoints[3 * i + 2] = probeSpheres[i].centerz;
                probeSphereRadii[i]          = probeSpheres[i].radius;
            }

            // Save probe box into searlized data;
            int probeBoxSize = PhononCore.iplSaveProbeBox(probeBox, null);

            probeBoxData = new byte[probeBoxSize];
            PhononCore.iplSaveProbeBox(probeBox, probeBoxData);

            if (steamAudioManager.GameEngineState().Scene().GetScene() != IntPtr.Zero)
            {
                Debug.Log("Generated " + probeSpheres.Length + " probes for game object " + gameObject.name + ".");
            }

            // Cleanup.
            PhononCore.iplDestroyProbeBox(ref probeBox);
            steamAudioManager.Destroy();
            ClearProbeDataMapping();

            // Redraw scene view for probes to show up instantly.
#if UNITY_EDITOR
            UnityEditor.SceneView.RepaintAll();
#endif
        }