using UnityEngine; using UnityEngine.Rendering; namespace UnityEditor.Rendering { using CED = CoreEditorDrawer; static partial class ProbeVolumeUI { internal static readonly CED.IDrawer Inspector = CED.Group( CED.Group( Drawer_VolumeContent, Drawer_RebakeWarning // This needs to be last to avoid popping in the UI ) ); static void Drawer_BakeToolBar(SerializedProbeVolume serialized, Editor owner) { if (!ProbeReferenceVolume.instance.isInitialized) return; ProbeVolume pv = (serialized.serializedObject.targetObject as ProbeVolume); GIContributors.ContributorFilter? filter = null; if (GUILayout.Button(EditorGUIUtility.TrTextContent("Fit to All Scenes", "Fit this Adaptive Probe Volume to cover all loaded Scenes. "), EditorStyles.miniButton)) filter = GIContributors.ContributorFilter.All; if (GUILayout.Button(EditorGUIUtility.TrTextContent("Fit to Scene", "Fit this Adaptive Probe Volume to the renderers in the same Scene."), EditorStyles.miniButton)) filter = GIContributors.ContributorFilter.Scene; if (GUILayout.Button(EditorGUIUtility.TrTextContent("Fit to Selection", "Fits this Adaptive Probe Volume to the selected renderer(s). Lock the Inspector to make additional selections."), EditorStyles.miniButton)) filter = GIContributors.ContributorFilter.Selection; if (filter.HasValue) { Undo.RecordObject(pv.transform, "Fitting Adaptive Probe Volume"); // Get minBrickSize from scene baking set if available var bakingSet = ProbeVolumeLightingTab.GetSceneBakingSetForUI(pv.gameObject.scene); float minBrickSize = bakingSet != null ? bakingSet.minBrickSize : ProbeReferenceVolume.instance.MinBrickSize(); var bounds = pv.ComputeBounds(filter.Value, pv.gameObject.scene); pv.transform.position = bounds.center; serialized.size.vector3Value = Vector3.Max(bounds.size + new Vector3(minBrickSize, minBrickSize, minBrickSize), Vector3.zero); } } static int s_SubdivisionRangeID = "SubdivisionRange".GetHashCode(); static void SubdivisionRange(SerializedProbeVolume serialized, int maxSimplicationLevel, float minDistance) { var rect = EditorGUILayout.GetControlRect(); EditorGUI.BeginProperty(rect, Styles.s_DistanceBetweenProbes, serialized.minSubdivisionLevel); EditorGUI.BeginProperty(rect, Styles.s_DistanceBetweenProbes, serialized.maxSubdivisionLevel); EditorGUI.BeginProperty(rect, Styles.s_DistanceBetweenProbes, serialized.overridesSubdivision); var checkbox = new Rect(rect) { width = 14 + 9, x = rect.x + 2 }; serialized.overridesSubdivision.boolValue = EditorGUI.Toggle(checkbox, serialized.overridesSubdivision.boolValue); using (new EditorGUI.DisabledScope(!serialized.overridesSubdivision.boolValue)) { EditorGUIUtility.labelWidth -= checkbox.width; rect.xMin = checkbox.xMax - 4; int id = GUIUtility.GetControlID(s_SubdivisionRangeID, FocusType.Keyboard, rect); rect = EditorGUI.PrefixLabel(rect, id, Styles.s_DistanceBetweenProbes); EditorGUIUtility.labelWidth += checkbox.width; // Make sure data is valid float maxLevelOverride = Mathf.Min(serialized.maxSubdivisionLevel.intValue, maxSimplicationLevel); float minLevelOverride = Mathf.Min(serialized.minSubdivisionLevel.intValue, maxLevelOverride); EditorGUI.BeginChangeCheck(); EditorGUI.MinMaxSlider(rect, ref minLevelOverride, ref maxLevelOverride, 0, maxSimplicationLevel); if (EditorGUI.EndChangeCheck()) { GUIUtility.keyboardControl = id; serialized.minSubdivisionLevel.intValue = Mathf.RoundToInt(minLevelOverride); serialized.maxSubdivisionLevel.intValue = Mathf.RoundToInt(maxLevelOverride); } ProbeVolumeLightingTab.DrawSimplificationLevelsMarkers(rect, minDistance, 0, maxSimplicationLevel, serialized.minSubdivisionLevel.intValue, serialized.maxSubdivisionLevel.intValue); } EditorGUI.EndProperty(); EditorGUI.EndProperty(); EditorGUI.EndProperty(); } static void Drawer_VolumeContent(SerializedProbeVolume serialized, Editor owner) { ProbeVolume pv = (serialized.serializedObject.targetObject as ProbeVolume); var bakingSet = ProbeVolumeLightingTab.GetSceneBakingSetForUI(pv.gameObject.scene); EditorGUILayout.PropertyField(serialized.mode); if (serialized.mode.intValue == (int)ProbeVolume.Mode.Local) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(serialized.size, Styles.s_Size); if (EditorGUI.EndChangeCheck()) serialized.size.vector3Value = Vector3.Max(serialized.size.vector3Value, Vector3.zero); Drawer_BakeToolBar(serialized, owner); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Subdivision Override", EditorStyles.boldLabel); bool isFreezingPlacement = bakingSet != null && bakingSet.freezePlacement && AdaptiveProbeVolumes.CanFreezePlacement(); using (new EditorGUI.DisabledScope(isFreezingPlacement)) { // Get settings from scene profile if available int simplificationLevels = ProbeReferenceVolume.instance.GetMaxSubdivision() - 1; float minDistance = ProbeReferenceVolume.instance.MinDistanceBetweenProbes(); if (bakingSet != null) { simplificationLevels = bakingSet.simplificationLevels; minDistance = bakingSet.minDistanceBetweenProbes; } if (simplificationLevels < 0) { simplificationLevels = 5; minDistance = 1; } SubdivisionRange(serialized, simplificationLevels, minDistance); } if (isFreezingPlacement) { CoreEditorUtils.DrawFixMeBox("The placement is frozen in the baking settings. To change these values uncheck the Freeze Placement in the Adaptive Probe Volumes tab of the Lighting Window.", MessageType.Info, "Open", () => { ProbeVolumeLightingTab.OpenBakingSet(bakingSet); }); } EditorGUILayout.LabelField("Geometry Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(serialized.overrideRendererFilters, Styles.s_OverrideRendererFilters); if (serialized.overrideRendererFilters.boolValue) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(serialized.objectLayerMask, Styles.s_ObjectLayerMask); EditorGUILayout.PropertyField(serialized.minRendererVolumeSize, Styles.s_MinRendererVolumeSize); EditorGUI.indentLevel--; } EditorGUILayout.PropertyField(serialized.fillEmptySpaces); if (bakingSet == null) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("The scene this Adaptive Probe Volume is part of does not belong to any Baking Set.", MessageType.Warning); } EditorGUILayout.Space(); using (new EditorGUI.DisabledScope(Lightmapping.isRunning || bakingSet == null)) { ProbeVolumeLightingTab.BakeAPVButton(); } } static void Drawer_RebakeWarning(SerializedProbeVolume serialized, Editor owner) { ProbeVolume pv = (serialized.serializedObject.targetObject as ProbeVolume); if (pv.mightNeedRebaking) { EditorGUILayout.Space(); var helpBoxRect = GUILayoutUtility.GetRect(new GUIContent(Styles.s_ProbeVolumeChangedMessage, EditorGUIUtility.IconContent("Warning@2x").image), EditorStyles.helpBox); EditorGUI.HelpBox(helpBoxRect, Styles.s_ProbeVolumeChangedMessage, MessageType.Warning); } } } }