You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.8 KiB
208 lines
6.8 KiB
using UnityEngine; |
|
using UnityEngine.PostProcessing; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Reflection; |
|
|
|
namespace UnityEditor.PostProcessing |
|
{ |
|
//[CanEditMultipleObjects] |
|
[CustomEditor(typeof(PostProcessingProfile))] |
|
public class PostProcessingInspector : Editor |
|
{ |
|
static GUIContent s_PreviewTitle = new GUIContent("Monitors"); |
|
|
|
PostProcessingProfile m_ConcreteTarget |
|
{ |
|
get { return target as PostProcessingProfile; } |
|
} |
|
|
|
int m_CurrentMonitorID |
|
{ |
|
get { return m_ConcreteTarget.monitors.currentMonitorID; } |
|
set { m_ConcreteTarget.monitors.currentMonitorID = value; } |
|
} |
|
|
|
List<PostProcessingMonitor> m_Monitors; |
|
GUIContent[] m_MonitorNames; |
|
Dictionary<PostProcessingModelEditor, PostProcessingModel> m_CustomEditors = new Dictionary<PostProcessingModelEditor, PostProcessingModel>(); |
|
|
|
public bool IsInteractivePreviewOpened { get; private set; } |
|
|
|
void OnEnable() |
|
{ |
|
if (target == null) |
|
return; |
|
|
|
// Aggregate custom post-fx editors |
|
var assembly = Assembly.GetAssembly(typeof(PostProcessingInspector)); |
|
|
|
var editorTypes = assembly.GetTypes() |
|
.Where(x => x.IsDefined(typeof(PostProcessingModelEditorAttribute), false)); |
|
|
|
var customEditors = new Dictionary<Type, PostProcessingModelEditor>(); |
|
foreach (var editor in editorTypes) |
|
{ |
|
var attr = (PostProcessingModelEditorAttribute)editor.GetCustomAttributes(typeof(PostProcessingModelEditorAttribute), false)[0]; |
|
var effectType = attr.type; |
|
var alwaysEnabled = attr.alwaysEnabled; |
|
|
|
var editorInst = (PostProcessingModelEditor)Activator.CreateInstance(editor); |
|
editorInst.alwaysEnabled = alwaysEnabled; |
|
editorInst.profile = target as PostProcessingProfile; |
|
editorInst.inspector = this; |
|
customEditors.Add(effectType, editorInst); |
|
} |
|
|
|
// ... and corresponding models |
|
var baseType = target.GetType(); |
|
var property = serializedObject.GetIterator(); |
|
|
|
while (property.Next(true)) |
|
{ |
|
if (!property.hasChildren) |
|
continue; |
|
|
|
var type = baseType; |
|
var srcObject = ReflectionUtils.GetFieldValueFromPath(serializedObject.targetObject, ref type, property.propertyPath); |
|
|
|
if (srcObject == null) |
|
continue; |
|
|
|
PostProcessingModelEditor editor; |
|
if (customEditors.TryGetValue(type, out editor)) |
|
{ |
|
var effect = (PostProcessingModel)srcObject; |
|
|
|
if (editor.alwaysEnabled) |
|
effect.enabled = editor.alwaysEnabled; |
|
|
|
m_CustomEditors.Add(editor, effect); |
|
editor.target = effect; |
|
editor.serializedProperty = property.Copy(); |
|
editor.OnPreEnable(); |
|
} |
|
} |
|
|
|
// Prepare monitors |
|
m_Monitors = new List<PostProcessingMonitor>(); |
|
|
|
var monitors = new List<PostProcessingMonitor> |
|
{ |
|
new HistogramMonitor(), |
|
new WaveformMonitor(), |
|
new ParadeMonitor(), |
|
new VectorscopeMonitor() |
|
}; |
|
|
|
var monitorNames = new List<GUIContent>(); |
|
|
|
foreach (var monitor in monitors) |
|
{ |
|
if (monitor.IsSupported()) |
|
{ |
|
monitor.Init(m_ConcreteTarget.monitors, this); |
|
m_Monitors.Add(monitor); |
|
monitorNames.Add(monitor.GetMonitorTitle()); |
|
} |
|
} |
|
|
|
m_MonitorNames = monitorNames.ToArray(); |
|
|
|
if (m_Monitors.Count > 0) |
|
m_ConcreteTarget.monitors.onFrameEndEditorOnly = OnFrameEnd; |
|
} |
|
|
|
void OnDisable() |
|
{ |
|
if (m_CustomEditors != null) |
|
{ |
|
foreach (var editor in m_CustomEditors.Keys) |
|
editor.OnDisable(); |
|
|
|
m_CustomEditors.Clear(); |
|
} |
|
|
|
if (m_Monitors != null) |
|
{ |
|
foreach (var monitor in m_Monitors) |
|
monitor.Dispose(); |
|
|
|
m_Monitors.Clear(); |
|
} |
|
|
|
if (m_ConcreteTarget != null) |
|
m_ConcreteTarget.monitors.onFrameEndEditorOnly = null; |
|
} |
|
|
|
void OnFrameEnd(RenderTexture source) |
|
{ |
|
if (!IsInteractivePreviewOpened) |
|
return; |
|
|
|
if (m_CurrentMonitorID < m_Monitors.Count) |
|
m_Monitors[m_CurrentMonitorID].OnFrameData(source); |
|
|
|
IsInteractivePreviewOpened = false; |
|
} |
|
|
|
public override void OnInspectorGUI() |
|
{ |
|
serializedObject.Update(); |
|
|
|
// Handles undo/redo events first (before they get used by the editors' widgets) |
|
var e = Event.current; |
|
if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed") |
|
{ |
|
foreach (var editor in m_CustomEditors) |
|
editor.Value.OnValidate(); |
|
} |
|
|
|
if (!m_ConcreteTarget.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.None)) |
|
EditorGUILayout.HelpBox("A debug view is currently enabled. Changes done to an effect might not be visible.", MessageType.Info); |
|
|
|
foreach (var editor in m_CustomEditors) |
|
{ |
|
EditorGUI.BeginChangeCheck(); |
|
|
|
editor.Key.OnGUI(); |
|
|
|
if (EditorGUI.EndChangeCheck()) |
|
editor.Value.OnValidate(); |
|
} |
|
|
|
serializedObject.ApplyModifiedProperties(); |
|
} |
|
|
|
public override GUIContent GetPreviewTitle() |
|
{ |
|
return s_PreviewTitle; |
|
} |
|
|
|
public override bool HasPreviewGUI() |
|
{ |
|
return GraphicsUtils.supportsDX11 && m_Monitors.Count > 0; |
|
} |
|
|
|
public override void OnPreviewSettings() |
|
{ |
|
using (new EditorGUILayout.HorizontalScope()) |
|
{ |
|
if (m_CurrentMonitorID < m_Monitors.Count) |
|
m_Monitors[m_CurrentMonitorID].OnMonitorSettings(); |
|
|
|
GUILayout.Space(5); |
|
m_CurrentMonitorID = EditorGUILayout.Popup(m_CurrentMonitorID, m_MonitorNames, FxStyles.preDropdown, GUILayout.MaxWidth(100f)); |
|
} |
|
} |
|
|
|
public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) |
|
{ |
|
IsInteractivePreviewOpened = true; |
|
|
|
if (m_CurrentMonitorID < m_Monitors.Count) |
|
m_Monitors[m_CurrentMonitorID].OnMonitorGUI(r); |
|
} |
|
} |
|
}
|
|
|