247 lines
7.8 KiB
C#
247 lines
7.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor.VFX;
|
|
using UnityEngine.UIElements;
|
|
using System.Reflection;
|
|
using UnityObject = UnityEngine.Object;
|
|
using NodeID = System.UInt32;
|
|
|
|
namespace UnityEditor.VFX.UI
|
|
{
|
|
class VFXCopyPasteCommon
|
|
{
|
|
protected const NodeID TypeMask = 3u << 30;
|
|
protected const NodeID ParameterFlag = 1u << 30;
|
|
protected const NodeID ContextFlag = 2u << 30;
|
|
protected const NodeID OperatorFlag = 3u << 30;
|
|
protected const NodeID BlockFlag = 0u << 30;
|
|
protected const NodeID InvalidID = 0xFFFFFFFF;
|
|
|
|
//NodeID are 32 identifiers to any node that can be in a groupNode or have links
|
|
//The two high bits are use with the above flags to give the type.
|
|
// For operators and context all the 30 remaining bit are used as an index
|
|
// For blocks the high bits 2 to 13 are a block index in the context the 18 remaining bits are an index in the contexts
|
|
// For parameters the high bits 2 to 13 are a parameter node index the 18 remaining are an index in the parameters
|
|
// Therefore you can copy :
|
|
// Up to 2^30 operators
|
|
// Up to 2^30 contexts, but only the first 2^18 can have blocks with links
|
|
// Up to 2^30 parameters, but only the first 2^18 can have nodes with links
|
|
// Up to 2^11 block per context can have links
|
|
// Up to 2^11 parameter nodes per parameter can have links
|
|
// Note : 2^30 > 1 billion, 2^18 = 262144, 2^11 = 2048
|
|
|
|
|
|
[Serializable]
|
|
protected struct DataAnchor
|
|
{
|
|
public NodeID targetIndex;
|
|
public int[] slotPath;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct DataEdge
|
|
{
|
|
public DataAnchor input;
|
|
public DataAnchor output;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct FlowAnchor
|
|
{
|
|
public NodeID contextIndex;
|
|
public int flowIndex;
|
|
}
|
|
|
|
|
|
[Serializable]
|
|
protected struct FlowEdge
|
|
{
|
|
public FlowAnchor input;
|
|
public FlowAnchor output;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct Property
|
|
{
|
|
public string name;
|
|
public VFXCoordinateSpace space;
|
|
public VFXSerializableObject value;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct Node
|
|
{
|
|
public Vector2 position;
|
|
|
|
[Flags]
|
|
public enum Flags
|
|
{
|
|
Collapsed = 1 << 0,
|
|
SuperCollapsed = 1 << 1,
|
|
Enabled = 1 << 2
|
|
}
|
|
public Flags flags;
|
|
|
|
public SerializableType type;
|
|
public Property[] settings;
|
|
public Property[] inputSlots;
|
|
public string[] expandedInputs;
|
|
public string[] expandedOutputs;
|
|
public int indexInClipboard;
|
|
}
|
|
|
|
|
|
[Serializable]
|
|
protected struct Context
|
|
{
|
|
public Node node;
|
|
public int dataIndex;
|
|
public string label;
|
|
public Node[] blocks;
|
|
public SubOutput[] subOutputs;
|
|
public string systemName;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct SubOutput
|
|
{
|
|
public SerializableType type;
|
|
public Property[] settings;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct Data
|
|
{
|
|
public Property[] settings;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct ParameterNode
|
|
{
|
|
public Vector2 position;
|
|
public bool collapsed;
|
|
public string[] expandedOutput;
|
|
public int indexInClipboard;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct Parameter
|
|
{
|
|
public int originalInstanceID;
|
|
public string name;
|
|
public VFXSerializableObject value;
|
|
public bool exposed;
|
|
public VFXValueFilter valueFilter;
|
|
public VFXSerializableObject min;
|
|
public VFXSerializableObject max;
|
|
public string[] enumValue;
|
|
public string tooltip;
|
|
public bool isOutput;
|
|
public ParameterNode[] nodes;
|
|
}
|
|
|
|
[Serializable]
|
|
protected struct GroupNode
|
|
{
|
|
public VFXUI.UIInfo infos;
|
|
public NodeID[] contents;
|
|
public int stickNodeCount;
|
|
}
|
|
|
|
[Serializable]
|
|
protected class SerializableGraph
|
|
{
|
|
public Rect bounds;
|
|
|
|
public bool blocksOnly;
|
|
|
|
public Context[] contexts;
|
|
public Node[] operators; // this contains blocks if blocksOnly else it contains operators and blocks are included in their respective contexts
|
|
public Data[] datas;
|
|
|
|
public Parameter[] parameters;
|
|
|
|
public DataEdge[] dataEdges;
|
|
public FlowEdge[] flowEdges;
|
|
|
|
public VFXUI.StickyNoteInfo[] stickyNotes;
|
|
public GroupNode[] groupNodes;
|
|
|
|
public int controllerCount;
|
|
}
|
|
|
|
static Dictionary<Type, List<FieldInfo>> s_SerializableFieldByType = new Dictionary<Type, List<FieldInfo>>();
|
|
protected static List<FieldInfo> GetFields(Type type)
|
|
{
|
|
List<FieldInfo> fields = null;
|
|
if (!s_SerializableFieldByType.TryGetValue(type, out fields))
|
|
{
|
|
fields = new List<FieldInfo>();
|
|
while (type != typeof(VFXContext) && type != typeof(VFXOperator) && type != typeof(VFXBlock) && type != typeof(VFXData) && type != typeof(VFXSRPSubOutput))
|
|
{
|
|
var typeFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
|
|
|
|
foreach (var field in typeFields)
|
|
{
|
|
if (!field.IsPublic)
|
|
{
|
|
object[] attributes = field.GetCustomAttributes(true);
|
|
|
|
if (!attributes.Any(t => t is VFXSettingAttribute || t is SerializeField))
|
|
continue;
|
|
}
|
|
|
|
if (field.IsNotSerialized)
|
|
continue;
|
|
|
|
if (!field.FieldType.IsSerializable && !typeof(UnityObject).IsAssignableFrom(field.FieldType)) // Skip field that are not serializable except for UnityObject that are anyway
|
|
continue;
|
|
|
|
if (typeof(VFXModel).IsAssignableFrom(field.FieldType) || field.FieldType.IsGenericType && typeof(VFXModel).IsAssignableFrom(field.FieldType.GetGenericArguments()[0]))
|
|
continue;
|
|
|
|
fields.Add(field);
|
|
}
|
|
type = type.BaseType;
|
|
}
|
|
s_SerializableFieldByType[type] = fields;
|
|
}
|
|
|
|
return fields;
|
|
}
|
|
|
|
protected static IEnumerable<VFXSlot> AllSlots(IEnumerable<VFXSlot> slots)
|
|
{
|
|
foreach (var slot in slots)
|
|
{
|
|
yield return slot;
|
|
|
|
foreach (var child in AllSlots(slot.children))
|
|
{
|
|
yield return child;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected static NodeID GetBlockID(uint contextIndex, uint blockIndex)
|
|
{
|
|
if (contextIndex < (1 << 18) && blockIndex < (1 << 11))
|
|
{
|
|
return BlockFlag | (blockIndex << 18) | contextIndex;
|
|
}
|
|
return InvalidID;
|
|
}
|
|
|
|
protected static NodeID GetParameterNodeID(uint parameterIndex, uint nodeIndex)
|
|
{
|
|
if (parameterIndex < (1 << 18) && nodeIndex < (1 << 11))
|
|
{
|
|
return ParameterFlag | (nodeIndex << 18) | parameterIndex;
|
|
}
|
|
return InvalidID;
|
|
}
|
|
}
|
|
}
|