Singularity/Library/PackageCache/com.unity.render-pipelines..../Editor/Lighting/ProbeVolume/ProbeVolumeUI.Drawer.cs

216 lines
9.9 KiB
C#
Raw Normal View History

2024-05-06 14:45:45 -04:00
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEditor.Rendering;
// TODO(Nicholas): deduplicate with LocalVolumetricFogUI.Drawer.cs.
namespace UnityEditor.Experimental.Rendering
{
using CED = CoreEditorDrawer<SerializedProbeVolume>;
static partial class ProbeVolumeUI
{
internal static readonly CED.IDrawer Inspector = CED.Group(
CED.Group(
Drawer_VolumeContent,
Drawer_BakeToolBar
)
);
static void Drawer_BakeToolBar(SerializedProbeVolume serialized, Editor owner)
{
if (!ProbeReferenceVolume.instance.isInitialized) return;
Bounds bounds = new Bounds();
bool foundABound = false;
bool performFitting = false;
bool performFittingOnlyOnSelection = false;
bool ContributesToGI(Renderer renderer)
{
var flags = GameObjectUtility.GetStaticEditorFlags(renderer.gameObject) & StaticEditorFlags.ContributeGI;
return (flags & StaticEditorFlags.ContributeGI) != 0;
}
void ExpandBounds(Bounds currBound)
{
if (!foundABound)
{
bounds = currBound;
foundABound = true;
}
else
{
bounds.Encapsulate(currBound);
}
}
if (GUILayout.Button(EditorGUIUtility.TrTextContent("Fit to Scene"), EditorStyles.miniButton))
{
performFitting = true;
}
if (GUILayout.Button(EditorGUIUtility.TrTextContent("Fit to Selection"), EditorStyles.miniButton))
{
performFitting = true;
performFittingOnlyOnSelection = true;
}
if (performFitting)
{
ProbeVolume pv = (serialized.serializedObject.targetObject as ProbeVolume);
Undo.RecordObject(pv.transform, "Fitting Probe Volume");
if (performFittingOnlyOnSelection)
{
var transforms = Selection.transforms;
foreach (var transform in transforms)
{
var childrens = transform.gameObject.GetComponentsInChildren<Transform>();
foreach (var children in childrens)
{
Renderer childRenderer;
if (children.gameObject.TryGetComponent<Renderer>(out childRenderer))
{
bool childContributeGI = ContributesToGI(childRenderer) && childRenderer.gameObject.activeInHierarchy && childRenderer.enabled;
if (childContributeGI)
{
ExpandBounds(childRenderer.bounds);
}
}
}
}
}
else
{
var renderers = UnityEngine.GameObject.FindObjectsOfType<Renderer>();
foreach (Renderer renderer in renderers)
{
bool contributeGI = ContributesToGI(renderer) && renderer.gameObject.activeInHierarchy && renderer.enabled;
if (contributeGI)
{
ExpandBounds(renderer.bounds);
}
}
}
pv.transform.position = bounds.center;
float minBrickSize = ProbeReferenceVolume.instance.MinBrickSize();
Vector3 tmpClamp = (bounds.size + new Vector3(minBrickSize, minBrickSize, minBrickSize));
tmpClamp.x = Mathf.Max(0f, tmpClamp.x);
tmpClamp.y = Mathf.Max(0f, tmpClamp.y);
tmpClamp.z = Mathf.Max(0f, tmpClamp.z);
serialized.size.vector3Value = tmpClamp;
}
}
static void Drawer_ToolBar(SerializedProbeVolume serialized, Editor owner)
{
}
static void Drawer_VolumeContent(SerializedProbeVolume serialized, Editor owner)
{
if (!ProbeReferenceVolume.instance.isInitialized || !ProbeReferenceVolume.instance.enabledBySRP)
{
var renderPipelineAsset = UnityEngine.Rendering.RenderPipelineManager.currentPipeline;
if (renderPipelineAsset != null && renderPipelineAsset.GetType().Name == "HDRenderPipeline")
{
EditorGUILayout.HelpBox("The probe volumes feature is disabled. The feature needs to be enabled in the HDRP Settings and on the used HDRP asset.", MessageType.Warning, wide: true);
}
else
{
EditorGUILayout.HelpBox("The probe volumes feature is not enabled or not available on current SRP.", MessageType.Warning, wide: true);
}
return;
}
ProbeVolume pv = (serialized.serializedObject.targetObject as ProbeVolume);
bool hasProfile = (ProbeReferenceVolume.instance.sceneData?.GetProfileForScene(pv.gameObject.scene) != null);
EditorGUI.BeginChangeCheck();
if (pv.mightNeedRebaking)
{
var helpBoxRect = GUILayoutUtility.GetRect(new GUIContent(Styles.s_ProbeVolumeChangedMessage, EditorGUIUtility.IconContent("Warning@2x").image), EditorStyles.helpBox);
EditorGUI.HelpBox(helpBoxRect, Styles.s_ProbeVolumeChangedMessage, MessageType.Warning);
}
EditorGUILayout.PropertyField(serialized.globalVolume, Styles.s_GlobalVolume);
if (!serialized.globalVolume.boolValue)
EditorGUILayout.PropertyField(serialized.size, Styles.s_Size);
if (!hasProfile)
{
EditorGUILayout.HelpBox("No profile information is set for the scene that owns this probe volume so no subdivision information can be retrieved.", MessageType.Warning);
}
EditorGUI.BeginDisabledGroup(!hasProfile);
var rect = EditorGUILayout.GetControlRect(true);
EditorGUI.BeginProperty(rect, Styles.s_HighestSubdivLevel, serialized.highestSubdivisionLevelOverride);
EditorGUI.BeginProperty(rect, Styles.s_LowestSubdivLevel, serialized.lowestSubdivisionLevelOverride);
// Round min and max subdiv
int maxSubdiv = ProbeReferenceVolume.instance.GetMaxSubdivision() - 1;
if (ProbeReferenceVolume.instance.sceneData != null)
{
var profile = ProbeReferenceVolume.instance.sceneData.GetProfileForScene(pv.gameObject.scene);
if (profile != null)
{
ProbeReferenceVolume.instance.SetMinBrickAndMaxSubdiv(profile.minBrickSize, profile.maxSubdivision);
maxSubdiv = ProbeReferenceVolume.instance.GetMaxSubdivision() - 1;
}
else
{
maxSubdiv = Mathf.Max(0, maxSubdiv);
}
}
EditorGUILayout.LabelField("Subdivision Overrides", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(serialized.overridesSubdivision, Styles.s_OverridesSubdivision);
EditorGUI.BeginDisabledGroup(!serialized.overridesSubdivision.boolValue);
int value = serialized.highestSubdivisionLevelOverride.intValue;
// We were initialized, but we cannot know the highest subdiv statically, so we need to resort to this.
if (serialized.highestSubdivisionLevelOverride.intValue < 0)
serialized.highestSubdivisionLevelOverride.intValue = maxSubdiv;
serialized.highestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_HighestSubdivLevel, serialized.highestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_LowestSubdivLevel, serialized.lowestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(serialized.lowestSubdivisionLevelOverride.intValue, serialized.highestSubdivisionLevelOverride.intValue);
EditorGUI.EndProperty();
EditorGUI.EndProperty();
int minSubdivInVolume = serialized.overridesSubdivision.boolValue ? serialized.lowestSubdivisionLevelOverride.intValue : 0;
int maxSubdivInVolume = serialized.overridesSubdivision.boolValue ? serialized.highestSubdivisionLevelOverride.intValue : maxSubdiv;
EditorGUI.indentLevel--;
if (hasProfile)
EditorGUILayout.HelpBox($"The distance between probes will fluctuate between : {ProbeReferenceVolume.instance.GetDistanceBetweenProbes(maxSubdiv - maxSubdivInVolume)}m and {ProbeReferenceVolume.instance.GetDistanceBetweenProbes(maxSubdiv - minSubdivInVolume)}m", MessageType.Info);
EditorGUI.EndDisabledGroup();
EditorGUI.EndDisabledGroup();
if (EditorGUI.EndChangeCheck())
{
Vector3 tmpClamp = serialized.size.vector3Value;
tmpClamp.x = Mathf.Max(0f, tmpClamp.x);
tmpClamp.y = Mathf.Max(0f, tmpClamp.y);
tmpClamp.z = Mathf.Max(0f, tmpClamp.z);
serialized.size.vector3Value = tmpClamp;
}
EditorGUILayout.LabelField("Geometry Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(serialized.objectLayerMask, Styles.s_ObjectLayerMask);
EditorGUILayout.PropertyField(serialized.geometryDistanceOffset, Styles.s_GeometryDistanceOffset);
EditorGUI.indentLevel--;
}
}
}