浏览代码

[Material Graph] change nodes property to GetNodes<T> where you can get nodes of a given type

Remove redundent code
Set node when adding to graph (do not set owner manually)
Tidy up tests after changes.
/main
Tim Cooper 8 年前
当前提交
0dd596bf
共有 59 个文件被更改,包括 178 次插入230 次删除
  1. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs
  2. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphDataSource.cs
  3. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  4. 151
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs
  5. 19
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  6. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  7. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IGraph.cs
  8. 57
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs
  9. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/MaterialGraphTests.cs
  10. 35
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  11. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs
  12. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraphAsset.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/PixelGraph.cs
  14. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbsoluteNode.cs
  15. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  16. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AddNode.cs
  17. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/BlendNode.cs
  18. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ClampNode.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ColorNode.cs
  20. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/CombineNode.cs
  21. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/DivNode.cs
  22. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/DotNode.cs
  23. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/FresnelNode.cs
  24. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs
  25. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs
  26. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs
  27. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/LengthNode.cs
  28. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/LerpNode.cs
  29. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaxNode.cs
  30. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MinNode.cs
  31. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MultiplyNode.cs
  32. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs
  33. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalizeNode.cs
  34. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs
  35. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PowerNode.cs
  36. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs
  37. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/QuantizeNode.cs
  38. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ReflectNode.cs
  39. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs
  40. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinNode.cs
  41. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinTimeNode.cs
  42. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SmoothStepNode.cs
  43. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SubtractNode.cs
  44. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SwizzleNode.cs
  45. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  46. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TimeNode.cs
  47. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs
  48. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UnpackNormalNode.cs
  49. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector1Node.cs
  50. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector2Node.cs
  51. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector3Node.cs
  52. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector4Node.cs
  53. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs
  54. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs
  55. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphIONode.cs
  56. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs
  57. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs
  58. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  59. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs


{
var childrenNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childrenNodes, m_Node);
if (childrenNodes.Any(x => x is IRequiresTime))
if (childrenNodes.OfType<IRequiresTime>().Any())
Invalidate();
ListPool<INode>.Release(childrenNodes);
return true;

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphDataSource.cs


m_DrawableNodes.Clear();
var graph = graphAsset.graph;
Debug.LogFormat("Trying to convert: {0}", graphAsset.graph);
foreach (var node in graph.nodes)
foreach (var node in graph.GetNodes<INode>())
{
var nodeType = node.GetType();
Type draweruiType = null;

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs


INode node;
try
{
node = Activator.CreateInstance(posObj.m_Type, m_LastSelection.graph) as INode;
node = Activator.CreateInstance(posObj.m_Type) as INode;
}
catch
{

151
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs


var graph = new SerializableGraph();
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(0, graph.nodes.Count());
Assert.AreEqual(0, graph.GetNodes<INode>().Count());
}
[Test]

var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual("Test Node", graph.nodes.FirstOrDefault().name);
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
Assert.AreEqual("Test Node", graph.GetNodes<INode>().FirstOrDefault().name);
Assert.AreEqual(graph, node.owner);
}
[Test]

var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
graph.RemoveNode(graph.nodes.FirstOrDefault());
Assert.AreEqual(0, graph.nodes.Count());
graph.RemoveNode(graph.GetNodes<INode>().FirstOrDefault());
Assert.AreEqual(0, graph.GetNodes<INode>().Count());
private class NoDeleteNode : SerializableNode
[Test]
public void TestRemoveNodeFromSerializableGraphCleansEdges()
public NoDeleteNode(SerializableGraph theOwner) : base(theOwner)
{}
var graph = new SerializableGraph();
var outputNode = new SerializableNode();
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
outputNode.AddSlot(outputSlot);
graph.AddNode(outputNode);
var inputNode = new SerializableNode();
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
var createdEdge = graph.Connect(outputNode.GetSlotReference("output"), inputNode.GetSlotReference("input"));
Assert.AreEqual(1, graph.edges.Count());
var edge = graph.edges.FirstOrDefault();
Assert.AreEqual(createdEdge, edge);
graph.RemoveNode(outputNode);
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(inputNode, graph.GetNodes<INode>().FirstOrDefault());
}
private class NoDeleteNode : SerializableNode
{
public override bool canDeleteNode { get { return false; } }
}

var graph = new SerializableGraph();
var node = new NoDeleteNode(graph);
var node = new NoDeleteNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
graph.RemoveNode(graph.nodes.FirstOrDefault());
Assert.AreEqual(1, graph.nodes.Count());
graph.RemoveNode(graph.GetNodes<INode>().FirstOrDefault());
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
}
[Test]

var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
Assert.IsNotNull(graph.GetNodeFromGuid(node.guid));
Assert.IsNull(graph.GetNodeFromGuid(Guid.NewGuid()));
}

{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(1, found.inputSlots.Count());
Assert.AreEqual("input", found.inputSlots.FirstOrDefault().name);
Assert.AreEqual(1, found.outputSlots.Count());

[Test]
public void TestCanRemoveSlotFromSerializableNode()
{
var node = new SerializableNode(null);
var node = new SerializableNode();
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));

[Test]
public void TestCanRemoveSlotsWithNonMathingNameFromSerializableNode()
{
var node = new SerializableNode(null);
var node = new SerializableNode();
node.AddSlot(new SerializableSlot("input1", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input2", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input3", "input", SlotType.Input, 0));

public void TestCanNotAddDuplicateSlotToSerializableNode()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());

public void TestCanUpdateDisplaynameByReaddingSlotToSerializableNode()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());

public void TestCanUpdatePriorityByReaddingSlotToSerializableNode()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());

[Test]
public void TestCanFindSlotOnSerializableNode()
{
var node = new SerializableNode(null);
var node = new SerializableNode();
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));

[Test]
public void TestCanFindSlotReferenceOnSerializableNode()
{
var node = new SerializableNode(null);
var node = new SerializableNode();
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));

public void TestCanConnectAndTraverseTwoNodesOnSerializableGraph()
{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
var createdEdge = graph.Connect(outputNode.GetSlotReference("output"), inputNode.GetSlotReference("input"));

public void TestCanNotConnectTwoOuputSlotsOnSerializableGraph()
{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var outputNode2 = new SerializableNode(graph);
var outputNode2 = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
var createdEdge = graph.Connect(outputNode.GetSlotReference("output"), outputNode2.GetSlotReference("output"));
Assert.IsNull(createdEdge);

public void TestCanNotConnectTwoInputSlotsOnSerializableGraph()
{
var graph = new SerializableGraph();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
var inputNode2 = new SerializableNode(graph);
var inputNode2 = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
var createdEdge = graph.Connect(inputNode.GetSlotReference("input"), inputNode2.GetSlotReference("input"));
Assert.IsNull(createdEdge);

public void TestRemovingNodeRemovesConectedEdgesOnSerializableGraph()
{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
graph.RemoveNode(graph.nodes.FirstOrDefault());
Assert.AreEqual(1, graph.nodes.Count());
graph.RemoveNode(graph.GetNodes<INode>().FirstOrDefault());
Assert.AreEqual(1, graph.GetNodes<INode>().Count());
Assert.AreEqual(0, graph.edges.Count());
}

var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
Assert.AreEqual(0, graph.edges.Count());
}

var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
graph.RemoveElements(graph.nodes, graph.edges);
Assert.AreEqual(0, graph.nodes.Count());
graph.RemoveElements(graph.GetNodes<INode>(), graph.edges);
Assert.AreEqual(0, graph.GetNodes<INode>().Count());
Assert.AreEqual(0, graph.edges.Count());
}

var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
graph.Connect(outputNode.GetSlotReference("output"), inputNode.GetSlotReference("input"));
Assert.AreEqual(1, graph.edges.Count());

public void TestGetInputsWithNoConnection()
{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputNode = new SerializableNode();
var inputNode = new SerializableNode(graph);
var inputNode = new SerializableNode();
Assert.AreEqual(2, graph.nodes.Count());
Assert.AreEqual(2, graph.GetNodes<INode>().Count());
graph.Connect(outputNode.GetSlotReference("output"), inputNode.GetSlotReference("input"));
Assert.AreEqual(1, graph.edges.Count());

19
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs


[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
public IEnumerable<INode> nodes
public IEnumerable<T> GetNodes<T>() where T : INode
get { return m_Nodes; }
return m_Nodes.OfType<T>();
}
public IEnumerable<IEdge> edges

public virtual void AddNode(INode node)
{
m_Nodes.Add(node);
node.owner = this;
ValidateGraph();
}

public virtual void OnAfterDeserialize()
{
m_Nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, new object[] { this });
m_Nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, new object[] {});
foreach (var node in m_Nodes)
node.owner = this;
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, new object[] { });
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, new object[] {});
m_SerializableEdges = null;
ValidateGraph();

}
}
foreach (var node in nodes)
foreach (var node in GetNodes<INode>())
}
public virtual bool RequiresConstantRepaint()
{
return false;
}
}
}

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs


get { return m_Slots; }
}
public SerializableNode(IGraph theOwner)
public SerializableNode()
owner = theOwner;
m_Guid = Guid.NewGuid();
}

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IGraph.cs


{
public interface IGraph
{
IEnumerable<INode> nodes { get; }
IEnumerable<T> GetNodes<T>() where T : INode;
IEnumerable<IEdge> edges { get; }
void AddNode(INode node);
void RemoveNode(INode node);

57
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs


{}
private class TestableMNode : AbstractMaterialNode
{
public TestableMNode(AbstractMaterialGraph theOwner) : base(theOwner)
{}
}
private class TimeTestableMNode : AbstractMaterialNode, IRequiresTime
{
public TimeTestableMNode(AbstractMaterialGraph theOwner) : base(theOwner)
{}
}
{}
[Test]
public void TestCanCreateMaterialGraph()

Assert.AreEqual(0, graph.nodes.Count());
Assert.AreEqual(0, graph.GetNodes<AbstractMaterialNode>().Count());
}
[Test]

var node = new TestableMNode(graph);
var node = new TestableMNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.materialNodes.Count());
Assert.AreEqual(1, graph.GetNodes<AbstractMaterialNode>().Count());
}
[Test]

var node = new SerializableNode(graph);
var node = new SerializableNode();
Assert.AreEqual(0, graph.nodes.Count());
Assert.AreEqual(0, graph.materialNodes.Count());
Assert.AreEqual(0, graph.GetNodes<AbstractMaterialNode>().Count());
}
[Test]

var node = new TestableMNode(graph);
var node = new TestableMNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<AbstractMaterialNode>().Count());
Assert.AreEqual(node, graph.GetNodeFromGuid(node.guid));
Assert.AreEqual(node, graph.GetNodeFromGuid<TestableMNode>(node.guid));

public void TestMaterialGraphNeedsRepaintWhenTimeNodePresent()
{
TestableMGraph graph = new TestableMGraph();
graph.AddNode(new TestableMNode(graph));
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(1, graph.nodes.Count());
Assert.IsFalse(graph.requiresRepaint);
graph.AddNode(new TimeTestableMNode(graph));
Assert.IsTrue(graph.requiresRepaint);
}
[Test]
Assert.AreEqual(0, graph.nodes.Count());
Assert.AreEqual(0, graph.GetNodes<AbstractMaterialNode>().Count());
var psn = new PixelShaderNode(graph);
var psn = new PixelShaderNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.IsInstanceOf(typeof(PixelShaderNode), graph.nodes.FirstOrDefault());
Assert.AreEqual(1, graph.GetNodes<AbstractMaterialNode>().Count());
Assert.IsInstanceOf(typeof(PixelShaderNode), graph.GetNodes<AbstractMaterialNode>().FirstOrDefault());
Assert.IsNotNull(graph.pixelMasterNode);
Assert.AreEqual(1, graph.activeNodes.Count());
}

{
var graph = new PixelGraph();
Assert.AreEqual(0, graph.nodes.Count());
Assert.AreEqual(0, graph.GetNodes<AbstractMaterialNode>().Count());
var psn = new PixelShaderNode(graph);
var psn = new PixelShaderNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<AbstractMaterialNode>().Count());
var psn2 = new PixelShaderNode(graph);
var psn2 = new PixelShaderNode();
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual(1, graph.GetNodes<AbstractMaterialNode>().Count());
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/MaterialGraphTests.cs


[Test]
public void TestCreateMaterialGraph()
{
UnityEngine.MaterialGraph.MaterialGraph graph = new UnityEngine.MaterialGraph.MaterialGraph();
var graph = new UnityEngine.MaterialGraph.MaterialGraph();
Assert.IsNotNull(graph.currentGraph);
Assert.IsNotNull(graph.materialOptions);

Assert.AreEqual(1, graph.currentGraph.nodes.Count());
Assert.IsInstanceOf(typeof(PixelShaderNode), graph.currentGraph.nodes.FirstOrDefault());
Assert.AreEqual(1, graph.currentGraph.GetNodes<AbstractMaterialNode>().Count());
Assert.IsInstanceOf(typeof(PixelShaderNode), graph.currentGraph.GetNodes<AbstractMaterialNode>().FirstOrDefault());
}
}
}

35
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph

{
public IEnumerable<AbstractMaterialNode> materialNodes
{
get { return nodes.OfType<AbstractMaterialNode>(); }
}
public bool requiresRepaint
{
get { return nodes.Any(x => x is IRequiresTime); }
}
public override void AddNode(INode node)
{
if (node is AbstractMaterialNode)

Debug.LogWarningFormat("Trying to add node {0} to Material graph, but it is not a {1}", node, typeof(AbstractMaterialNode));
}
}
public override bool RequiresConstantRepaint()
{
return nodes.OfType<IRequiresTime>().Any();
}
/*public PreviewRenderUtility previewUtility
{
get
{
if (m_PreviewUtility == null)
{
m_PreviewUtility = new PreviewRenderUtility();
EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
}
return m_PreviewUtility;
}
}
[NonSerialized]
private PreviewRenderUtility m_PreviewUtility;*/
}
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace UnityEngine.MaterialGraph
{

public void PostCreate()
{
m_PixelGraph.AddNode(new PixelShaderNode(m_PixelGraph));
m_PixelGraph.AddNode(new PixelShaderNode());
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraphAsset.cs


public bool shouldRepaint
{
get { return graph.nodes.OfType<IRequiresTime>().Any(); }
get { return graph.GetNodes<AbstractMaterialNode>().OfType<IRequiresTime>().Any(); }
}
public ScriptableObject GetScriptableObject()

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/PixelGraph.cs


{
// find existing node
if (m_PixelMasterNode == null)
m_PixelMasterNode = nodes.FirstOrDefault(x => x.GetType() == typeof(PixelShaderNode)) as PixelShaderNode;
m_PixelMasterNode = GetNodes<AbstractMaterialNode>().FirstOrDefault(x => x.GetType() == typeof(PixelShaderNode)) as PixelShaderNode;
return m_PixelMasterNode;
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbsoluteNode.cs


[Title("Math/Absolute Node")]
class AbsoluteNode : Function1Input, IGeneratesFunction
{
public AbsoluteNode(IGraph owner) : base(owner)
public AbsoluteNode()
{
name = "AbsoluteNode";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs


get { return outputSlots.OfType<MaterialSlot>(); }
}
protected AbstractMaterialNode(IGraph theOwner) : base(theOwner)
protected AbstractMaterialNode()
{
version = 0;
}

return null;
}
private ConcreteSlotValueType FindCommonChannelType(ConcreteSlotValueType @from, ConcreteSlotValueType to)
private ConcreteSlotValueType FindCommonChannelType(ConcreteSlotValueType from, ConcreteSlotValueType to)
if (ImplicitConversionExists(@from, to))
if (ImplicitConversionExists(from, to))
return to;
return ConcreteSlotValueType.Error;

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AddNode.cs


[Title("Math/Add Node")]
public class AddNode : Function2Input, IGeneratesFunction
{
public AddNode(IGraph owner)
: base(owner)
public AddNode()
{
name = "AddNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/BlendNode.cs


[Title("Art/Blend Node")]
public class BlendNode : Function2Input, IGeneratesFunction
{
public BlendNode(IGraph owner) : base(owner)
public BlendNode()
{
name = "BlendNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ClampNode.cs


[Title("Math/Clamp Node")]
public class ClampNode : Function3Input, IGeneratesFunction
{
public ClampNode(IGraph owner) : base(owner)
public ClampNode()
{
name = "ClampNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ColorNode.cs


private const string kOutputSlotName = "Color";
public ColorNode(IGraph owner) : base(owner)
public ColorNode()
{
name = "ColorNode";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/CombineNode.cs


[Title("Art/Combine Node")]
public class CombineNode : Function2Input, IGeneratesFunction
{
public CombineNode(IGraph owner) : base(owner)
public CombineNode()
{
name = "CombineNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/DivNode.cs


[Title("Math/Div Node")]
public class DivNode : Function2Input, IGeneratesFunction
{
public DivNode(IGraph owner) : base(owner)
public DivNode()
{
name = "DivNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/DotNode.cs


[Title("Math/Dot Node")]
public class DotNode : Function2Input
{
public DotNode(IGraph owner) : base(owner)
public DotNode()
{
name = "DotNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/FresnelNode.cs


[Title("Math/Fresnel Node")]
class FresnelNode : Function2Input, IGeneratesFunction
{
public FresnelNode(IGraph owner) : base(owner)
public FresnelNode()
{
name = "FresnelNode";
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs


get { return true; }
}
protected Function1Input(IGraph owner)
: base(owner)
protected Function1Input()
{
UpdateNodeAfterDeserialization();
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs


get { return true; }
}
protected Function2Input(IGraph owner)
: base(owner)
protected Function2Input()
{
UpdateNodeAfterDeserialization();
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs


get { return true; }
}
protected Function3Input(IGraph owner)
: base(owner)
protected Function3Input()
{
UpdateNodeAfterDeserialization();
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/LengthNode.cs


[Title("Math/Length Node")]
public class LengthNode : Function1Input
{
public LengthNode(IGraph owner) : base(owner)
public LengthNode()
{
name = "LengthNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/LerpNode.cs


[Title("Math/Lerp Node")]
public class LerpNode : Function3Input, IGeneratesFunction
{
public LerpNode(IGraph owner) : base(owner)
public LerpNode()
{
name = "LerpNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaxNode.cs


[Title("Math/Maximum Node")]
public class MaximumNode : Function2Input
{
public MaximumNode(IGraph owner) : base(owner)
public MaximumNode()
{
name = "MaximumNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MinNode.cs


[Title("Math/Minimum Node")]
public class MinimumNode : Function2Input
{
public MinimumNode(IGraph owner) : base(owner)
public MinimumNode()
{
name = "MinimumNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MultiplyNode.cs


[Title("Math/Multiply Node")]
public class MultiplyNode : Function2Input, IGeneratesFunction
{
public MultiplyNode(IGraph owner) : base(owner)
public MultiplyNode()
{
name = "MultiplyNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs


[Title("Input/Normal Node")]
public class NormalNode : AbstractMaterialNode
{
public NormalNode(IGraph theOwner) : base(theOwner)
public NormalNode()
{
name = "Normal";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalizeNode.cs


[Title("Math/Normalize Node")]
class NormalizeNode : Function1Input
{
public NormalizeNode(IGraph owner) : base(owner)
public NormalizeNode()
{
name = "NormalizeNode";
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs


private static List<BaseLightFunction> s_LightFunctions;
public PixelShaderNode(IGraph owner)
: base(owner)
public PixelShaderNode()
{
name = "PixelMaster";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PowerNode.cs


[Title("Math/Power Node")]
public class PowerNode : Function2Input
{
public PowerNode(IGraph owner) : base(owner)
public PowerNode()
{
name = "PowerNode";
}

9
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs


[SerializeField]
public bool m_Exposed;
protected PropertyNode(IGraph owner) : base(owner)
{}
public bool exposed
{
get { return m_Exposed; }

if (!exposed)
return false;
var allNodes = owner.nodes;
foreach (var n in allNodes.OfType<PropertyNode>())
var propNodes = owner.GetNodes<PropertyNode>();
foreach (var n in propNodes)
{
if (n == this)
continue;;

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/QuantizeNode.cs


[Title("Math/Quantize Node")]
class QuantizeNode : Function2Input, IGeneratesFunction
{
public QuantizeNode(IGraph owner) : base(owner)
public QuantizeNode()
{
name = "QuantizeNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ReflectNode.cs


[Title("Math/Reflect Node")]
class ReflectNode : Function2Input, IGeneratesFunction
{
public ReflectNode(IGraph owner) : base(owner)
public ReflectNode()
{
name = "ReflectNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs


[Title("Input/Screen Pos Node")]
public class ScreenPosNode : AbstractMaterialNode, IGeneratesVertexToFragmentBlock
{
public ScreenPosNode(IGraph theOwner) : base(theOwner)
public ScreenPosNode()
{
name = "ScreenPos";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinNode.cs


[Title("Math/Sin Node")]
class SinNode : Function1Input
{
public SinNode(IGraph owner) : base(owner)
public SinNode()
{
name = "SinNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinTimeNode.cs


[Title("Input/Sine Time Node")]
public class SinTimeNode : AbstractMaterialNode, IRequiresTime
{
public SinTimeNode(IGraph theOwner) : base(theOwner)
public SinTimeNode()
{
name = "Sine Time";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SmoothStepNode.cs


[Title("Math/SmoothStep Node")]
class SmoothStepNode : Function3Input, IGeneratesFunction
{
public SmoothStepNode(IGraph owner) : base(owner)
public SmoothStepNode()
{
name = "SmoothStepNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SubtractNode.cs


[Title("Math/Subtract Node")]
class SubtractNode : Function2Input, IGeneratesFunction
{
public SubtractNode(IGraph owner) : base(owner)
public SubtractNode()
{
name = "SubtractNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SwizzleNode.cs


[SerializeField]
private int[] m_SwizzleChannel = new int[4];
public SwizzleNode(IGraph owner) : base(owner)
public SwizzleNode()
{
name = "SwizzleNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs


set { m_TextureType = value; }
}
public TextureNode(IGraph owner) : base(owner)
public TextureNode()
{
name = "Texture";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TimeNode.cs


private const string kOutputSlotNameZ = "Time.z";
private const string kOutputSlotNameW = "Time.w";
public TimeNode(IGraph theOwner) : base(theOwner)
public TimeNode()
{
name = "Time";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs


public override bool hasPreview { get { return true; } }
public UVNode(IGraph theOwner) : base(theOwner)
public UVNode()
{
name = "UV";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UnpackNormalNode.cs


[Title("Channels/Unpack Normal Node")]
internal class UnpackNormalNode : Function1Input
{
public UnpackNormalNode(IGraph owner) : base(owner)
public UnpackNormalNode()
{
name = "UnpackNormalNode";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector1Node.cs


private const string kOutputSlotName = "Value";
public Vector1Node(IGraph owner) : base(owner)
public Vector1Node()
{
name = "V1Node";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector2Node.cs


[SerializeField]
private Vector2 m_Value;
public Vector2Node(IGraph owner) : base(owner)
public Vector2Node()
{
name = "V2Node";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector3Node.cs


[SerializeField]
private Vector3 m_Value;
public Vector3Node(IGraph owner) : base(owner)
public Vector3Node()
{
name = "V3Node";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector4Node.cs


private const string kOutputSlotName = "Value";
public Vector4Node(IGraph owner) : base(owner)
public Vector4Node()
{
name = "V4Node";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs


get { return PreviewMode.Preview3D; }
}
public ViewDirectionNode(IGraph theOwner) : base(theOwner)
public ViewDirectionNode()
{
name = "View Direction";
UpdateNodeAfterDeserialization();

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs


get { return PreviewMode.Preview3D; }
}
public WorldPosNode(IGraph theOwner) : base(theOwner)
public WorldPosNode()
{
name = "WorldPos";
UpdateNodeAfterDeserialization();

5
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphIONode.cs


using UnityEngine.Graphing;
protected AbstractSubGraphIONode(IGraph theOwner) : base(theOwner)
{}
/*public void FooterUI(GraphGUI host)
{
// TODO: make it pretty

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs


public bool shouldRepaint
{
get { return graph.nodes.OfType<IRequiresTime>().Any(); }
get { return graph.GetNodes<AbstractMaterialNode>().OfType<IRequiresTime>().Any(); }
}
public ScriptableObject GetScriptableObject()

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs


{
// find existing node
if (m_InputNode == null)
m_InputNode = nodes.OfType<SubGraphInputNode>().FirstOrDefault();
m_InputNode = GetNodes<SubGraphInputNode>().FirstOrDefault();
return m_InputNode;
}

{
// find existing node
if (m_OutputNode == null)
m_OutputNode = nodes.OfType<SubGraphOutputNode>().FirstOrDefault();
m_OutputNode = GetNodes<SubGraphOutputNode>().FirstOrDefault();
return m_OutputNode;
}

public void PostCreate()
{
AddNode(new SubGraphInputNode(this));
AddNode(new SubGraphOutputNode(this));
AddNode(new SubGraphInputNode());
AddNode(new SubGraphOutputNode());
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs


using System.Collections.Generic;
using UnityEngine.Graphing;
public SubGraphInputNode(IGraph theOwner) : base(theOwner)
public SubGraphInputNode()
{
name = "SubGraphInputs";
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs


using UnityEngine.Graphing;
public SubGraphOutputNode(IGraph theOwner) : base(theOwner)
public SubGraphOutputNode()
{
name = "SubGraphOutputs";
}
正在加载...
取消
保存