InsAsterix/InsAsterix/Library/PackageCache/com.unity.render-pipelines.core@12.1.9/Editor/Volume/VolumeComponentProvider.cs
2023-03-02 20:21:33 +01:00

191 wiersze
6,2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering
{
using IProvider = FilterWindow.IProvider;
using Element = FilterWindow.Element;
using GroupElement = FilterWindow.GroupElement;
class VolumeComponentProvider : IProvider
{
class VolumeComponentElement : Element
{
public Type type;
public VolumeComponentElement(int level, string label, Type type)
{
this.level = level;
this.type = type;
// TODO: Add support for custom icons
content = new GUIContent(label);
}
}
class PathNode : IComparable<PathNode>
{
public List<PathNode> nodes = new List<PathNode>();
public string name;
public Type type;
public int CompareTo(PathNode other)
{
return name.CompareTo(other.name);
}
}
public Vector2 position { get; set; }
VolumeProfile m_Target;
VolumeComponentListEditor m_TargetEditor;
public VolumeComponentProvider(VolumeProfile target, VolumeComponentListEditor targetEditor)
{
m_Target = target;
m_TargetEditor = targetEditor;
}
static readonly Dictionary<Type, List<(string, Type)>> s_SupportedVolumeComponentsForRenderPipeline = new();
static List<(string, Type)> GetSupportedVolumeComponents(Type currentPipelineType)
{
if (s_SupportedVolumeComponentsForRenderPipeline.TryGetValue(currentPipelineType,
out var supportedVolumeComponents))
return supportedVolumeComponents;
supportedVolumeComponents = FilterVolumeComponentTypes(
VolumeManager.instance.baseComponentTypeArray, currentPipelineType);
s_SupportedVolumeComponentsForRenderPipeline[currentPipelineType] = supportedVolumeComponents;
return supportedVolumeComponents;
}
static List<(string, Type)> FilterVolumeComponentTypes(Type[] types, Type currentPipelineType)
{
var volumes = new List<(string, Type)>();
foreach (var t in types)
{
string path = string.Empty;
var attrs = t.GetCustomAttributes(false);
bool skipComponent = false;
// Look for the attributes of this volume component and decide how is added and if it needs to be skipped
foreach (var attr in attrs)
{
switch (attr)
{
case VolumeComponentMenu attrMenu:
{
path = attrMenu.menu;
if (attrMenu is VolumeComponentMenuForRenderPipeline supportedOn)
skipComponent |= !supportedOn.pipelineTypes.Contains(currentPipelineType);
break;
}
case HideInInspector attrHide:
case ObsoleteAttribute attrDeprecated:
skipComponent = true;
break;
}
}
if (skipComponent)
continue;
// If no attribute or in case something went wrong when grabbing it, fallback to a
// beautified class name
if (string.IsNullOrEmpty(path))
path = ObjectNames.NicifyVariableName(t.Name);
volumes.Add((path, t));
}
return volumes;
}
public void CreateComponentTree(List<Element> tree)
{
var currentPipeline = RenderPipelineManager.currentPipeline;
if (currentPipeline == null)
{
tree.Add(new GroupElement(0, "No SRP in use"));
return;
}
tree.Add(new GroupElement(0, "Volume Overrides"));
var volumeComponentTypesFiltered =
GetSupportedVolumeComponents(currentPipeline.GetType());
if (volumeComponentTypesFiltered.Any())
{
var rootNode = new PathNode();
foreach (var (path, t) in volumeComponentTypesFiltered)
{
// Skip components that have already been added to the volume
if (m_Target.Has(t))
continue;
// Prep the categories & types tree
AddNode(rootNode, path, t);
}
// Recursively add all elements to the tree
Traverse(rootNode, 1, tree);
}
}
public bool GoToChild(Element element, bool addIfComponent)
{
if (element is VolumeComponentElement volumeComponentElement)
{
m_TargetEditor.AddComponent(volumeComponentElement.type);
return true;
}
return false;
}
void AddNode(PathNode root, string path, Type type)
{
var current = root;
var parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var part in parts)
{
var child = current.nodes.Find(x => x.name == part);
if (child == null)
{
child = new PathNode { name = part, type = type };
current.nodes.Add(child);
}
current = child;
}
}
void Traverse(PathNode node, int depth, List<Element> tree)
{
node.nodes.Sort();
foreach (var n in node.nodes)
{
if (n.nodes.Count > 0) // Group
{
tree.Add(new GroupElement(depth, n.name));
Traverse(n, depth + 1, tree);
}
else // Element
{
tree.Add(new VolumeComponentElement(depth, n.name, n.type));
}
}
}
}
}