浏览代码

[material graph]Tidy slot reference usages + update tests.

/main
Tim Cooper 9 年前
当前提交
ed811c3c
共有 14 个文件被更改,包括 104 次插入79 次删除
  1. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
  2. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs
  3. 26
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs
  4. 13
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs
  5. 6
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function2Input.cs
  6. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs
  7. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
  8. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
  9. 6
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs
  10. 35
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs
  11. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs
  12. 13
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs
  13. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs
  14. 37
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs


pos.y = yStart;
foreach (var slot in node.materialOuputSlots)
{
var edges = node.owner.GetEdges(slot);
var edges = node.owner.GetEdges(new SlotReference(node.guid, slot.name));
// don't show empty output slots in collapsed mode
if (node.drawMode == DrawMode.Collapsed && !edges.Any())
continue;

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs


{
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor) x).m_Slot == slot);
var edges = baseNode.owner.GetEdges(slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.name));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);

public void Connect(NodeAnchor a, NodeAnchor b)
{
var pixelGraph = graph.currentGraph;
pixelGraph.Connect(a.m_Slot, b.m_Slot);
pixelGraph.Connect(a.m_Node.GetSlotReference(a.m_Slot.name), b.m_Node.GetSlotReference(b.m_Slot.name));
}
private string m_LastPath;

26
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs


public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandard"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialSlot(node, kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kMetallicSlotName, kMetallicSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kMetallicSlotName, kMetallicSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
// clear out slot names that do not match the slots
// we support

public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandardSpecular"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialSlot(node, kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kSpecularSlotName, kSpecularSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kEmissionSlotName, kEmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(node, kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSpecularSlotName, kSpecularSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kEmissionSlotName, kEmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
// clear out slot names that do not match the slots
// we support

13
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs


{
get { return slots.OfType<MaterialSlot>(); }
}
public IEnumerable<MaterialSlot> materialInputSlots
{
get { return inputSlots.OfType<MaterialSlot>(); }

foreach (var inputSlot in materialInputSlots)
{
var edges = owner.GetEdges(inputSlot);
var edges = owner.GetEdges(GetSlotReference(inputSlot.name));
if (edges.Any())
continue;

protected string GetSlotValue(MaterialSlot inputSlot, GenerationMode generationMode)
{
var edges = owner.GetEdges(inputSlot).ToArray();
var edges = owner.GetEdges(GetSlotReference(inputSlot.name)).ToArray();
if (edges.Length > 0)
{

// so do that here
foreach (var inputSlot in inputSlots)
{
var edges = owner.GetEdges(inputSlot);
var edges = owner.GetEdges(GetSlotReference(inputSlot.name));
foreach (var edge in edges)
{
var fromSocketRef = edge.outputSlot;

{
var inputType = inputSlot.valueType;
// if there is a connection
var edges = owner.GetEdges(inputSlot).ToList();
var edges = owner.GetEdges(GetSlotReference(inputSlot.name)).ToList();
if (!edges.Any())
{
if (inputType != SlotValueType.Dynamic)

public virtual IEnumerable<MaterialSlot> GetDrawableInputProxies()
{
return materialInputSlots.Where(x => !owner.GetEdges(x).Any());
return materialInputSlots.Where(x => !owner.GetEdges(GetSlotReference(x.name)).Any());
}
public void ExecuteRepaint()

for (var index = 0; index < validSlots.Length; index++)
{
var s = validSlots[index];
var edges = owner.GetEdges(s);
var edges = owner.GetEdges(GetSlotReference(s.name));
if (edges.Any())
continue;

6
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function2Input.cs


protected MaterialSlot GetInputSlot1()
{
return new MaterialSlot(this, GetInputSlot1Name(), GetInputSlot1Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetInputSlot1Name(), GetInputSlot1Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(this, GetInputSlot2Name(), GetInputSlot2Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetInputSlot2Name(), GetInputSlot2Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(this, GetOutputSlotName(), GetOutputSlotName(), SlotType.Output, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetOutputSlotName(), GetOutputSlotName(), SlotType.Output, SlotValueType.Dynamic, Vector4.zero);
}
protected virtual string GetInputSlot1Name()

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs


[SerializeField]
private ConcreteSlotValueType m_ConcreteValueType;
public MaterialSlot(AbstractMaterialNode owner, string name, string displayName, SlotType slotType, SlotValueType valueType, Vector4 defaultValue)
: base(owner, name, displayName, slotType)
public MaterialSlot(string name, string displayName, SlotType slotType, SlotValueType valueType, Vector4 defaultValue)
: base(name, displayName, slotType)
public MaterialSlot (AbstractMaterialNode owner) : base (owner)
{ }
public Vector4 defaultValue
{
get { return m_DefaultValue; }

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs


(node as IGeneratesBodyCode).GenerateNodeCode(shaderBody, generationMode);
}
foreach (var edge in owner.GetEdges(firstPassSlot))
foreach (var edge in owner.GetEdges(GetSlotReference(firstPassSlot.name)))
{
var outputRef = edge.outputSlot;
var fromNode = materialGraphOwner.GetMaterialNodeFromGuid(outputRef.nodeGuid);

if (slot == firstPassSlot)
continue;
foreach (var edge in owner.GetEdges(slot))
foreach (var edge in owner.GetEdges(GetSlotReference(slot.name)))
{
var outputRef = edge.outputSlot;
var fromNode = materialGraphOwner.GetMaterialNodeFromGuid(outputRef.nodeGuid);

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs


private void InternalValidate()
{
AddSlot(new MaterialSlot(this, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
}
private const string kOutputSlotName = "Value";

6
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs


for (int index = 0; index < validSlots.Count; index++)
{
var inputSlot = validSlots[index];
var edges = currentNode.owner.GetEdges(inputSlot);
var edges = currentNode.owner.GetEdges(currentNode.GetSlotReference(inputSlot.name));
foreach (var edge in edges)
{
var outputNode = currentNode.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);

{
var slot = validSlots[index];
var edges = node.owner.GetEdges(slot);
var edges = node.owner.GetEdges(node.GetSlotReference(slot.name));
foreach (var edge in edges)
{
var outputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);

foreach (var slot in node.outputSlots)
{
foreach (var edge in node.owner.GetEdges(slot))
foreach (var edge in node.owner.GetEdges(node.GetSlotReference(slot.name)))
{
var inputNode = node.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
CollectDependentNodes(nodeList, inputNode);

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


m_Nodes.Remove(node);
}
public virtual Edge Connect(SerializableSlot fromSlot, SerializableSlot toSlot)
public virtual Edge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
SerializableSlot outputSlot = null;
SerializableSlot inputSlot = null;
SerializableNode fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid);
SerializableNode toNode = GetNodeFromGuid(toSlotRef.nodeGuid);
if (fromNode == null || toNode == null)
return null;
SerializableSlot fromSlot = fromNode.FindSlot(fromSlotRef.slotName);
SerializableSlot toSlot = toNode.FindSlot(toSlotRef.slotName);
SlotReference outputSlot = null;
SlotReference inputSlot = null;
outputSlot = fromSlot;
outputSlot = fromSlotRef;
inputSlot = fromSlot;
inputSlot = fromSlotRef;
outputSlot = toSlot;
outputSlot = toSlotRef;
inputSlot = toSlot;
inputSlot = toSlotRef;
var edges = GetEdges(inputSlot).ToList();
var slotEdges = GetEdges(inputSlot).ToList();
foreach (var edge in edges)
foreach (var edge in slotEdges)
{
Debug.Log("Removing existing edge:" + edge);
// call base here as we DO NOT want to

var newEdge = new Edge(new SlotReference(outputSlot.owner.guid, outputSlot.name), new SlotReference(inputSlot.owner.guid, inputSlot.name));
var newEdge = new Edge(outputSlot, inputSlot);
m_Edges.Add(newEdge);
Debug.Log("Connected edge: " + newEdge);

return m_Nodes.FirstOrDefault(x => x.guid == guid);
}
public IEnumerable<Edge> GetEdges(SerializableSlot s)
public IEnumerable<Edge> GetEdges(SlotReference s)
(x.outputSlot.nodeGuid == s.owner.guid && x.outputSlot.slotName == s.name)
|| x.inputSlot.nodeGuid == s.owner.guid && x.inputSlot.slotName == s.name);
(x.outputSlot.nodeGuid == s.nodeGuid && x.outputSlot.slotName == s.slotName)
|| x.inputSlot.nodeGuid == s.nodeGuid && x.inputSlot.slotName == s.slotName);
}
public virtual void OnBeforeSerialize()

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs


}
}
public SlotReference GetSlotReference(string name)
{
return new SlotReference(guid, name);
}
public SerializableSlot FindSlot(string name)
{
var slot = slots.FirstOrDefault(x => x.name == name);
if (slot == null)
Debug.LogErrorFormat("Input Slot: {0} could be found on node {1}", name, this);
return slot;
}
public SerializableSlot FindInputSlot(string name)
{
var slot = inputSlots.FirstOrDefault(x => x.name == name);

var modified = false;
foreach (var slot in inputSlots)
{
if (!owner.GetEdges(slot).Any())
if (!owner.GetEdges(GetSlotReference(slot.name)).Any())
modified |= DoSlotUI(this, slot);
}

13
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs


[SerializeField]
private SlotType m_SlotType;
public SerializableNode owner { get; set; }
public string name
{
get { return m_Name; }

get { return m_SlotType == SlotType.Output; }
}
public SerializableSlot(SerializableNode theOwner, string name, string displayName, SlotType slotType)
public SerializableSlot(string name, string displayName, SlotType slotType)
owner = theOwner;
m_Name = name;
m_DisplayName = displayName;
m_SlotType = slotType;

// to reconstruct this slot.
protected SerializableSlot(SerializableNode theOwner)
{
owner = theOwner;
}
protected SerializableSlot()
{}
public virtual bool OnGUI()
{

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


[SerializeField]
private string m_NodeGUIDSerialized;
m_NodeGUIDSerialized = string.Empty;
}
public static SerializableSlot ToSerializableSlot(SerializableGraph graph, SlotReference slotRef)
{
var node = graph.GetNodeFromGuid(slotRef.nodeGuid);
if (node == null)
return null;
return node.FindSlot(slotRef.slotName);
}
public Guid nodeGuid

37
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs


{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot(node, "input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
node.name = "Test Node";
graph.AddNode(node);

Assert.AreEqual("input", found.outputSlots.FirstOrDefault().name);
Assert.AreEqual("input", found.inputSlots.FirstOrDefault().name);
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual("output", found.outputSlots.FirstOrDefault().name);
Assert.AreEqual(2, found.slots.Count());

{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.name = "Test Node";
graph.AddNode(node);

{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot(node, "output", "output_updated", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output_updated", SlotType.Output));
node.name = "Test Node";
graph.AddNode(node);

public void TestCanFindSlotOnSerializableNode()
{
var node = new SerializableNode(null);
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot(node, "input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
Assert.AreEqual(2, node.slots.Count());
Assert.IsNotNull(node.FindInputSlot("input"));

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot(outputNode, "output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var inputSlot = new SerializableSlot(inputNode, "input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var createdEdge = graph.Connect(outputNode.FindOutputSlot("output"), inputNode.FindInputSlot("input"));
var createdEdge = graph.Connect(outputNode.GetSlotReference("output"), inputNode.GetSlotReference("input"));
Assert.AreEqual(1, graph.edges.Count());
var edge = graph.edges.FirstOrDefault();

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot(outputNode, "output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot2 = new SerializableSlot(outputNode2, "output", "output", SlotType.Output);
var outputSlot2 = new SerializableSlot("output", "output", SlotType.Output);
var createdEdge = graph.Connect(outputNode.FindOutputSlot("output"), outputNode2.FindOutputSlot("output"));
var createdEdge = graph.Connect(outputNode.GetSlotReference("output"), outputNode2.GetSlotReference("output"));
Assert.IsNull(createdEdge);
Assert.AreEqual(0, graph.edges.Count());
}

{
var graph = new SerializableGraph();
var inputNode = new SerializableNode(graph);
var inputSlot = new SerializableSlot(inputNode, "input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot2 = new SerializableSlot(inputNode2, "input", "input", SlotType.Input);
var inputSlot2 = new SerializableSlot("input", "input", SlotType.Input);
var createdEdge = graph.Connect(inputNode.FindInputSlot("input"), inputNode.FindInputSlot("input"));
var createdEdge = graph.Connect(inputNode.GetSlotReference("input"), inputNode2.GetSlotReference("input"));
Assert.IsNull(createdEdge);
Assert.AreEqual(0, graph.edges.Count());
}

正在加载...
取消
保存