2021-09-09 20:42:29 -04:00

263 lines
9.3 KiB
C#

//#define OLD_COPY_PASTE
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor.VFX;
using UnityEngine.VFX;
using UnityObject = UnityEngine.Object;
namespace UnityEditor.VFX.UI
{
class GroupNodeAdder
{
}
abstract class SubGraphCache
{
protected SubGraphCache()
{
}
string m_Filter;
public struct Item
{
public string category;
public string name;
public string path;
public object additionalInfos;
}
public struct AdditionalBlockInfo
{
public VFXContextType compatibleType;
public VFXDataType compatibleData;
}
protected List<Item> m_Items = new List<Item>();
protected bool m_UptoDate = false;
public IEnumerable<Item> items
{
get
{
UpdateCache();
return m_Items;
}
}
protected abstract void UpdateCache();
static Dictionary<Type, SubGraphCache> s_Caches = new Dictionary<Type, SubGraphCache>
{
{ typeof(VisualEffectAsset), new SubGraphCache<VisualEffectAsset>()},
{ typeof(VisualEffectSubgraphBlock), new SubGraphCache<VisualEffectSubgraphBlock>()},
{ typeof(VisualEffectSubgraphOperator), new SubGraphCache<VisualEffectSubgraphOperator>()},
};
static void MarkChanged(Type type)
{
SubGraphCache cache;
s_Caches.TryGetValue(type, out cache);
if (cache != null)
cache.m_UptoDate = false;
}
public static IEnumerable<Item> GetItems(Type type)
{
SubGraphCache cache;
s_Caches.TryGetValue(type, out cache);
if (cache != null)
return cache.items;
return Enumerable.Empty<Item>();
}
}
class SubGraphCache<T> : SubGraphCache where T : VisualEffectObject
{
protected override void UpdateCache()
{
var guids = AssetDatabase.FindAssets("t:" + typeof(T).Name);
m_Items.Clear();
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
if (!path.StartsWith(VisualEffectAssetEditorUtility.templatePath))
{
T asset = AssetDatabase.LoadAssetAtPath<T>(path);
if (asset != null)
{
VisualEffectResource res = asset.GetResource();
Item item = new Item() { name = asset.name, category = res.GetOrCreateGraph().categoryPath, path = path };
if (item.category == null)
item.category = "";
if (typeof(T) == typeof(VisualEffectSubgraphBlock))
{
VFXBlockSubgraphContext blockContext = asset.GetResource().GetOrCreateGraph().children.OfType<VFXBlockSubgraphContext>().FirstOrDefault();
if (blockContext != null)
{
item.additionalInfos = new AdditionalBlockInfo() { compatibleType = blockContext.compatibleContextType, compatibleData = blockContext.ownedType };
m_Items.Add(item);
}
}
else
m_Items.Add(item);
}
}
}
m_UptoDate = true;
}
}
class VFXNodeProvider : VFXAbstractProvider<VFXNodeProvider.Descriptor>
{
public class Descriptor
{
public object modelDescriptor;
public string category;
public string name;
}
Func<Descriptor, bool> m_Filter;
IEnumerable<Type> m_AcceptedTypes;
VFXViewController m_Controller;
public VFXNodeProvider(VFXViewController controller, Action<Descriptor, Vector2> onAddBlock, Func<Descriptor, bool> filter = null, IEnumerable<Type> acceptedTypes = null) : base(onAddBlock)
{
m_Filter = filter;
m_AcceptedTypes = acceptedTypes;
m_Controller = controller;
}
protected override string GetCategory(Descriptor desc)
{
return desc.category;
}
protected override string GetName(Descriptor desc)
{
return desc.name;
}
protected override string title
{
get {return "Node"; }
}
string ComputeCategory<T>(string type, VFXModelDescriptor<T> model) where T : VFXModel
{
if (model.info != null && model.info.category != null)
{
if (m_AcceptedTypes != null && m_AcceptedTypes.Count() == 1)
{
return model.info.category;
}
else
{
return string.Format("{0}/{1}", type, model.info.category);
}
}
else
{
return type;
}
}
protected override IEnumerable<Descriptor> GetDescriptors()
{
IEnumerable<Descriptor> descs = Enumerable.Empty<Descriptor>();
if (m_AcceptedTypes == null || m_AcceptedTypes.Contains(typeof(VFXContext)))
{
var descriptorsContext = VFXLibrary.GetContexts().Select(o =>
{
return new Descriptor()
{
modelDescriptor = o,
category = ComputeCategory("Context", o),
name = o.name
};
}).OrderBy(o => o.category + o.name);
descs = descs.Concat(descriptorsContext);
}
if (m_AcceptedTypes == null || m_AcceptedTypes.Contains(typeof(VFXOperator)))
{
var descriptorsOperator = VFXLibrary.GetOperators().Select(o =>
{
return new Descriptor()
{
modelDescriptor = o,
category = ComputeCategory("Operator", o),
name = o.name
};
});
descriptorsOperator = descriptorsOperator.Concat(SubGraphCache.GetItems(typeof(VisualEffectSubgraphOperator)).Select(
t => new Descriptor()
{
modelDescriptor = t.path,
category = "Operator/" + t.category,
name = t.name
}
));
descs = descs.Concat(descriptorsOperator.OrderBy(o => o.category + o.name));
}
if (m_AcceptedTypes == null || m_AcceptedTypes.Contains(typeof(VFXParameter)))
{
var parameterDescriptors = m_Controller.parameterControllers.Select(t =>
new Descriptor
{
modelDescriptor = t,
category = string.IsNullOrEmpty(t.model.category) ? "Property" : string.Format("Property/{0}", t.model.category),
name = t.exposedName
}
).OrderBy(t => t.category);
descs = descs.Concat(parameterDescriptors);
}
if (m_AcceptedTypes == null)
{
AddTemplatesFromDirectory(VisualEffectAssetEditorUtility.templatePath, "System", ref descs);
if ((VFXResources.defaultResources.userTemplateDirectory.Length > 0) && System.IO.Directory.Exists(VFXResources.defaultResources.userTemplateDirectory))
AddTemplatesFromDirectory(VFXResources.defaultResources.userTemplateDirectory, "User Systems", ref descs);
}
var groupNodeDesc = new Descriptor()
{
modelDescriptor = new GroupNodeAdder(),
category = "Misc",
name = "Group Node"
};
descs = descs.Concat(Enumerable.Repeat(groupNodeDesc, 1));
if (m_Filter == null)
return descs;
else
return descs.Where(t => m_Filter(t));
}
protected void AddTemplatesFromDirectory(string directory, string menuCategory, ref IEnumerable<Descriptor> descriptors)
{
var subDirectories = System.IO.Directory.GetDirectories(directory);
Array.Sort(subDirectories, (x, y) => String.Compare(x, y, true));
foreach (var subDirectory in subDirectories)
AddTemplatesFromDirectory(subDirectory, subDirectory.Replace(directory, menuCategory), ref descriptors);
var discoveredTemplates = System.IO.Directory.GetFiles(directory).Where(t => Path.GetExtension(t) == VisualEffectResource.Extension).Select(t => t.Replace("\\", "/"));
var templateDescriptors = discoveredTemplates.Select(t => new Descriptor() { modelDescriptor = t, category = menuCategory.Replace("\\", "/"), name = ObjectNames.NicifyVariableName(System.IO.Path.GetFileNameWithoutExtension(t)) });
descriptors = descriptors.Concat(templateDescriptors);
}
}
}