浏览代码

[materialgraph] start removing old things.

/main
Tim Cooper 8 年前
当前提交
07060e1e
共有 9 个文件被更改,包括 0 次插入617 次删除
  1. 102
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/NodeUtils.cs
  2. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/NodeUtils.cs.meta
  3. 248
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs
  4. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs.meta
  5. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Edge.cs
  6. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Edge.cs.meta
  7. 44
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SlotReference.cs
  8. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SlotReference.cs.meta
  9. 153
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph.cs

102
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/NodeUtils.cs


using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
internal class NodeUtils
{
// GetSlotsThatOutputToNodeRecurse returns a list of output slots on from node that
// manage to connect to toNode... they may go via some other nodes to reach there.
// This is done by working backwards from the toNode to the fromNode as graph is one directional
public static List<SerializableSlot> GetSlotsThatOutputToNodeRecurse(SerializableNode fromNode, SerializableNode toNode)
{
var foundUsedOutputSlots = new List<SerializableSlot>();
RecurseNodesToFindValidOutputSlots(fromNode, toNode, foundUsedOutputSlots);
return foundUsedOutputSlots;
}
public static void RecurseNodesToFindValidOutputSlots(SerializableNode fromNode, SerializableNode currentNode, ICollection<SerializableSlot> foundUsedOutputSlots)
{
if (fromNode == null || currentNode == null)
{
Debug.LogError("Recursing to find valid inputs on NULL node");
return;
}
var validSlots = ListPool<SerializableSlot>.Get();
validSlots.AddRange(currentNode.inputSlots);
for (int index = 0; index < validSlots.Count; index++)
{
var inputSlot = validSlots[index];
var edges = currentNode.owner.GetEdges(inputSlot);
foreach (var edge in edges)
{
var outputNode = currentNode.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var outputSlot = outputNode.FindOutputSlot(edge.outputSlot.slotName);
if (outputNode == fromNode && !foundUsedOutputSlots.Contains(outputSlot))
foundUsedOutputSlots.Add(outputSlot);
else
RecurseNodesToFindValidOutputSlots(fromNode, outputNode, foundUsedOutputSlots);
}
}
ListPool<SerializableSlot>.Release(validSlots);
}
public static void CollectChildNodesByExecutionOrder(List<SerializableNode> nodeList, SerializableNode node, SerializableSlot slotToUse)
{
if (node == null)
return;
if (nodeList.Contains(node))
return;
var validSlots = ListPool<SerializableSlot>.Get();
validSlots.AddRange(node.inputSlots);
if (slotToUse != null && !validSlots.Contains(slotToUse))
{
ListPool<SerializableSlot>.Release(validSlots);
return;
}
if (slotToUse != null)
{
validSlots.Clear();
validSlots.Add(slotToUse);
}
for (int index = 0; index < validSlots.Count; index++)
{
var slot = validSlots[index];
var edges = node.owner.GetEdges(slot);
foreach (var edge in edges)
{
var outputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
CollectChildNodesByExecutionOrder(nodeList, outputNode, null);
}
}
nodeList.Add(node);
ListPool<SerializableSlot>.Release(validSlots);
}
public static void CollectDependentNodes(List<SerializableNode> nodeList, SerializableNode node)
{
if (node == null)
return;
if (nodeList.Contains(node))
return;
foreach (var slot in node.outputSlots)
{
foreach (var edge in node.owner.GetEdges(slot))
{
var inputNode = node.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
CollectDependentNodes(nodeList, inputNode);
}
}
nodeList.Add(node);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/NodeUtils.cs.meta


fileFormatVersion: 2
guid: 992a8f404953a8248b943cb6fb0b2c79
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

248
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public abstract class BaseMaterialGraph : ISerializationCallbackReceiver
{
[SerializeField]
private List<Edge> m_Edges = new List<Edge>();
[SerializeField]
private List<BaseMaterialNode> m_Nodes = new List<BaseMaterialNode>();
private PreviewRenderUtility m_PreviewUtility;
private MaterialGraph m_Owner;
public BaseMaterialGraph(MaterialGraph owner)
{
m_Owner = owner;
}
public IEnumerable<BaseMaterialNode> nodes { get { return m_Nodes; } }
public IEnumerable<Edge> edges { get { return m_Edges; } }
public PreviewRenderUtility previewUtility
{
get
{
if (m_PreviewUtility == null)
{
m_PreviewUtility = new PreviewRenderUtility();
// EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
}
return m_PreviewUtility;
}
}
public bool requiresRepaint
{
get { return m_Nodes.Any(x => x is IRequiresTime); }
}
public MaterialGraph owner
{
get { return m_Owner; }
}
public void RemoveEdge(Edge e)
{
m_Edges.Remove(e);
RevalidateGraph();
}
public void RemoveEdgeNoRevalidate(Edge e)
{
m_Edges.Remove(e);
}
public void RemoveNode(BaseMaterialNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
RevalidateGraph();
}
public void RemoveNodeNoRevalidate(BaseMaterialNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
}
public BaseMaterialNode GetNodeFromGUID(Guid guid)
{
return m_Nodes.FirstOrDefault(x => x.guid == guid);
}
public IEnumerable<Edge> GetEdges(Slot s)
{
return m_Edges.Where(x =>
(x.outputSlot.nodeGuid == s.owner.guid && x.outputSlot.slotName == s.name)
|| x.inputSlot.nodeGuid == s.owner.guid && x.inputSlot.slotName == s.name);
}
public Edge Connect(Slot fromSlot, Slot toSlot)
{
Slot outputSlot = null;
Slot inputSlot = null;
// output must connect to input
if (fromSlot.isOutputSlot)
outputSlot = fromSlot;
else if (fromSlot.isInputSlot)
inputSlot = fromSlot;
if (toSlot.isOutputSlot)
outputSlot = toSlot;
else if (toSlot.isInputSlot)
inputSlot = toSlot;
if (inputSlot == null || outputSlot == null)
return null;
var edges = GetEdges(inputSlot).ToList();
// remove any inputs that exits before adding
foreach (var edge in edges)
{
Debug.Log("Removing existing edge:" + edge);
// call base here as we DO NOT want to
// do expensive shader regeneration
RemoveEdge(edge);
}
var newEdge = new Edge(new SlotReference(outputSlot.owner.guid, outputSlot.name), new SlotReference(inputSlot.owner.guid, inputSlot.name));
m_Edges.Add(newEdge);
Debug.Log("Connected edge: " + newEdge);
RevalidateGraph();
return newEdge;
}
public virtual void RevalidateGraph()
{
//First validate edges, remove any
//orphans. This can happen if a user
//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
var allNodeGUIDs = m_Nodes.Select(x => x.guid).ToList();
foreach (var edge in edges.ToArray())
{
if (allNodeGUIDs.Contains(edge.inputSlot.nodeGuid) && allNodeGUIDs.Contains(edge.outputSlot.nodeGuid))
continue;
//orphaned edge
m_Edges.Remove(edge);
}
var bmns = m_Nodes.Where(x => x is BaseMaterialNode).ToList();
foreach (var node in bmns)
node.ValidateNode();
}
public void AddNode(BaseMaterialNode node)
{
m_Nodes.Add(node);
RevalidateGraph();
}
private void AddNodeNoValidate(BaseMaterialNode node)
{
m_Nodes.Add(node);
}
private static string GetTypeSerializableAsString(Type type)
{
if (type == null)
return string.Empty;
return string.Format("{0}, {1}", type.FullName, type.Assembly.GetName().Name);
}
private static Type GetTypeFromSerializedString(string type)
{
if (string.IsNullOrEmpty(type))
return null;
return Type.GetType(type);
}
[Serializable]
struct SerializableNode
{
[SerializeField]
public string typeName;
[SerializeField]
public string JSONnodeData;
}
[SerializeField]
List<SerializableNode> m_SerializableNodes = new List<SerializableNode>();
public void OnBeforeSerialize()
{
m_SerializableNodes.Clear();
foreach (var node in nodes)
{
if (node == null)
continue;
var typeName = GetTypeSerializableAsString(node.GetType());
var data = JsonUtility.ToJson(node, true);
if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(data))
continue;
m_SerializableNodes.Add( new SerializableNode()
{
typeName = typeName,
JSONnodeData = data
});
}
}
public void OnAfterDeserialize()
{
m_Nodes.Clear();
foreach (var serializedNode in m_SerializableNodes)
{
if (string.IsNullOrEmpty(serializedNode.typeName) || string.IsNullOrEmpty(serializedNode.JSONnodeData))
continue;
var type = GetTypeFromSerializedString(serializedNode.typeName);
if (type == null)
{
Debug.LogWarningFormat("Could not find node of type {0} in loaded assemblies", serializedNode.typeName);
continue;
}
BaseMaterialNode node;
try
{
var constructorInfo = type.GetConstructor(new[] { typeof(BaseMaterialGraph) });
node = (BaseMaterialNode)constructorInfo.Invoke(new object[] { this });
}
catch
{
Debug.LogWarningFormat("Could not construct instance of: {0} as there is no single argument constuctor that takes a BaseMaterialGraph", type);
continue;
}
JsonUtility.FromJsonOverwrite(serializedNode.JSONnodeData, node);
AddNodeNoValidate(node);
}
RevalidateGraph();
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs.meta


fileFormatVersion: 2
guid: 6567c9f37c0aaa94e9083ffc63612ecf
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Edge.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class Edge
{
[SerializeField]
private SlotReference m_OutputSlot;
[SerializeField]
private SlotReference m_InputSlot;
public Edge(SlotReference outputSlot, SlotReference inputSlot)
{
m_OutputSlot = outputSlot;
m_InputSlot = inputSlot;
}
public SlotReference outputSlot
{
get { return m_OutputSlot; }
}
public SlotReference inputSlot
{
get { return m_InputSlot; }
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Edge.cs.meta


fileFormatVersion: 2
guid: 6b610a05c25f54d4c90f7ebf82696481
timeCreated: 1463576280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

44
UnityProject/Assets/UnityShaderEditor/Editor/Source/SlotReference.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SlotReference : ISerializationCallbackReceiver
{
[SerializeField]
private string m_SlotName;
[NonSerialized]
private Guid m_NodeGUID;
[SerializeField]
private string m_NodeGUIDSerialized;
public SlotReference(Guid nodeGuid, string slotName)
{
m_NodeGUID = nodeGuid;
m_SlotName = slotName;
}
public Guid nodeGuid
{
get { return m_NodeGUID; }
}
public string slotName
{
get { return m_SlotName; }
}
public void OnBeforeSerialize()
{
m_NodeGUIDSerialized = m_NodeGUID.ToString();
}
public void OnAfterDeserialize()
{
m_NodeGUID = new Guid(m_NodeGUIDSerialized);
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SlotReference.cs.meta


fileFormatVersion: 2
guid: a178e14960be0e944b4652535f2d12e4
timeCreated: 1463576280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

153
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SerializableGraph : ISerializationCallbackReceiver
{
[SerializeField]
private List<Edge> m_Edges = new List<Edge>();
[NonSerialized]
private List<SerializableNode> m_Nodes = new List<SerializableNode>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
public IEnumerable<SerializableNode> nodes
{
get { return m_Nodes; }
}
public IEnumerable<Edge> edges
{
get { return m_Edges; }
}
public virtual void AddNode(SerializableNode node)
{
m_Nodes.Add(node);
ValidateGraph();
}
public virtual void RemoveNode(SerializableNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
ValidateGraph();
}
private void RemoveNodeNoValidate(SerializableNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
}
public virtual Edge Connect(SerializableSlot fromSlot, SerializableSlot toSlot)
{
SerializableSlot outputSlot = null;
SerializableSlot inputSlot = null;
// output must connect to input
if (fromSlot.isOutputSlot)
outputSlot = fromSlot;
else if (fromSlot.isInputSlot)
inputSlot = fromSlot;
if (toSlot.isOutputSlot)
outputSlot = toSlot;
else if (toSlot.isInputSlot)
inputSlot = toSlot;
if (inputSlot == null || outputSlot == null)
return null;
var edges = GetEdges(inputSlot).ToList();
// remove any inputs that exits before adding
foreach (var edge in edges)
{
Debug.Log("Removing existing edge:" + edge);
// call base here as we DO NOT want to
// do expensive shader regeneration
RemoveEdge(edge);
}
var newEdge = new Edge(new SlotReference(outputSlot.owner.guid, outputSlot.name), new SlotReference(inputSlot.owner.guid, inputSlot.name));
m_Edges.Add(newEdge);
Debug.Log("Connected edge: " + newEdge);
return newEdge;
}
public virtual void RemoveEdge(Edge e)
{
m_Edges.Remove(e);
ValidateGraph();
}
public void RemoveElements(IEnumerable<SerializableNode> nodes, IEnumerable<Edge> edges)
{
foreach (var edge in edges)
RemoveEdgeNoValidate(edge);
foreach (var serializableNode in nodes)
RemoveNodeNoValidate(serializableNode);
ValidateGraph();
}
private void RemoveEdgeNoValidate(Edge e)
{
m_Edges.Remove(e);
}
public SerializableNode GetNodeFromGuid(Guid guid)
{
return m_Nodes.FirstOrDefault(x => x.guid == guid);
}
public IEnumerable<Edge> GetEdges(SerializableSlot s)
{
return m_Edges.Where(x =>
(x.outputSlot.nodeGuid == s.owner.guid && x.outputSlot.slotName == s.name)
|| x.inputSlot.nodeGuid == s.owner.guid && x.inputSlot.slotName == s.name);
}
public virtual void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize(m_Nodes);
}
public virtual void OnAfterDeserialize()
{
m_Nodes = SerializationHelper.Deserialize<SerializableNode>(m_SerializableNodes, new object[] {this});
m_SerializableNodes = null;
}
public virtual void ValidateGraph()
{
//First validate edges, remove any
//orphans. This can happen if a user
//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
var allNodeGUIDs = nodes.Select(x => x.guid).ToList();
foreach (var edge in edges.ToArray())
{
if (allNodeGUIDs.Contains(edge.inputSlot.nodeGuid) && allNodeGUIDs.Contains(edge.outputSlot.nodeGuid))
continue;
//orphaned edge
RemoveEdgeNoValidate(edge);
}
}
}
}
正在加载...
取消
保存