浏览代码

fix formatting

/main
Tim Cooper 8 年前
当前提交
c565a8d4
共有 27 个文件被更改,包括 1282 次插入1293 次删除
  1. 496
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/CopySelected.cs
  2. 120
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DeleteSelected.cs
  3. 420
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs
  4. 484
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphDataSource.cs
  5. 50
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  6. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/IGraphElementView.cs
  7. 94
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphDataSource.cs
  8. 46
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphElementView.cs
  9. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphNode.cs
  10. 186
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphView.cs
  11. 50
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeAnchorData.cs
  12. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeData.cs
  13. 134
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/NullInputProxy.cs
  14. 4
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IGraph.cs
  15. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs
  16. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs
  17. 32
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/PropertyNodeTests.cs
  18. 402
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/PropertyGeneratorTests.cs
  20. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/PropertyNodeTests.cs
  21. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs
  22. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs
  23. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/PixelGraph.cs
  24. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  25. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  26. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  27. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs

496
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/CopySelected.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
/*
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
internal class CopyPasteGraph : ISerializationCallbackReceiver
{
[NonSerialized]
private HashSet<IEdge> m_Edges = new HashSet<IEdge>();
[NonSerialized]
private HashSet<INode> m_Nodes = new HashSet<INode>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
public virtual void AddNode(INode node)
{
m_Nodes.Add(node);
}
public void AddEdge(IEdge edge)
{
m_Edges.Add(edge);
}
public IEnumerable<T> GetNodes<T>() where T : INode
{
return m_Nodes.OfType<T>();
}
public IEnumerable<IEdge> edges
{
get { return m_Edges; }
}
public virtual void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize<INode>(m_Nodes);
m_SerializableEdges = SerializationHelper.Serialize<IEdge>(m_Edges);
}
public virtual void OnAfterDeserialize()
{
var nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes);
m_Nodes.Clear();
foreach (var node in nodes)
m_Nodes.Add(node);
m_SerializableNodes = null;
var edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges);
m_Edges.Clear();
foreach (var edge in edges)
m_Edges.Add(edge);
m_SerializableEdges = null;
}
}
internal class CopySelected : IManipulate
{
public delegate void CopyElements(List<CanvasElement> elements);
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ValidateCommand += Validate;
element.ExecuteCommand += CopyPaste;
}
private bool Validate(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Copy" && e.commandName != "Paste" && e.commandName != "Duplicate")
return false;
e.Use();
return true;
}
private bool CopyPaste(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Copy" && e.commandName != "Paste" && e.commandName != "Duplicate")
return false;
if (e.commandName == "Copy" || e.commandName == "Duplicate")
DoCopy(parent);
if (e.commandName == "Paste" || e.commandName == "Duplicate")
DoPaste(parent);
e.Use();
return true;
}
private static void DoCopy(Canvas2D parent)
{
EditorGUIUtility.systemCopyBuffer = SerializeSelectedElements(parent);
}
public static string SerializeSelectedElements(Canvas2D parent)
{
var selectedElements = parent.selection;
// build a graph to serialize (will just contain the
// nodes and edges we are interested in.
var graph = new CopyPasteGraph();
foreach (var thing in selectedElements)
{
var dNode = thing as DrawableNode;
if (dNode != null)
{
graph.AddNode(dNode.m_Node);
foreach (var edge in NodeUtils.GetAllEdges(dNode.m_Node))
graph.AddEdge(edge);
}
var dEdge = thing as DrawableEdge<NodeAnchor>;
if (dEdge != null)
{
graph.AddEdge(dEdge.m_Edge);
}
}
// serialize then break references
var serialized = JsonUtility.ToJson(graph, true);
return serialized;
}
public static CopyPasteGraph DeserializeSelectedElements(string toDeserialize)
{
try
{
return JsonUtility.FromJson<CopyPasteGraph>(toDeserialize);
}
catch
{
// ignored. just means copy buffer was not a graph :(
return null;
}
}
private static void DoPaste(Canvas2D parent)
{
var copyText = EditorGUIUtility.systemCopyBuffer;
if (string.IsNullOrEmpty(copyText))
return;
var pastedGraph = DeserializeSelectedElements(copyText);
if (pastedGraph == null)
return;
if (parent.dataSource == null)
return;
var dataSource = parent.dataSource as GraphDataSource;
if (dataSource == null)
return;
var asset = dataSource.graphAsset;
if (asset == null)
return;
var graph = asset.graph;
if (graph == null)
return;
var addedNodes = new List<INode>();
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in pastedGraph.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
var drawState = node.drawState;
var position = drawState.position;
position.x += 30;
position.y += 30;
drawState.position = position;
node.drawState = drawState;
graph.AddNode(node);
addedNodes.Add(node);
}
// only connect edges within pasted elements, discard
// external edges.
var addedEdges = new List<IEdge>();
foreach (var edge in pastedGraph.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid)
&& nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid))
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
addedEdges.Add(graph.Connect(outputSlotRef, inputSlotRef));
}
}
graph.ValidateGraph();
parent.ReloadData();
parent.Invalidate();
parent.selection.Clear();
foreach (var element in parent.elements)
{
var drawableNode = element as DrawableNode;
if (drawableNode != null && addedNodes.Any(x => x == drawableNode.m_Node))
{
drawableNode.selected = true;
parent.selection.Add(drawableNode);
continue;
}
var drawableEdge = element as DrawableEdge<NodeAnchor>;
if (drawableEdge != null && addedEdges.Any(x => x == drawableEdge.m_Edge))
{
drawableEdge.selected = true;
parent.selection.Add(drawableEdge);
}
}
parent.Repaint();
}
}
}*/
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
/*
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
internal class CopyPasteGraph : ISerializationCallbackReceiver
{
[NonSerialized]
private HashSet<IEdge> m_Edges = new HashSet<IEdge>();
[NonSerialized]
private HashSet<INode> m_Nodes = new HashSet<INode>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
public virtual void AddNode(INode node)
{
m_Nodes.Add(node);
}
public void AddEdge(IEdge edge)
{
m_Edges.Add(edge);
}
public IEnumerable<T> GetNodes<T>() where T : INode
{
return m_Nodes.OfType<T>();
}
public IEnumerable<IEdge> edges
{
get { return m_Edges; }
}
public virtual void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize<INode>(m_Nodes);
m_SerializableEdges = SerializationHelper.Serialize<IEdge>(m_Edges);
}
public virtual void OnAfterDeserialize()
{
var nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes);
m_Nodes.Clear();
foreach (var node in nodes)
m_Nodes.Add(node);
m_SerializableNodes = null;
var edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges);
m_Edges.Clear();
foreach (var edge in edges)
m_Edges.Add(edge);
m_SerializableEdges = null;
}
}
internal class CopySelected : IManipulate
{
public delegate void CopyElements(List<CanvasElement> elements);
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ValidateCommand += Validate;
element.ExecuteCommand += CopyPaste;
}
private bool Validate(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Copy" && e.commandName != "Paste" && e.commandName != "Duplicate")
return false;
e.Use();
return true;
}
private bool CopyPaste(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Copy" && e.commandName != "Paste" && e.commandName != "Duplicate")
return false;
if (e.commandName == "Copy" || e.commandName == "Duplicate")
DoCopy(parent);
if (e.commandName == "Paste" || e.commandName == "Duplicate")
DoPaste(parent);
e.Use();
return true;
}
private static void DoCopy(Canvas2D parent)
{
EditorGUIUtility.systemCopyBuffer = SerializeSelectedElements(parent);
}
public static string SerializeSelectedElements(Canvas2D parent)
{
var selectedElements = parent.selection;
// build a graph to serialize (will just contain the
// nodes and edges we are interested in.
var graph = new CopyPasteGraph();
foreach (var thing in selectedElements)
{
var dNode = thing as DrawableNode;
if (dNode != null)
{
graph.AddNode(dNode.m_Node);
foreach (var edge in NodeUtils.GetAllEdges(dNode.m_Node))
graph.AddEdge(edge);
}
var dEdge = thing as DrawableEdge<NodeAnchor>;
if (dEdge != null)
{
graph.AddEdge(dEdge.m_Edge);
}
}
// serialize then break references
var serialized = JsonUtility.ToJson(graph, true);
return serialized;
}
public static CopyPasteGraph DeserializeSelectedElements(string toDeserialize)
{
try
{
return JsonUtility.FromJson<CopyPasteGraph>(toDeserialize);
}
catch
{
// ignored. just means copy buffer was not a graph :(
return null;
}
}
private static void DoPaste(Canvas2D parent)
{
var copyText = EditorGUIUtility.systemCopyBuffer;
if (string.IsNullOrEmpty(copyText))
return;
var pastedGraph = DeserializeSelectedElements(copyText);
if (pastedGraph == null)
return;
if (parent.dataSource == null)
return;
var dataSource = parent.dataSource as GraphDataSource;
if (dataSource == null)
return;
var asset = dataSource.graphAsset;
if (asset == null)
return;
var graph = asset.graph;
if (graph == null)
return;
var addedNodes = new List<INode>();
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in pastedGraph.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
var drawState = node.drawState;
var position = drawState.position;
position.x += 30;
position.y += 30;
drawState.position = position;
node.drawState = drawState;
graph.AddNode(node);
addedNodes.Add(node);
}
// only connect edges within pasted elements, discard
// external edges.
var addedEdges = new List<IEdge>();
foreach (var edge in pastedGraph.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid)
&& nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid))
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
addedEdges.Add(graph.Connect(outputSlotRef, inputSlotRef));
}
}
graph.ValidateGraph();
parent.ReloadData();
parent.Invalidate();
parent.selection.Clear();
foreach (var element in parent.elements)
{
var drawableNode = element as DrawableNode;
if (drawableNode != null && addedNodes.Any(x => x == drawableNode.m_Node))
{
drawableNode.selected = true;
parent.selection.Add(drawableNode);
continue;
}
var drawableEdge = element as DrawableEdge<NodeAnchor>;
if (drawableEdge != null && addedEdges.Any(x => x == drawableEdge.m_Edge))
{
drawableEdge.selected = true;
parent.selection.Add(drawableEdge);
}
}
parent.Repaint();
}
}
}*/

120
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DeleteSelected.cs


/*using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Graphing.Drawing
{
internal class DeleteSelected : IManipulate
{
public delegate void DeleteElements(List<CanvasElement> elements);
private readonly DeleteElements m_DeletionCallback;
public DeleteSelected(DeleteElements deletionCallback)
{
m_DeletionCallback = deletionCallback;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ValidateCommand += Validate;
element.ExecuteCommand += Delete;
}
private bool Validate(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Delete" && e.commandName != "SoftDelete")
return false;
e.Use();
return true;
}
private bool Delete(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Delete" && e.commandName != "SoftDelete")
return false;
if (m_DeletionCallback != null)
{
m_DeletionCallback(parent.selection);
parent.ReloadData();
parent.Repaint();
}
e.Use();
return true;
}
}
}
*/
/*using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Graphing.Drawing
{
internal class DeleteSelected : IManipulate
{
public delegate void DeleteElements(List<CanvasElement> elements);
private readonly DeleteElements m_DeletionCallback;
public DeleteSelected(DeleteElements deletionCallback)
{
m_DeletionCallback = deletionCallback;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ValidateCommand += Validate;
element.ExecuteCommand += Delete;
}
private bool Validate(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Delete" && e.commandName != "SoftDelete")
return false;
e.Use();
return true;
}
private bool Delete(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if (e.commandName != "Delete" && e.commandName != "SoftDelete")
return false;
if (m_DeletionCallback != null)
{
m_DeletionCallback(parent.selection);
parent.ReloadData();
parent.Repaint();
}
e.Use();
return true;
}
}
}
*/

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


using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
/*
namespace UnityEditor.Graphing.Drawing
{
public class DrawableNode : CanvasElement
{
private readonly GraphDataSource m_Data;
private readonly Rect m_CustomUiRect;
public readonly INode m_Node;
private readonly ICustomNodeUi m_Ui;
private const int kDefaultWidth = 200;
public DrawableNode(INode node, ICustomNodeUi ui, GraphDataSource data)
{
var drawData = node.drawState;
translation = drawData.position.min;
var width = ui != null ? ui.GetNodeWidth() : kDefaultWidth;
scale = new Vector2(width, width);
m_Node = node;
m_Ui = ui;
m_Data = data;
const float yStart = 10.0f;
var vector3 = new Vector3(5.0f, yStart, 0.0f);
Vector3 pos = vector3;
// input slots
foreach (var slot in node.GetInputSlots<ISlot>().OrderBy(x => x.priority))
{
pos.y += 22;
AddChild(new NodeAnchor(pos, typeof(Vector4), node, slot, data, Direction.Input));
}
var inputYMax = pos.y + 22;
// output port
pos.x = width;
pos.y = yStart;
bool first = true;
foreach (var slot in node.GetOutputSlots<ISlot>().OrderBy(x => x.priority).ThenBy(x => x.id))
{
var edges = node.owner.GetEdges(node.GetSlotReference(slot.id));
// don't show empty output slots in collapsed mode
if (!node.drawState.expanded && !edges.Any() && !first)
continue;
pos.y += 22;
AddChild(new NodeAnchor(pos, typeof(Vector4), node, slot, data, Direction.Output));
first = false;
}
pos.y += 22;
pos.y = Mathf.Max(pos.y, inputYMax);
if (ui != null)
{
var customUiHeight = ui.GetNodeUiHeight(width);
m_CustomUiRect = new Rect(10, pos.y, width - 20, customUiHeight);
pos.y += customUiHeight;
}
scale = new Vector3(pos.x, pos.y + 10.0f, 0.0f);
OnWidget += InvalidateUIIfNeedsTime;
AddManipulator(new ImguiContainer());
AddManipulator(new Draggable());
}
private bool InvalidateUIIfNeedsTime(CanvasElement element, Event e, Canvas2D parent)
{
var childrenNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childrenNodes, m_Node);
if (childrenNodes.OfType<IRequiresTime>().Any())
Invalidate();
ListPool<INode>.Release(childrenNodes);
return true;
}
public override void UpdateModel(UpdateType t)
{
base.UpdateModel(t);
var drawState = m_Node.drawState;
var pos = drawState.position;
pos.min = translation;
drawState.position = pos;
m_Node.drawState = drawState;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
Color selectedColor = new Color(1.0f, 0.7f, 0.0f, 0.7f);
EditorGUI.DrawRect(new Rect(0, 0, scale.x, scale.y), m_Node.hasError ? Color.red : selected ? selectedColor : backgroundColor);
GUI.Label(new Rect(0, 0, scale.x, 26f), GUIContent.none, new GUIStyle("preToolbar"));
GUI.Label(new Rect(10, 2, scale.x - 20.0f, 16.0f), m_Node.name, EditorStyles.toolbarTextField);
var drawState = m_Node.drawState;
if (GUI.Button(new Rect(scale.x - 20f, 3f, 14f, 14f), drawState.expanded ? "-" : "+"))
{
drawState.expanded = !drawState.expanded;
m_Node.drawState = drawState;
ParentCanvas().ReloadData();
ParentCanvas().Repaint();
return;
}
if (m_Ui != null)
{
var modificationType = m_Ui.Render(m_CustomUiRect);
if (modificationType != GUIModificationType.None)
m_Data.MarkDirty();
if (modificationType == GUIModificationType.ModelChanged)
{
m_Node.owner.ValidateGraph();
ParentCanvas().Invalidate();
ParentCanvas().ReloadData();
ParentCanvas().Repaint();
return;
}
if (modificationType == GUIModificationType.DataChanged)
{
ValidateDependentNodes(m_Node);
RepaintDependentNodes(m_Node);
}
else if (modificationType == GUIModificationType.Repaint)
{
// if we were changed, we need to redraw all the
// dependent nodes.
RepaintDependentNodes(m_Node);
}
}
base.Render(parentRect, canvas);
}
private void RepaintDependentNodes(INode theNode)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, theNode);
foreach (var node in dependentNodes)
{
foreach (var drawableNode in m_Data.lastGeneratedNodes.Where(x => x.m_Node == node))
drawableNode.Invalidate();
}
}
private void ValidateDependentNodes(INode theNode)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, theNode);
foreach (var node in dependentNodes)
node.ValidateNode();
}
/*
public static void OnGUI(List<CanvasElement> selection)
{
var drawableMaterialNode = selection.OfType<DrawableMaterialNode>().FirstOrDefault();
if (drawableMaterialNode != null && drawableMaterialNode.m_Node.OnGUI())
{
// if we were changed, we need to redraw all the
// dependent nodes.
RepaintDependentNodes(drawableMaterialNode.m_Node);
}
}*/
/* public virtual GUIModificationType NodeUI(Rect drawArea)
{
return GUIModificationType.None;
}
public virtual bool OnGUI()
{
GUILayout.Label("MaterialSlot Defaults", EditorStyles.boldLabel);
var modified = false;
foreach (var slot in inputSlots)
{
if (!owner.GetEdges(GetSlotReference(slot.name)).Any())
modified |= DoSlotUI(this, slot);
}
return modified;
}
public static bool DoSlotUI(SerializableNode node, ISlot slot)
{
GUILayout.BeginHorizontal( /*EditorStyles.inspectorBig*);
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("MaterialSlot " + slot.name, EditorStyles.largeLabel);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
//TODO: fix this
return false;
//return slot.OnGUI();
}*
}
}*/
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
/*
namespace UnityEditor.Graphing.Drawing
{
public class DrawableNode : CanvasElement
{
private readonly GraphDataSource m_Data;
private readonly Rect m_CustomUiRect;
public readonly INode m_Node;
private readonly ICustomNodeUi m_Ui;
private const int kDefaultWidth = 200;
public DrawableNode(INode node, ICustomNodeUi ui, GraphDataSource data)
{
var drawData = node.drawState;
translation = drawData.position.min;
var width = ui != null ? ui.GetNodeWidth() : kDefaultWidth;
scale = new Vector2(width, width);
m_Node = node;
m_Ui = ui;
m_Data = data;
const float yStart = 10.0f;
var vector3 = new Vector3(5.0f, yStart, 0.0f);
Vector3 pos = vector3;
// input slots
foreach (var slot in node.GetInputSlots<ISlot>().OrderBy(x => x.priority))
{
pos.y += 22;
AddChild(new NodeAnchor(pos, typeof(Vector4), node, slot, data, Direction.Input));
}
var inputYMax = pos.y + 22;
// output port
pos.x = width;
pos.y = yStart;
bool first = true;
foreach (var slot in node.GetOutputSlots<ISlot>().OrderBy(x => x.priority).ThenBy(x => x.id))
{
var edges = node.owner.GetEdges(node.GetSlotReference(slot.id));
// don't show empty output slots in collapsed mode
if (!node.drawState.expanded && !edges.Any() && !first)
continue;
pos.y += 22;
AddChild(new NodeAnchor(pos, typeof(Vector4), node, slot, data, Direction.Output));
first = false;
}
pos.y += 22;
pos.y = Mathf.Max(pos.y, inputYMax);
if (ui != null)
{
var customUiHeight = ui.GetNodeUiHeight(width);
m_CustomUiRect = new Rect(10, pos.y, width - 20, customUiHeight);
pos.y += customUiHeight;
}
scale = new Vector3(pos.x, pos.y + 10.0f, 0.0f);
OnWidget += InvalidateUIIfNeedsTime;
AddManipulator(new ImguiContainer());
AddManipulator(new Draggable());
}
private bool InvalidateUIIfNeedsTime(CanvasElement element, Event e, Canvas2D parent)
{
var childrenNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childrenNodes, m_Node);
if (childrenNodes.OfType<IRequiresTime>().Any())
Invalidate();
ListPool<INode>.Release(childrenNodes);
return true;
}
public override void UpdateModel(UpdateType t)
{
base.UpdateModel(t);
var drawState = m_Node.drawState;
var pos = drawState.position;
pos.min = translation;
drawState.position = pos;
m_Node.drawState = drawState;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
Color selectedColor = new Color(1.0f, 0.7f, 0.0f, 0.7f);
EditorGUI.DrawRect(new Rect(0, 0, scale.x, scale.y), m_Node.hasError ? Color.red : selected ? selectedColor : backgroundColor);
GUI.Label(new Rect(0, 0, scale.x, 26f), GUIContent.none, new GUIStyle("preToolbar"));
GUI.Label(new Rect(10, 2, scale.x - 20.0f, 16.0f), m_Node.name, EditorStyles.toolbarTextField);
var drawState = m_Node.drawState;
if (GUI.Button(new Rect(scale.x - 20f, 3f, 14f, 14f), drawState.expanded ? "-" : "+"))
{
drawState.expanded = !drawState.expanded;
m_Node.drawState = drawState;
ParentCanvas().ReloadData();
ParentCanvas().Repaint();
return;
}
if (m_Ui != null)
{
var modificationType = m_Ui.Render(m_CustomUiRect);
if (modificationType != GUIModificationType.None)
m_Data.MarkDirty();
if (modificationType == GUIModificationType.ModelChanged)
{
m_Node.owner.ValidateGraph();
ParentCanvas().Invalidate();
ParentCanvas().ReloadData();
ParentCanvas().Repaint();
return;
}
if (modificationType == GUIModificationType.DataChanged)
{
ValidateDependentNodes(m_Node);
RepaintDependentNodes(m_Node);
}
else if (modificationType == GUIModificationType.Repaint)
{
// if we were changed, we need to redraw all the
// dependent nodes.
RepaintDependentNodes(m_Node);
}
}
base.Render(parentRect, canvas);
}
private void RepaintDependentNodes(INode theNode)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, theNode);
foreach (var node in dependentNodes)
{
foreach (var drawableNode in m_Data.lastGeneratedNodes.Where(x => x.m_Node == node))
drawableNode.Invalidate();
}
}
private void ValidateDependentNodes(INode theNode)
{
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, theNode);
foreach (var node in dependentNodes)
node.ValidateNode();
}
/*
public static void OnGUI(List<CanvasElement> selection)
{
var drawableMaterialNode = selection.OfType<DrawableMaterialNode>().FirstOrDefault();
if (drawableMaterialNode != null && drawableMaterialNode.m_Node.OnGUI())
{
// if we were changed, we need to redraw all the
// dependent nodes.
RepaintDependentNodes(drawableMaterialNode.m_Node);
}
}*/
/* public virtual GUIModificationType NodeUI(Rect drawArea)
{
return GUIModificationType.None;
}
public virtual bool OnGUI()
{
GUILayout.Label("MaterialSlot Defaults", EditorStyles.boldLabel);
var modified = false;
foreach (var slot in inputSlots)
{
if (!owner.GetEdges(GetSlotReference(slot.name)).Any())
modified |= DoSlotUI(this, slot);
}
return modified;
}
public static bool DoSlotUI(SerializableNode node, ISlot slot)
{
GUILayout.BeginHorizontal( /*EditorStyles.inspectorBig*);
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("MaterialSlot " + slot.name, EditorStyles.largeLabel);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
//TODO: fix this
return false;
//return slot.OnGUI();
}*
}
}*/

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


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[AttributeUsage(AttributeTargets.Class)]
sealed class CustomNodeUI : Attribute
{
private Type m_ModeToDrawFor;
public CustomNodeUI(Type nodeToDrawFor)
{
m_ModeToDrawFor = nodeToDrawFor;
}
public Type nodeToDrawFor
{
get { return m_ModeToDrawFor; } }
}
/*
public class GraphDataSource : ICanvasDataSource
{
readonly List<DrawableNode> m_DrawableNodes = new List<DrawableNode>();
public IGraphAsset graphAsset { get; set; }
public ICollection<DrawableNode> lastGeneratedNodes
{
get { return m_DrawableNodes; }
}
private static Type[] GetTypesFromAssembly(Assembly assembly)
{
if (assembly == null)
return new Type[] {};
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException)
{
return new Type[] {};
}
}
private static Dictionary<Type, Type> s_DrawerUI;
private static Dictionary<Type, Type> drawerUI
{
get
{
if (s_DrawerUI == null)
{
s_DrawerUI = new Dictionary<Type, Type>();
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => GetTypesFromAssembly(x));
foreach (var type in loadedTypes)
{
var attribute = type.GetCustomAttributes(true).OfType<CustomNodeUI>().FirstOrDefault();
if (attribute != null && typeof(ICustomNodeUi).IsAssignableFrom(type))
s_DrawerUI.Add(attribute.nodeToDrawFor, type);
}
}
return s_DrawerUI;
}
}
public CanvasElement[] FetchElements()
{
m_DrawableNodes.Clear();
var graph = graphAsset.graph;
Debug.LogFormat("Trying to convert: {0}", graphAsset.graph);
foreach (var node in graph.GetNodes<INode>())
{
var nodeType = node.GetType();
Type draweruiType = null;
while (draweruiType == null && nodeType != null)
{
draweruiType = drawerUI.FirstOrDefault(x => x.Key == nodeType).Value;
nodeType = nodeType.BaseType;
}
ICustomNodeUi customUI = null;
if (draweruiType != null)
{
try
{
customUI = Activator.CreateInstance(draweruiType) as ICustomNodeUi;
customUI.node = node;
}
catch (Exception e)
{
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", draweruiType, e);
}
}
// add the nodes
m_DrawableNodes.Add(new DrawableNode(node, customUI, this));
}
// Add the edges now
var drawableEdges = new List<DrawableEdge<NodeAnchor>>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_DrawableNodes.FirstOrDefault(x => x.m_Node == toNode);
var targetAnchor = (NodeAnchor)targetNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == toSlot);
drawableEdges.Add(new DrawableEdge<NodeAnchor>(edge, this, sourceAnchor, targetAnchor));
}
}
}
// Add proxy inputs for when edges are not connect
var nullInputSlots = new List<NullInputProxy>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
// grab the input slots where there are no edges
foreach (var slot in baseNode.GetInputsWithNoConnection())
{
// if there is no anchor, continue
// this can happen if we are in collapsed mode
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
if (sourceAnchor == null)
continue;
nullInputSlots.Add(new NullInputProxy(baseNode, slot, sourceAnchor));
}
}
var toReturn = new List<CanvasElement>();
toReturn.AddRange(m_DrawableNodes.Select(x => (CanvasElement)x));
toReturn.AddRange(drawableEdges.Select(x => (CanvasElement)x));
toReturn.AddRange(nullInputSlots.Select(x => (CanvasElement)x));
//toReturn.Add(new FloatingPreview(new Rect(Screen.width - 300, Screen.height - 300, 300, 300), pixelGraph.nodes.FirstOrDefault(x => x is PixelShaderNode)));
Debug.LogFormat("Returning {0} nodes", m_DrawableNodes.Count);
Debug.LogFormat("Returning {0} drawableEdges", drawableEdges.Count);
Debug.LogFormat("Returning {0} nullInputSlots", nullInputSlots.Count);
return toReturn.ToArray();
}
public void DeleteElement(CanvasElement e)
{
// do nothing here, we want to use delete elements.
// delete elements ensures that edges are deleted before nodes.
}
public void DeleteElements(List<CanvasElement> elements)
{
var graph = graphAsset.graph;
var toRemoveEdge = new List<IEdge>();
// delete selected edges first
foreach (var e in elements.OfType<Edge<NodeAnchor>>())
{
//find the edge
var edge = graph.edges.FirstOrDefault(x => graph.GetNodeFromGuid(x.outputSlot.nodeGuid).FindOutputSlot<ISlot>(x.outputSlot.slotId) == e.Left.m_Slot
&& graph.GetNodeFromGuid(x.inputSlot.nodeGuid).FindInputSlot<ISlot>(x.inputSlot.slotId) == e.Right.m_Slot);
toRemoveEdge.Add(edge);
}
var toRemoveNode = new List<INode>();
// now delete the nodes
foreach (var e in elements.OfType<DrawableNode>())
{
if (!e.m_Node.canDeleteNode)
continue;
toRemoveNode.Add(e.m_Node);
}
graph.RemoveElements(toRemoveNode, toRemoveEdge);
MarkDirty();
}
public void Connect(NodeAnchor a, NodeAnchor b)
{
var graph = graphAsset.graph;
graph.Connect(a.m_Node.GetSlotReference(a.m_Slot.id), b.m_Node.GetSlotReference(b.m_Slot.id));
MarkDirty();
}
public void Addnode(INode node)
{
var graph = graphAsset.graph;
graph.AddNode(node);
MarkDirty();
}
public void MarkDirty()
{
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
}
/*
}
public class FloatingPreview : CanvasElement
{
private AbstractMaterialNode m_Node;
public FloatingPreview(Rect position, AbstractMaterialNode node)
{
m_Node = node as AbstractMaterialNode;
m_Translation = new Vector2(position.x, position.y);
m_Scale = new Vector3(position.width, position.height, 1);
m_Caps |= Capabilities.Floating | Capabilities.Unselectable;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
var drawArea = new Rect(0, 0, scale.x, scale.y);
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
EditorGUI.DrawRect(drawArea, backgroundColor);
drawArea.width -= 10;
drawArea.height -= 10;
drawArea.x += 5;
drawArea.y += 5;
GL.sRGBWrite = (QualitySettings.activeColorSpace == ColorSpace.Linear);
GUI.DrawTexture(drawArea, m_Node.RenderPreview(new Rect(0, 0, drawArea.width, drawArea.height)), ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
Invalidate();
canvas.Repaint();
}*
}*/
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[AttributeUsage(AttributeTargets.Class)]
sealed class CustomNodeUI : Attribute
{
private Type m_ModeToDrawFor;
public CustomNodeUI(Type nodeToDrawFor)
{
m_ModeToDrawFor = nodeToDrawFor;
}
public Type nodeToDrawFor
{
get { return m_ModeToDrawFor; } }
}
/*
public class GraphDataSource : ICanvasDataSource
{
readonly List<DrawableNode> m_DrawableNodes = new List<DrawableNode>();
public IGraphAsset graphAsset { get; set; }
public ICollection<DrawableNode> lastGeneratedNodes
{
get { return m_DrawableNodes; }
}
private static Type[] GetTypesFromAssembly(Assembly assembly)
{
if (assembly == null)
return new Type[] {};
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException)
{
return new Type[] {};
}
}
private static Dictionary<Type, Type> s_DrawerUI;
private static Dictionary<Type, Type> drawerUI
{
get
{
if (s_DrawerUI == null)
{
s_DrawerUI = new Dictionary<Type, Type>();
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => GetTypesFromAssembly(x));
foreach (var type in loadedTypes)
{
var attribute = type.GetCustomAttributes(true).OfType<CustomNodeUI>().FirstOrDefault();
if (attribute != null && typeof(ICustomNodeUi).IsAssignableFrom(type))
s_DrawerUI.Add(attribute.nodeToDrawFor, type);
}
}
return s_DrawerUI;
}
}
public CanvasElement[] FetchElements()
{
m_DrawableNodes.Clear();
var graph = graphAsset.graph;
Debug.LogFormat("Trying to convert: {0}", graphAsset.graph);
foreach (var node in graph.GetNodes<INode>())
{
var nodeType = node.GetType();
Type draweruiType = null;
while (draweruiType == null && nodeType != null)
{
draweruiType = drawerUI.FirstOrDefault(x => x.Key == nodeType).Value;
nodeType = nodeType.BaseType;
}
ICustomNodeUi customUI = null;
if (draweruiType != null)
{
try
{
customUI = Activator.CreateInstance(draweruiType) as ICustomNodeUi;
customUI.node = node;
}
catch (Exception e)
{
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", draweruiType, e);
}
}
// add the nodes
m_DrawableNodes.Add(new DrawableNode(node, customUI, this));
}
// Add the edges now
var drawableEdges = new List<DrawableEdge<NodeAnchor>>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_DrawableNodes.FirstOrDefault(x => x.m_Node == toNode);
var targetAnchor = (NodeAnchor)targetNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == toSlot);
drawableEdges.Add(new DrawableEdge<NodeAnchor>(edge, this, sourceAnchor, targetAnchor));
}
}
}
// Add proxy inputs for when edges are not connect
var nullInputSlots = new List<NullInputProxy>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
// grab the input slots where there are no edges
foreach (var slot in baseNode.GetInputsWithNoConnection())
{
// if there is no anchor, continue
// this can happen if we are in collapsed mode
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
if (sourceAnchor == null)
continue;
nullInputSlots.Add(new NullInputProxy(baseNode, slot, sourceAnchor));
}
}
var toReturn = new List<CanvasElement>();
toReturn.AddRange(m_DrawableNodes.Select(x => (CanvasElement)x));
toReturn.AddRange(drawableEdges.Select(x => (CanvasElement)x));
toReturn.AddRange(nullInputSlots.Select(x => (CanvasElement)x));
//toReturn.Add(new FloatingPreview(new Rect(Screen.width - 300, Screen.height - 300, 300, 300), pixelGraph.nodes.FirstOrDefault(x => x is PixelShaderNode)));
Debug.LogFormat("Returning {0} nodes", m_DrawableNodes.Count);
Debug.LogFormat("Returning {0} drawableEdges", drawableEdges.Count);
Debug.LogFormat("Returning {0} nullInputSlots", nullInputSlots.Count);
return toReturn.ToArray();
}
public void DeleteElement(CanvasElement e)
{
// do nothing here, we want to use delete elements.
// delete elements ensures that edges are deleted before nodes.
}
public void DeleteElements(List<CanvasElement> elements)
{
var graph = graphAsset.graph;
var toRemoveEdge = new List<IEdge>();
// delete selected edges first
foreach (var e in elements.OfType<Edge<NodeAnchor>>())
{
//find the edge
var edge = graph.edges.FirstOrDefault(x => graph.GetNodeFromGuid(x.outputSlot.nodeGuid).FindOutputSlot<ISlot>(x.outputSlot.slotId) == e.Left.m_Slot
&& graph.GetNodeFromGuid(x.inputSlot.nodeGuid).FindInputSlot<ISlot>(x.inputSlot.slotId) == e.Right.m_Slot);
toRemoveEdge.Add(edge);
}
var toRemoveNode = new List<INode>();
// now delete the nodes
foreach (var e in elements.OfType<DrawableNode>())
{
if (!e.m_Node.canDeleteNode)
continue;
toRemoveNode.Add(e.m_Node);
}
graph.RemoveElements(toRemoveNode, toRemoveEdge);
MarkDirty();
}
public void Connect(NodeAnchor a, NodeAnchor b)
{
var graph = graphAsset.graph;
graph.Connect(a.m_Node.GetSlotReference(a.m_Slot.id), b.m_Node.GetSlotReference(b.m_Slot.id));
MarkDirty();
}
public void Addnode(INode node)
{
var graph = graphAsset.graph;
graph.AddNode(node);
MarkDirty();
}
public void MarkDirty()
{
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
}
/*
}
public class FloatingPreview : CanvasElement
{
private AbstractMaterialNode m_Node;
public FloatingPreview(Rect position, AbstractMaterialNode node)
{
m_Node = node as AbstractMaterialNode;
m_Translation = new Vector2(position.x, position.y);
m_Scale = new Vector3(position.width, position.height, 1);
m_Caps |= Capabilities.Floating | Capabilities.Unselectable;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
var drawArea = new Rect(0, 0, scale.x, scale.y);
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
EditorGUI.DrawRect(drawArea, backgroundColor);
drawArea.width -= 10;
drawArea.height -= 10;
drawArea.x += 5;
drawArea.y += 5;
GL.sRGBWrite = (QualitySettings.activeColorSpace == ColorSpace.Linear);
GUI.DrawTexture(drawArea, m_Node.RenderPreview(new Rect(0, 0, drawArea.width, drawArea.height)), ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
Invalidate();
canvas.Repaint();
}*
}*/
}

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


[SerializeField]
private ScriptableObject m_LastSelectedGraphSerialized;
private bool shouldRepaint
{
get

graph.OnEnable();
graph.ValidateGraph();
m_LastSelection = selection;
m_Contents.StretchToParentSize();
Repaint();
}

m_Canvas.ReloadData();
}*/
/* void OnGUI()
{
m_HostWindow = this;
if (m_Canvas == null)
{
InitializeCanvas();
}
/* void OnGUI()
{
m_HostWindow = this;
if (m_Canvas == null)
{
InitializeCanvas();
}
if (m_LastSelection == null || m_LastSelection.graph == null)
{
GUILayout.Label("No Graph selected");
return;
}
if (m_LastSelection == null || m_LastSelection.graph == null)
{
GUILayout.Label("No Graph selected");
return;
}
m_Canvas.OnGUI(this, new Rect(0, 0, position.width - 250, position.height));
m_Canvas.OnGUI(this, new Rect(0, 0, position.width - 250, position.height));
if (GUI.Button(new Rect(position.width - 250, 0, 250, 50), "Convert to Sub-Graph"))
ConvertSelectionToSubGraph();
if (GUI.Button(new Rect(position.width - 250, 0, 250, 50), "Convert to Sub-Graph"))
ConvertSelectionToSubGraph();
if (GUI.Button(new Rect(position.width - 250, 70, 250, 50), "Export"))
Export(false);
if (GUI.Button(new Rect(position.width - 250, 70, 250, 50), "Export"))
Export(false);
if (GUI.Button(new Rect(position.width - 250, 140, 250, 50), "Export - quick"))
Export(true);
if (GUI.Button(new Rect(position.width - 250, 140, 250, 50), "Export - quick"))
Export(true);
EditorGUI.ObjectField(new Rect(position.width - 250, 210, 250, 50), rt, typeof(RenderTexture), false);
}*/
EditorGUI.ObjectField(new Rect(position.width - 250, 210, 250, 50), rt, typeof(RenderTexture), false);
}*/
private string m_LastPath;

var ds = m_Contents.dataSource as MaterialGraphDataSource;
if (ds != null && !string.IsNullOrEmpty(path))
{
ExportShader (ds.graphAsset as MaterialGraphAsset, path);
ExportShader(ds.graphAsset as MaterialGraphAsset, path);
}
else
EditorUtility.DisplayDialog("Export Shader Error", "Cannot export shader", "Ok");

1
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/IGraphElementView.cs


94
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphDataSource.cs


namespace UnityEditor.Graphing.Drawing
{
[Serializable]
[Serializable]
public class MaterialGraphDataSource : IGraphElementDataSource
{
private List<GraphElementData> m_Elements = new List<GraphElementData>();

if (graphAsset == null)
return;
var drawableNodes = new List<MaterialNodeData>();
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
MaterialNodeData nodeData;
var drawableNodes = new List<MaterialNodeData>();
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
MaterialNodeData nodeData;
if (node is ColorNode)
nodeData = ScriptableObject.CreateInstance<ColorNodeData>();
else
nodeData = ScriptableObject.CreateInstance<MaterialNodeData>();
nodeData.Initialize(node);
drawableNodes.Add(nodeData);
}
var drawableEdges = new List<EdgeData>();
foreach (var addedNode in drawableNodes)
{
var baseNode = addedNode.node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchors = addedNode.elements.OfType<MaterialNodeAnchorData>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == slot);
if (node is ColorNode)
nodeData = ScriptableObject.CreateInstance<ColorNodeData>();
else
nodeData = ScriptableObject.CreateInstance<MaterialNodeData>();
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = drawableNodes.FirstOrDefault(x => x.node == toNode);
nodeData.Initialize(node);
drawableNodes.Add(nodeData);
}
var targetAnchors = targetNode.elements.OfType<MaterialNodeAnchorData>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
drawableEdges.Add(new EdgeData {left = sourceAnchor, right = targetAnchor});
}
}
}
m_Elements.AddRange(drawableNodes.OfType<GraphElementData>());
m_Elements.AddRange(drawableEdges.OfType<GraphElementData>());
}
var drawableEdges = new List<EdgeData>();
foreach (var addedNode in drawableNodes)
{
var baseNode = addedNode.node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchors = addedNode.elements.OfType<MaterialNodeAnchorData>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = drawableNodes.FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.elements.OfType<MaterialNodeAnchorData>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
drawableEdges.Add(new EdgeData {left = sourceAnchor, right = targetAnchor});
}
}
}
m_Elements.AddRange(drawableNodes.OfType<GraphElementData>());
m_Elements.AddRange(drawableEdges.OfType<GraphElementData>());
}
public IEnumerable<GraphElementData> elements
{

public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
}

46
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphElementView.cs


namespace UnityEditor.Graphing.Drawing
{
/*public class MaterialGraphElementView : IGraphElementView
{
private bool m_Selected;
/*public class MaterialGraphElementView : IGraphElementView
{
private bool m_Selected;
public string name { get; set; }
public string name { get; set; }
public Capabilities capabilities { get; set; }
public Capabilities capabilities { get; set; }
public Rect position { get; set; }
public Rect position { get; set; }
public bool selected
{
get { return m_Selected; }
set
{
// Set new value (toggle old value)
if ((capabilities & Capabilities.Selectable) == Capabilities.Selectable)
{
m_Selected = value;
}
}
}
public bool selected
{
get { return m_Selected; }
set
{
// Set new value (toggle old value)
if ((capabilities & Capabilities.Selectable) == Capabilities.Selectable)
{
m_Selected = value;
}
}
}
protected void OnEnable()
{
capabilities = Capabilities.Normal | Capabilities.Movable | Capabilities.Selectable;
}
}*/
protected void OnEnable()
{
capabilities = Capabilities.Normal | Capabilities.Movable | Capabilities.Selectable;
}
}*/
}

7
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphNode.cs


name = "preview", // for USS&Flexbox
pickingMode = PickingMode.Ignore,
};
}
public override void DoRepaint(PaintContext painter)

name = "input", // for USS&Flexbox
pickingMode = PickingMode.Ignore,
};
m_SlotContainer.AddChild(inputs);
m_SlotContainer.AddChild(inputs);
// put a spacer here?
//m_SlotContainer.AddChild(new f);

AddChild(m_SlotContainer);
}
private void AddControls(MaterialNodeData nodeData)
{
m_ControlsContainer.ClearChildren();

m_ControlsContainer.ClearChildren();
m_PreviewContainer.ClearChildren();
var nodeData = dataProvider as MaterialNodeData;
if (nodeData == null)

186
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphView.cs


using System;
using System.Reflection;
using RMGUI.GraphView;
using RMGUI.GraphView.Demo;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using UnityEngine.RMGUI;
using Object = UnityEngine.Object;
namespace UnityEditor.Graphing.Drawing
{
[StyleSheet("Assets/UnityShaderEditor/Editor/Styles/NodalView.uss")]
//[StyleSheet("Assets/UnityShaderEditor/Editor/Styles/MatGraph.uss")]
public class MaterialGraphView : GraphView
{
public MaterialGraphView()
{
AddManipulator(new ContentZoomer());
AddManipulator(new ContentDragger());
AddManipulator(new RectangleSelector());
AddManipulator(new SelectionDragger());
AddManipulator(new ClickSelector());
AddManipulator(new ContextualMenu(DoContextMenu));
AddDecorator(new GridBackground(contentViewContainer));
}
public virtual bool CanAddToNodeMenu(Type type)
{
return true;
}
protected EventPropagation DoContextMenu(Event evt, Object customData)
{
var gm = new GenericMenu();
foreach (Type type in Assembly.GetAssembly(typeof(AbstractMaterialNode)).GetTypes())
{
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))))
{
var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[];
if (attrs != null && attrs.Length > 0 && CanAddToNodeMenu(type))
{
gm.AddItem(new GUIContent(attrs[0].m_Title), false, AddNode, new AddNodeCreationObject(type, evt.mousePosition));
}
}
}
//gm.AddSeparator("");
// gm.AddItem(new GUIContent("Convert To/SubGraph"), true, ConvertSelectionToSubGraph);
gm.ShowAsContext();
return EventPropagation.Stop;
}
private class AddNodeCreationObject : object
{
public Vector2 m_Pos;
public readonly Type m_Type;
public AddNodeCreationObject(Type t, Vector2 p)
{
m_Type = t;
m_Pos = p;
}
};
private void AddNode(object obj)
{
var posObj = obj as AddNodeCreationObject;
if (posObj == null)
return;
INode node;
try
{
node = Activator.CreateInstance(posObj.m_Type) as INode;
}
catch (Exception e)
{
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", posObj.m_Type, e);
return;
}
if (node == null)
return;
var drawstate = node.drawState;
drawstate.position = new Rect(posObj.m_Pos.x, posObj.m_Pos.y, drawstate.position.width, drawstate.position.height);
node.drawState = drawstate;
/*m_DataSource.Addnode(node);
Rebuild();
Repaint();*/
}
}
}
using System;
using System.Reflection;
using RMGUI.GraphView;
using RMGUI.GraphView.Demo;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using UnityEngine.RMGUI;
using Object = UnityEngine.Object;
namespace UnityEditor.Graphing.Drawing
{
[StyleSheet("Assets/UnityShaderEditor/Editor/Styles/NodalView.uss")]
//[StyleSheet("Assets/UnityShaderEditor/Editor/Styles/MatGraph.uss")]
public class MaterialGraphView : GraphView
{
public MaterialGraphView()
{
AddManipulator(new ContentZoomer());
AddManipulator(new ContentDragger());
AddManipulator(new RectangleSelector());
AddManipulator(new SelectionDragger());
AddManipulator(new ClickSelector());
AddManipulator(new ContextualMenu(DoContextMenu));
AddDecorator(new GridBackground(contentViewContainer));
}
public virtual bool CanAddToNodeMenu(Type type)
{
return true;
}
protected EventPropagation DoContextMenu(Event evt, Object customData)
{
var gm = new GenericMenu();
foreach (Type type in Assembly.GetAssembly(typeof(AbstractMaterialNode)).GetTypes())
{
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))))
{
var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[];
if (attrs != null && attrs.Length > 0 && CanAddToNodeMenu(type))
{
gm.AddItem(new GUIContent(attrs[0].m_Title), false, AddNode, new AddNodeCreationObject(type, evt.mousePosition));
}
}
}
//gm.AddSeparator("");
// gm.AddItem(new GUIContent("Convert To/SubGraph"), true, ConvertSelectionToSubGraph);
gm.ShowAsContext();
return EventPropagation.Stop;
}
private class AddNodeCreationObject : object
{
public Vector2 m_Pos;
public readonly Type m_Type;
public AddNodeCreationObject(Type t, Vector2 p)
{
m_Type = t;
m_Pos = p;
}
};
private void AddNode(object obj)
{
var posObj = obj as AddNodeCreationObject;
if (posObj == null)
return;
INode node;
try
{
node = Activator.CreateInstance(posObj.m_Type) as INode;
}
catch (Exception e)
{
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", posObj.m_Type, e);
return;
}
if (node == null)
return;
var drawstate = node.drawState;
drawstate.position = new Rect(posObj.m_Pos.x, posObj.m_Pos.y, drawstate.position.width, drawstate.position.height);
node.drawState = drawstate;
/*m_DataSource.Addnode(node);
Rebuild();
Repaint();*/
}
}
}

50
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeAnchorData.cs


using System;
using RMGUI.GraphView;
using RMGUI.GraphView.Demo;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
public class MaterialNodeAnchorData : NodeAnchorData
{
protected MaterialNodeAnchorData()
{}
public ISlot slot { get; private set; }
public void Initialize(ISlot slot)
{
this.slot = slot;
name = slot.displayName;
type = typeof(Vector4);
direction = slot.isInputSlot ? Direction.Input : Direction.Output;
}
}
}
using System;
using RMGUI.GraphView;
using RMGUI.GraphView.Demo;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
public class MaterialNodeAnchorData : NodeAnchorData
{
protected MaterialNodeAnchorData()
{}
public ISlot slot { get; private set; }
public void Initialize(ISlot slot)
{
this.slot = slot;
name = slot.displayName;
type = typeof(Vector4);
direction = slot.isInputSlot ? Direction.Input : Direction.Output;
}
}
}

1
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeData.cs


namespace UnityEditor.Graphing.Drawing
{
[Serializable]
public class ColorNodeData : MaterialNodeData
{

134
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/NullInputProxy.cs


using UnityEngine;
using UnityEngine.Graphing;
/*
namespace UnityEditor.Graphing.Drawing
{
public class NullInputProxy : CanvasElement
{
private ISlot m_InputSlot;
private INode m_Node;
private NodeAnchor m_NodeAnchor;
private const int kWidth = 180;
public NullInputProxy(INode node, ISlot inputSlot, NodeAnchor nodeAnchor)
{
m_InputSlot = inputSlot;
m_Node = node;
m_NodeAnchor = nodeAnchor;
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
nodeAnchor.AddDependency(this);
UpdateModel(UpdateType.Update);
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
AddManipulator(new ImguiContainer());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
base.Render(parentRect, canvas);
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
var rect = new Rect(0, 0, scale.x, scale.y);
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
//TODO: FIX
/*var changed = m_Node.DrawSlotDefaultInput(rect, m_InputSlot);
if (changed)
DrawableMaterialNode.RepaintDependentNodes(m_Node);*
}
public override void UpdateModel(UpdateType t)
{
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
base.UpdateModel(t);
}
}*/
using UnityEngine;
using UnityEngine.Graphing;
/*
namespace UnityEditor.Graphing.Drawing
{
public class NullInputProxy : CanvasElement
{
private ISlot m_InputSlot;
private INode m_Node;
private NodeAnchor m_NodeAnchor;
private const int kWidth = 180;
public NullInputProxy(INode node, ISlot inputSlot, NodeAnchor nodeAnchor)
{
m_InputSlot = inputSlot;
m_Node = node;
m_NodeAnchor = nodeAnchor;
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
nodeAnchor.AddDependency(this);
UpdateModel(UpdateType.Update);
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
AddManipulator(new ImguiContainer());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
base.Render(parentRect, canvas);
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
var rect = new Rect(0, 0, scale.x, scale.y);
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
//TODO: FIX
/*var changed = m_Node.DrawSlotDefaultInput(rect, m_InputSlot);
if (changed)
DrawableMaterialNode.RepaintDependentNodes(m_Node);*
}
public override void UpdateModel(UpdateType t)
{
var size = m_NodeAnchor.scale;
size.x = kWidth;
scale = size;
var position = m_NodeAnchor.canvasBoundingRect.min;
position.x -= kWidth;
translation = position;
base.UpdateModel(t);
}
}*/

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


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

INode GetNodeFromGuid(Guid guid);
T GetNodeFromGuid<T>(Guid guid) where T: INode;
T GetNodeFromGuid<T>(Guid guid) where T : INode;
IEnumerable<IEdge> GetEdges(SlotReference s);
void ValidateGraph();
}

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs


Guid RewriteGuid();
string name { get; set; }
bool canDeleteNode { get; }
IEnumerable<T> GetInputSlots<T>() where T: ISlot;
IEnumerable<T> GetOutputSlots<T>() where T: ISlot;
IEnumerable<T> GetSlots<T>() where T: ISlot;
IEnumerable<T> GetInputSlots<T>() where T : ISlot;
IEnumerable<T> GetOutputSlots<T>() where T : ISlot;
IEnumerable<T> GetSlots<T>() where T : ISlot;
T FindSlot<T>(int slotId) where T: ISlot;
T FindInputSlot<T>(int slotId) where T: ISlot;
T FindOutputSlot<T>(int slotId) where T: ISlot;
T FindSlot<T>(int slotId) where T : ISlot;
T FindInputSlot<T>(int slotId) where T : ISlot;
T FindOutputSlot<T>(int slotId) where T : ISlot;
IEnumerable<ISlot> GetInputsWithNoConnection();
DrawingData drawState { get; set; }
bool hasError { get; }

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs


public abstract class NodeControlData : GraphElementData
{
protected NodeControlData()
{ }
{}
public abstract void OnGUIHandler();
}

{
protected NodePreviewData()
{ }
{}
private MaterialGraphPreviewGenerator m_PreviewGenerator;

// TODO: this is a workaround right now.
if (m_Node is PixelShaderNode)
{
var localNode = (PixelShaderNode) m_Node;
var localNode = (PixelShaderNode)m_Node;
if (localNode == null)
return string.Empty;

32
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/PropertyNodeTests.cs


namespace UnityEditor.MaterialGraph.IntegrationTests
{
[TestFixtureSetUp]
public void RunBeforeAnyTests()
{

"IntegrationTests",
"Textures",
"MudDiffuse.tif"
};
private static Texture2D FindTestTexture()

m_TextureNode.GeneratePropertyBlock(generator, GenerationMode.SurfaceShader);
var expected1 = "[NonModifiableTextureData] "
+ m_TextureNode.propertyName
+ "(\""
+ m_TextureNode.description
+ "\", 2D) = \"bump\" {}"
+ Environment.NewLine;
+ m_TextureNode.propertyName
+ "(\""
+ m_TextureNode.description
+ "\", 2D) = \"bump\" {}"
+ Environment.NewLine;
+ "(\""
+ m_TextureNode.description
+ "\", 2D) = \"bump\" {}"
+ Environment.NewLine;
+ "(\""
+ m_TextureNode.description
+ "\", 2D) = \"bump\" {}"
+ Environment.NewLine;
m_TextureNode.exposedState = PropertyNode.ExposedState.Exposed;
generator = new PropertyGenerator();
m_TextureNode.GeneratePropertyBlock(generator, GenerationMode.SurfaceShader);

var generator = new ShaderGenerator();
m_TextureNode.GeneratePropertyUsages(generator, GenerationMode.SurfaceShader);
var expected = "sampler2D "
+ m_TextureNode.propertyName
+ ";"
+ Environment.NewLine;
+ m_TextureNode.propertyName
+ ";"
+ Environment.NewLine;
m_TextureNode.exposedState = PropertyNode.ExposedState.Exposed;
generator = new ShaderGenerator();
m_TextureNode.GeneratePropertyUsages(generator, GenerationMode.SurfaceShader);

402
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs


using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph.IntegrationTests
{
public class ShaderGenerationTest
{
private static readonly string[] s_Path =
{
"UnityShaderEditor",
"Editor",
"Testing",
"IntegrationTests",
"Graphs"
};
public struct TestInfo
{
public string name;
public FileInfo info;
public float threshold;
public override string ToString()
{
return name;
}
}
public static class CollectGraphs
{
public static IEnumerable graphs
{
get
{
var absoluteGraphsPath = s_Path.Aggregate(Application.dataPath, Path.Combine);
var filePaths = Directory.GetFiles(absoluteGraphsPath).Select(x => new FileInfo(x)).Where(x => x.Extension == ".ShaderGraph");
foreach (var p in filePaths)
{
yield return new TestInfo
{
name = p.Name,
info = p,
threshold = 0.02f
};
}
}
}
}
private Shader m_Shader;
private Material m_PreviewMaterial;
private Texture2D m_Captured;
private Texture2D m_FromDisk;
[TearDown]
public void CleanUp()
{
if (m_Shader != null)
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(m_Shader));
if (m_PreviewMaterial != null)
Object.DestroyImmediate(m_PreviewMaterial);
if (m_Captured != null)
Object.DestroyImmediate(m_Captured);
if (m_FromDisk != null)
Object.DestroyImmediate(m_FromDisk);
}
[Test, TestCaseSource(typeof(CollectGraphs), "graphs")]
public void ShaderGeneratorOutput(TestInfo testInfo)
{
var file = testInfo.info;
var prjRelativeGraphsPath = s_Path.Aggregate("Assets", Path.Combine);
var filePath = Path.Combine(prjRelativeGraphsPath, file.Name);
var graphAsset = AssetDatabase.LoadAssetAtPath<MaterialGraphAsset>(filePath);
Assert.IsNotNull(graphAsset, "Graph asset not found");
var materialGraph = graphAsset.graph as PixelGraph;
Assert.IsNotNull(materialGraph);
// Generate the shader
List<PropertyGenerator.TextureInfo> configuredTextures;
var shaderString = ShaderGenerator.GenerateSurfaceShader(materialGraph.pixelMasterNode, graphAsset.options, materialGraph.name, false, out configuredTextures);
m_Shader = ShaderUtil.CreateShaderAsset(shaderString);
m_Shader.hideFlags = HideFlags.HideAndDontSave;
Assert.IsNotNull(m_Shader, "Shader Generation Failed");
//Assert.IsFalse(AbstractMaterialNodeUI.ShaderHasError(m_Shader), "Shader has error");
m_PreviewMaterial = new Material(m_Shader)
{
hideFlags = HideFlags.HideAndDontSave
};
foreach (var textureInfo in configuredTextures)
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
m_PreviewMaterial.SetTexture(textureInfo.name, texture);
}
Assert.IsNotNull(m_PreviewMaterial, "preview material could not be created");
const int res = 256;
var generator = new MaterialGraphPreviewGenerator();
var rendered = generator.DoRenderPreview(m_PreviewMaterial, PreviewMode.Preview3D, new Rect(0, 0, res, res), 10) as RenderTexture;
Assert.IsNotNull(rendered, "Render failed");
RenderTexture.active = rendered;
m_Captured = new Texture2D(rendered.width, rendered.height, TextureFormat.ARGB32, false);
m_Captured.ReadPixels(new Rect(0, 0, rendered.width, rendered.height), 0, 0);
RenderTexture.active = null; //can help avoid errors
var rootPath = Directory.GetParent(Directory.GetParent(Application.dataPath).ToString());
var templatePath = Path.Combine(rootPath.ToString(), "ImageTemplates");
// find the reference image
var dumpFileLocation = Path.Combine(templatePath, string.Format("{0}.{1}", file.Name, "png"));
if (!File.Exists(dumpFileLocation))
{
// no reference exists, create it
Directory.CreateDirectory(templatePath);
var generated = m_Captured.EncodeToPNG();
File.WriteAllBytes(dumpFileLocation, generated);
Assert.Fail("Template file not found for {0}, creating it.", file);
}
var template = File.ReadAllBytes(dumpFileLocation);
m_FromDisk = new Texture2D(2,2);
m_FromDisk.LoadImage(template, false);
var areEqual = CompareTextures(m_FromDisk, m_Captured, testInfo.threshold);
if (!areEqual)
{
var failedPath = Path.Combine(rootPath.ToString(), "Failed");
Directory.CreateDirectory(failedPath);
var misMatchLocationResult = Path.Combine(failedPath, string.Format("{0}.{1}", file.Name, "png"));
var misMatchLocationTemplate = Path.Combine(failedPath, string.Format("{0}.template.{1}", file.Name, "png"));
var generated = m_Captured.EncodeToPNG();
File.WriteAllBytes(misMatchLocationResult, generated);
File.WriteAllBytes(misMatchLocationTemplate, template);
}
Assert.IsTrue(areEqual, "Shader from graph {0}, did not match .template file.", file);
}
private bool CompareTextures(Texture2D fromDisk, Texture2D captured, float threshold)
{
if (fromDisk == null || captured == null)
return false;
if (fromDisk.width != captured.width
|| fromDisk.height != captured.height)
return false;
var pixels1 = fromDisk.GetPixels();
var pixels2 = captured.GetPixels();
if (pixels1.Length != pixels2.Length)
return false;
for (int i = 0; i < pixels1.Length; i++)
{
if (!CompareColor(pixels1[i], pixels2[i], threshold))
return false;
}
return true;
}
private bool CompareColor(Vector4 left, Vector4 right, float threshold)
{
Vector4 diff = left - right;
if (Mathf.Abs(diff.x) > threshold)
return false;
if (Mathf.Abs(diff.y) > threshold)
return false;
if (Mathf.Abs(diff.z) > threshold)
return false;
if (Mathf.Abs(diff.w) > threshold)
return false;
return true;
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph.IntegrationTests
{
public class ShaderGenerationTest
{
private static readonly string[] s_Path =
{
"UnityShaderEditor",
"Editor",
"Testing",
"IntegrationTests",
"Graphs"
};
public struct TestInfo
{
public string name;
public FileInfo info;
public float threshold;
public override string ToString()
{
return name;
}
}
public static class CollectGraphs
{
public static IEnumerable graphs
{
get
{
var absoluteGraphsPath = s_Path.Aggregate(Application.dataPath, Path.Combine);
var filePaths = Directory.GetFiles(absoluteGraphsPath).Select(x => new FileInfo(x)).Where(x => x.Extension == ".ShaderGraph");
foreach (var p in filePaths)
{
yield return new TestInfo
{
name = p.Name,
info = p,
threshold = 0.02f
};
}
}
}
}
private Shader m_Shader;
private Material m_PreviewMaterial;
private Texture2D m_Captured;
private Texture2D m_FromDisk;
[TearDown]
public void CleanUp()
{
if (m_Shader != null)
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(m_Shader));
if (m_PreviewMaterial != null)
Object.DestroyImmediate(m_PreviewMaterial);
if (m_Captured != null)
Object.DestroyImmediate(m_Captured);
if (m_FromDisk != null)
Object.DestroyImmediate(m_FromDisk);
}
[Test, TestCaseSource(typeof(CollectGraphs), "graphs")]
public void ShaderGeneratorOutput(TestInfo testInfo)
{
var file = testInfo.info;
var prjRelativeGraphsPath = s_Path.Aggregate("Assets", Path.Combine);
var filePath = Path.Combine(prjRelativeGraphsPath, file.Name);
var graphAsset = AssetDatabase.LoadAssetAtPath<MaterialGraphAsset>(filePath);
Assert.IsNotNull(graphAsset, "Graph asset not found");
var materialGraph = graphAsset.graph as PixelGraph;
Assert.IsNotNull(materialGraph);
// Generate the shader
List<PropertyGenerator.TextureInfo> configuredTextures;
var shaderString = ShaderGenerator.GenerateSurfaceShader(materialGraph.pixelMasterNode, graphAsset.options, materialGraph.name, false, out configuredTextures);
m_Shader = ShaderUtil.CreateShaderAsset(shaderString);
m_Shader.hideFlags = HideFlags.HideAndDontSave;
Assert.IsNotNull(m_Shader, "Shader Generation Failed");
//Assert.IsFalse(AbstractMaterialNodeUI.ShaderHasError(m_Shader), "Shader has error");
m_PreviewMaterial = new Material(m_Shader)
{
hideFlags = HideFlags.HideAndDontSave
};
foreach (var textureInfo in configuredTextures)
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
m_PreviewMaterial.SetTexture(textureInfo.name, texture);
}
Assert.IsNotNull(m_PreviewMaterial, "preview material could not be created");
const int res = 256;
var generator = new MaterialGraphPreviewGenerator();
var rendered = generator.DoRenderPreview(m_PreviewMaterial, PreviewMode.Preview3D, new Rect(0, 0, res, res), 10) as RenderTexture;
Assert.IsNotNull(rendered, "Render failed");
RenderTexture.active = rendered;
m_Captured = new Texture2D(rendered.width, rendered.height, TextureFormat.ARGB32, false);
m_Captured.ReadPixels(new Rect(0, 0, rendered.width, rendered.height), 0, 0);
RenderTexture.active = null; //can help avoid errors
var rootPath = Directory.GetParent(Directory.GetParent(Application.dataPath).ToString());
var templatePath = Path.Combine(rootPath.ToString(), "ImageTemplates");
// find the reference image
var dumpFileLocation = Path.Combine(templatePath, string.Format("{0}.{1}", file.Name, "png"));
if (!File.Exists(dumpFileLocation))
{
// no reference exists, create it
Directory.CreateDirectory(templatePath);
var generated = m_Captured.EncodeToPNG();
File.WriteAllBytes(dumpFileLocation, generated);
Assert.Fail("Template file not found for {0}, creating it.", file);
}
var template = File.ReadAllBytes(dumpFileLocation);
m_FromDisk = new Texture2D(2, 2);
m_FromDisk.LoadImage(template, false);
var areEqual = CompareTextures(m_FromDisk, m_Captured, testInfo.threshold);
if (!areEqual)
{
var failedPath = Path.Combine(rootPath.ToString(), "Failed");
Directory.CreateDirectory(failedPath);
var misMatchLocationResult = Path.Combine(failedPath, string.Format("{0}.{1}", file.Name, "png"));
var misMatchLocationTemplate = Path.Combine(failedPath, string.Format("{0}.template.{1}", file.Name, "png"));
var generated = m_Captured.EncodeToPNG();
File.WriteAllBytes(misMatchLocationResult, generated);
File.WriteAllBytes(misMatchLocationTemplate, template);
}
Assert.IsTrue(areEqual, "Shader from graph {0}, did not match .template file.", file);
}
private bool CompareTextures(Texture2D fromDisk, Texture2D captured, float threshold)
{
if (fromDisk == null || captured == null)
return false;
if (fromDisk.width != captured.width
|| fromDisk.height != captured.height)
return false;
var pixels1 = fromDisk.GetPixels();
var pixels2 = captured.GetPixels();
if (pixels1.Length != pixels2.Length)
return false;
for (int i = 0; i < pixels1.Length; i++)
{
if (!CompareColor(pixels1[i], pixels2[i], threshold))
return false;
}
return true;
}
private bool CompareColor(Vector4 left, Vector4 right, float threshold)
{
Vector4 diff = left - right;
if (Mathf.Abs(diff.x) > threshold)
return false;
if (Mathf.Abs(diff.y) > threshold)
return false;
if (Mathf.Abs(diff.z) > threshold)
return false;
if (Mathf.Abs(diff.w) > threshold)
return false;
return true;
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/PropertyGeneratorTests.cs


Debug.logger.logHandler = new ConsoleLogHandler();
}
private const string kPropertyName = "ThePropertyName";
private const string kPropertyDescription = "ThePropertyDescription";

Assert.AreEqual(kPropertyName, infos[0].name);
Assert.AreEqual(0, infos[0].textureId);
Assert.AreEqual(TexturePropertyChunk.ModifiableState.Modifiable, infos[0].modifiable);
}
}
}

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/PropertyNodeTests.cs


Assert.AreEqual(expected, generator.GetShaderString(0));
}
[Test]
public void TestVector3NodeTypeIsCorrect()
{

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs


[Test]
public void AdaptNodeOutput2To4PreviewWorks()
{
var node = new TestNode();
var expected = string.Format("half4({0}.x, {0}.y, 0.0, 0.0)", node.GetVariableNameForSlot(TestNode.V2Out));
var result = ShaderGenerator.AdaptNodeOutputForPreview(node, TestNode.V2Out, ConcreteSlotValueType.Vector4);

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


return m_PixelGraph.GetMaterial();
}*/
public void PostCreate()
{
m_PixelGraph.AddNode(new PixelShaderNode());

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


base.AddNode(node);
}
/*
public Material GetMaterial()
{

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


{
public Texture2D texture;
}
public override bool hasPreview { get { return true; } }
#if UNITY_EDITOR

}
}
#else
public Texture2D defaultTexture {get;set;}
public Texture2D defaultTexture {get; set; }
#endif
public TextureType textureType

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


{
properties.Add(
new PreviewProperty
{
m_Name = GetVariableNameForSlot(slot.id),
m_PropType = PropertyType.Vector4,
m_Vector4 = slot.defaultValue
}
{
m_Name = GetVariableNameForSlot(slot.id),
m_PropType = PropertyType.Vector4,
m_Vector4 = slot.defaultValue
}
);
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs


[SerializeField]
private int serializedVersion = 0;
const int kCurrentSerializedVersion = 1;
private void DoUpgrade()
{
var helper = new SubGraphHelper();

m_SerializedSubGraph = EditorJsonUtility.ToJson(helper, true);
serializedVersion = kCurrentSerializedVersion;
m_SubGraphAssetGuid = string.Empty;
mark dirty damn
mark dirty damn
public MaterialSubGraphAsset subGraphAsset {get; set;}
public MaterialSubGraphAsset subGraphAsset {get; set; }
#endif
private SubGraph subGraph

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs


var line = lines[index];
for (var i = 0; i < shaderChunk.chunkIndentLevel + baseIndentLevel; i++)
sb.Append("\t");
sb.AppendLine(line);
}
}

正在加载...
取消
保存