浏览代码

fixing node drawing

/main
Tim Cooper 8 年前
当前提交
8c5f323e
共有 61 个文件被更改,包括 1825 次插入2244 次删除
  1. 750
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  2. 146
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphDataSource.cs
  3. 94
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialGraphNode.cs
  4. 55
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeData.cs
  5. 108
      MaterialGraphProject/Assets/NewUI/Editor/DataContainer.cs
  6. 4
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Data/MiniMapData.cs
  7. 2
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/CustomEdge.cs
  8. 40
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/Data/NodeData.cs
  9. 10
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/Data/VerticalNodeData.cs
  10. 54
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/MiniMap.cs
  11. 131
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/Data/IMGUISampleViewData.cs
  12. 14
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/Data/SimpleGraphView.cs
  13. 6
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/IMGUISampleView.cs
  14. 272
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.cs
  15. 3
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.cs
  16. 6
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleGraphView.cs
  17. 4
      MaterialGraphProject/Assets/NewUI/Editor/Elements/Data/EdgeData.cs
  18. 120
      MaterialGraphProject/Assets/NewUI/Editor/Elements/Data/GraphElementData.cs
  19. 90
      MaterialGraphProject/Assets/NewUI/Editor/Elements/Edge.cs
  20. 11
      MaterialGraphProject/Assets/NewUI/Editor/Elements/GraphElement.cs
  21. 23
      MaterialGraphProject/Assets/NewUI/Editor/Manipulators/Dragger.cs
  22. 12
      MaterialGraphProject/Assets/NewUI/Editor/Manipulators/EdgeConnector.cs
  23. 344
      MaterialGraphProject/Assets/NewUI/Editor/Manipulators/Resizer.cs
  24. 19
      MaterialGraphProject/Assets/NewUI/Editor/NodeAdapter.cs
  25. 64
      MaterialGraphProject/Assets/NewUI/Editor/Views/Data/GraphViewDataSource.cs
  26. 12
      MaterialGraphProject/Assets/NewUI/Editor/Views/GraphView.cs
  27. 25
      MaterialGraphProject/Assets/NewUI/Editor/Views/GraphView.uss
  28. 417
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs
  29. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Editors/MaterialGraphEditor.cs
  30. 22
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Styles/NodalView.uss
  31. 402
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs
  32. 2
      MaterialGraphProject/MaterialGraphProject.sln.DotSettings.user
  33. 2
      MaterialGraphProject/ProjectSettings/ProjectVersion.txt
  34. 25
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeAnchorData.cs
  35. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeAnchorData.cs.meta
  36. 43
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.uss
  37. 8
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.uss.meta
  38. 34
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.uss
  39. 8
      MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.uss.meta
  40. 11
      MaterialGraphProject/Assets/NewUI/Editor/Views/Data/IDataSource.cs
  41. 12
      MaterialGraphProject/Assets/NewUI/Editor/Views/Data/IDataSource.cs.meta
  42. 51
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs
  43. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs.meta
  44. 65
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs
  45. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs.meta
  46. 49
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/ColorNodeUI.cs
  47. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/ColorNodeUI.cs.meta
  48. 37
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/CombineNodeUI.cs
  49. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/CombineNodeUI.cs.meta
  50. 41
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector1NodeUI.cs
  51. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector1NodeUI.cs.meta
  52. 51
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector2NodeUI.cs
  53. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector2NodeUI.cs.meta
  54. 51
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector3NodeUI.cs
  55. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector3NodeUI.cs.meta
  56. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs.meta
  57. 55
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs
  58. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs.meta
  59. 39
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs
  60. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs.meta
  61. 87
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs

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


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using UnityEngine.RMGUI;
namespace UnityEditor.Graphing.Drawing
{
public class GraphEditWindow : AbstractGraphEditWindow<IGraphAsset>
{
[MenuItem("Window/Graph Editor")]
public static void OpenMenu()
{
GetWindow<GraphEditWindow>();
}
}
public abstract class AbstractGraphEditWindow<T> : EditorWindow, ISerializationCallbackReceiver where T : class, IGraphAsset
{
public RenderTexture rt;
[NonSerialized]
private T m_LastSelection;
[SerializeField]
private ScriptableObject m_LastSelectedGraphSerialized;
private bool shouldRepaint
{
get
{
return m_LastSelection != null && m_LastSelection.shouldRepaint;
}
}
private MaterialGraphView m_Contents;
void OnEnable()
{
m_Contents = new MaterialGraphView();
m_Contents.name = "theView";
m_Contents.dataProvider = new MaterialGraphDataSource(m_LastSelection);
m_Contents.StretchToParentSize();
windowRoot.AddChild(m_Contents);
}
void OnDisable()
{
windowRoot.ClearChildren();
}
void Update()
{
if (shouldRepaint)
Repaint();
}
void OnSelectionChange()
{
if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject))
return;
if (Selection.activeObject is ScriptableObject)
{
var selection = Selection.activeObject as T;
if (selection != m_LastSelection)
{
var graph = selection.graph;
graph.OnEnable();
graph.ValidateGraph();
m_LastSelection = selection;
m_Contents.dataProvider = new MaterialGraphDataSource(m_LastSelection);
m_Contents.StretchToParentSize();
m_Contents.OnDataChanged();
Repaint();
}
}
}
/*
private void ConvertSelectionToSubGraph()
{
if (m_Canvas.dataSource == null)
return;
var dataSource = m_Canvas.dataSource as GraphDataSource;
if (dataSource == null)
return;
var asset = dataSource.graphAsset;
if (asset == null)
return;
var targetGraph = asset.graph;
if (targetGraph == null)
return;
if (!m_Canvas.selection.Any())
return;
var serialzied = CopySelected.SerializeSelectedElements(m_Canvas);
var deserialized = CopySelected.DeserializeSelectedElements(serialzied);
if (deserialized == null)
return;
string path = EditorUtility.SaveFilePanelInProject("Save subgraph", "New SubGraph", "ShaderSubGraph", "");
path = path.Replace(Application.dataPath, "Assets");
if (path.Length == 0)
return;
var graphAsset = CreateInstance<MaterialSubGraphAsset>();
graphAsset.name = Path.GetFileName(path);
graphAsset.PostCreate();
var graph = graphAsset.subGraph;
if (graphAsset.graph == null)
return;
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in deserialized.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
graph.AddNode(node);
}
// remap outputs to the subgraph
var inputEdgeNeedsRemap = new List<IEdge>();
var outputEdgeNeedsRemap = new List<IEdge>();
foreach (var edge in deserialized.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
var outputRemapExists = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid);
var inputRemapExists = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid);
// pasting nice internal links!
if (outputRemapExists && inputRemapExists)
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
graph.Connect(outputSlotRef, inputSlotRef);
}
// one edge needs to go to outside world
else if (outputRemapExists)
{
inputEdgeNeedsRemap.Add(edge);
}
else if (inputRemapExists)
{
outputEdgeNeedsRemap.Add(edge);
}
}
// we do a grouping here as the same output can
// point to multiple inputs
var uniqueOutputs = outputEdgeNeedsRemap.GroupBy(edge => edge.outputSlot);
var inputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueOutputs)
{
var inputNode = graph.inputNode;
var slotId = inputNode.AddSlot();
var outputSlotRef = new SlotReference(inputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(outputSlotRef, new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId));
inputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
var uniqueInputs = inputEdgeNeedsRemap.GroupBy(edge => edge.inputSlot);
var outputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueInputs)
{
var outputNode = graph.outputNode;
var slotId = outputNode.AddSlot();
var inputSlotRef = new SlotReference(outputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
outputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
AssetDatabase.CreateAsset(graphAsset, path);
var subGraphNode = new SubGraphNode();
targetGraph.AddNode(subGraphNode);
subGraphNode.subGraphAsset = graphAsset;
foreach (var edgeMap in inputsNeedingConnection)
{
targetGraph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.outputSlot.slotId));
}
foreach (var edgeMap in outputsNeedingConnection)
{
targetGraph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot);
}
var toDelete = m_Canvas.selection.Where(x => x is DrawableNode).ToList();
dataSource.DeleteElements(toDelete);
targetGraph.ValidateGraph();
m_Canvas.ReloadData();
m_Canvas.Invalidate();
m_Canvas.selection.Clear();
var toSelect = m_Canvas.elements.OfType<DrawableNode>().FirstOrDefault(x => x.m_Node == subGraphNode);
if (toSelect != null)
{
toSelect.selected = true;
m_Canvas.selection.Add(toSelect);
}
m_Canvas.Repaint();
}
private void Rebuild()
{
if (m_Canvas == null || m_LastSelection == null)
return;
m_DataSource.graphAsset = m_LastSelection;
m_Canvas.ReloadData();
}*/
/* void OnGUI()
{
m_HostWindow = this;
if (m_Canvas == null)
{
InitializeCanvas();
}
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));
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, 140, 250, 50), "Export - quick"))
Export(true);
EditorGUI.ObjectField(new Rect(position.width - 250, 210, 250, 50), rt, typeof(RenderTexture), false);
}*/
private string m_LastPath;
public void Export(bool quickExport)
{
var path = quickExport ? m_LastPath : EditorUtility.SaveFilePanelInProject("Export shader to file...", "shader.shader", "shader", "Enter file name");
m_LastPath = path; // For quick exporting
/* if (!string.IsNullOrEmpty(path))
ExportShader(m_DataSource.graphAsset as MaterialGraphAsset, path);
else
EditorUtility.DisplayDialog("Export Shader Error", "Cannot export shader", "Ok");*/
}
public static Shader ExportShader(MaterialGraphAsset graphAsset, string path)
{
if (graphAsset == null)
return null;
var materialGraph = graphAsset.graph as PixelGraph;
if (materialGraph == null)
return null;
List<PropertyGenerator.TextureInfo> configuredTextures;
var shaderString = ShaderGenerator.GenerateSurfaceShader(materialGraph.pixelMasterNode, new MaterialOptions(), materialGraph.name, false, out configuredTextures);
File.WriteAllText(path, shaderString);
AssetDatabase.Refresh(); // Investigate if this is optimal
var shader = AssetDatabase.LoadAssetAtPath(path, typeof(Shader)) as Shader;
if (shader == null)
return null;
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)
return null;
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.Modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.NonModifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
// shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
shaderImporter.SaveAndReimport();
return shaderImporter.GetShader();
}
/*public void RenderOptions(MaterialGraph graph)
{
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.BeginVertical();
m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos, EditorStyles.textArea, GUILayout.width(250), GUILayout.ExpandHeight(true));
graph.materialOptions.DoGUI();
EditorGUILayout.Separator();
m_NodeExpanded = MaterialGraphStyles.Header("Selected", m_NodeExpanded);
if (m_NodeExpanded)
DrawableMaterialNode.OnGUI(m_Canvas.selection);
GUILayout.EndScrollView();
if (GUILayout.Button("Export"))
m_DataSource.Export(false);
GUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}*/
public void OnBeforeSerialize()
{
var o = m_LastSelection as ScriptableObject;
if (o != null)
m_LastSelectedGraphSerialized = o;
}
public void OnAfterDeserialize()
{
if (m_LastSelectedGraphSerialized != null)
m_LastSelection = m_LastSelectedGraphSerialized as T;
m_LastSelectedGraphSerialized = null;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using UnityEngine.RMGUI;
namespace UnityEditor.Graphing.Drawing
{
public class GraphEditWindow : AbstractGraphEditWindow<IGraphAsset>
{
[MenuItem("Window/Graph Editor")]
public static void OpenMenu()
{
GetWindow<GraphEditWindow>();
}
}
public abstract class AbstractGraphEditWindow<T> : EditorWindow, ISerializationCallbackReceiver where T : class, IGraphAsset
{
public RenderTexture rt;
[NonSerialized]
private T m_LastSelection;
[SerializeField]
private ScriptableObject m_LastSelectedGraphSerialized;
private bool shouldRepaint
{
get
{
return m_LastSelection != null && m_LastSelection.shouldRepaint;
}
}
private MaterialGraphView m_Contents;
void OnEnable()
{
m_Contents = new MaterialGraphView();
m_Contents.name = "theView";
m_Contents.dataProvider = new MaterialGraphDataSource(m_LastSelection);
m_Contents.StretchToParentSize();
windowRoot.AddChild(m_Contents);
}
void OnDisable()
{
windowRoot.ClearChildren();
}
void Update()
{
if (shouldRepaint)
Repaint();
}
void OnSelectionChange()
{
if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject))
return;
if (Selection.activeObject is ScriptableObject)
{
var selection = Selection.activeObject as T;
if (selection != m_LastSelection)
{
var graph = selection.graph;
graph.OnEnable();
graph.ValidateGraph();
m_LastSelection = selection;
m_Contents.dataProvider = new MaterialGraphDataSource(m_LastSelection);
m_Contents.StretchToParentSize();
m_Contents.OnDataChanged();
Repaint();
}
}
}
/*
private void ConvertSelectionToSubGraph()
{
if (m_Canvas.dataSource == null)
return;
var dataSource = m_Canvas.dataSource as GraphDataSource;
if (dataSource == null)
return;
var asset = dataSource.graphAsset;
if (asset == null)
return;
var targetGraph = asset.graph;
if (targetGraph == null)
return;
if (!m_Canvas.selection.Any())
return;
var serialzied = CopySelected.SerializeSelectedElements(m_Canvas);
var deserialized = CopySelected.DeserializeSelectedElements(serialzied);
if (deserialized == null)
return;
string path = EditorUtility.SaveFilePanelInProject("Save subgraph", "New SubGraph", "ShaderSubGraph", "");
path = path.Replace(Application.dataPath, "Assets");
if (path.Length == 0)
return;
var graphAsset = CreateInstance<MaterialSubGraphAsset>();
graphAsset.name = Path.GetFileName(path);
graphAsset.PostCreate();
var graph = graphAsset.subGraph;
if (graphAsset.graph == null)
return;
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in deserialized.GetNodes<INode>())
{
var oldGuid = node.guid;
var newGuid = node.RewriteGuid();
nodeGuidMap[oldGuid] = newGuid;
graph.AddNode(node);
}
// remap outputs to the subgraph
var inputEdgeNeedsRemap = new List<IEdge>();
var outputEdgeNeedsRemap = new List<IEdge>();
foreach (var edge in deserialized.edges)
{
var outputSlot = edge.outputSlot;
var inputSlot = edge.inputSlot;
Guid remappedOutputNodeGuid;
Guid remappedInputNodeGuid;
var outputRemapExists = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid);
var inputRemapExists = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid);
// pasting nice internal links!
if (outputRemapExists && inputRemapExists)
{
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId);
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId);
graph.Connect(outputSlotRef, inputSlotRef);
}
// one edge needs to go to outside world
else if (outputRemapExists)
{
inputEdgeNeedsRemap.Add(edge);
}
else if (inputRemapExists)
{
outputEdgeNeedsRemap.Add(edge);
}
}
// we do a grouping here as the same output can
// point to multiple inputs
var uniqueOutputs = outputEdgeNeedsRemap.GroupBy(edge => edge.outputSlot);
var inputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueOutputs)
{
var inputNode = graph.inputNode;
var slotId = inputNode.AddSlot();
var outputSlotRef = new SlotReference(inputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(outputSlotRef, new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId));
inputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
var uniqueInputs = inputEdgeNeedsRemap.GroupBy(edge => edge.inputSlot);
var outputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueInputs)
{
var outputNode = graph.outputNode;
var slotId = outputNode.AddSlot();
var inputSlotRef = new SlotReference(outputNode.guid, slotId);
foreach (var edge in group)
{
var newEdge = graph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
outputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
}
}
AssetDatabase.CreateAsset(graphAsset, path);
var subGraphNode = new SubGraphNode();
targetGraph.AddNode(subGraphNode);
subGraphNode.subGraphAsset = graphAsset;
foreach (var edgeMap in inputsNeedingConnection)
{
targetGraph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.outputSlot.slotId));
}
foreach (var edgeMap in outputsNeedingConnection)
{
targetGraph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot);
}
var toDelete = m_Canvas.selection.Where(x => x is DrawableNode).ToList();
dataSource.DeleteElements(toDelete);
targetGraph.ValidateGraph();
m_Canvas.ReloadData();
m_Canvas.Invalidate();
m_Canvas.selection.Clear();
var toSelect = m_Canvas.elements.OfType<DrawableNode>().FirstOrDefault(x => x.m_Node == subGraphNode);
if (toSelect != null)
{
toSelect.selected = true;
m_Canvas.selection.Add(toSelect);
}
m_Canvas.Repaint();
}
private void Rebuild()
{
if (m_Canvas == null || m_LastSelection == null)
return;
m_DataSource.graphAsset = m_LastSelection;
m_Canvas.ReloadData();
}*/
/* void OnGUI()
{
m_HostWindow = this;
if (m_Canvas == null)
{
InitializeCanvas();
}
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));
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, 140, 250, 50), "Export - quick"))
Export(true);
EditorGUI.ObjectField(new Rect(position.width - 250, 210, 250, 50), rt, typeof(RenderTexture), false);
}*/
private string m_LastPath;
public void Export(bool quickExport)
{
var path = quickExport ? m_LastPath : EditorUtility.SaveFilePanelInProject("Export shader to file...", "shader.shader", "shader", "Enter file name");
m_LastPath = path; // For quick exporting
var ds = m_Contents.dataProvider as MaterialGraphDataSource;
if (ds != null && !string.IsNullOrEmpty(path))
{
ExportShader (ds.graphAsset as MaterialGraphAsset, path);
}
else
EditorUtility.DisplayDialog("Export Shader Error", "Cannot export shader", "Ok");
}
public static Shader ExportShader(MaterialGraphAsset graphAsset, string path)
{
if (graphAsset == null)
return null;
var materialGraph = graphAsset.graph as PixelGraph;
if (materialGraph == null)
return null;
List<PropertyGenerator.TextureInfo> configuredTextures;
var shaderString = ShaderGenerator.GenerateSurfaceShader(materialGraph.pixelMasterNode, new MaterialOptions(), materialGraph.name, false, out configuredTextures);
File.WriteAllText(path, shaderString);
AssetDatabase.Refresh(); // Investigate if this is optimal
var shader = AssetDatabase.LoadAssetAtPath(path, typeof(Shader)) as Shader;
if (shader == null)
return null;
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)
return null;
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.Modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable == TexturePropertyChunk.ModifiableState.NonModifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
shaderImporter.SaveAndReimport();
return shaderImporter.GetShader();
}
/*public void RenderOptions(MaterialGraph graph)
{
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.BeginVertical();
m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos, EditorStyles.textArea, GUILayout.width(250), GUILayout.ExpandHeight(true));
graph.materialOptions.DoGUI();
EditorGUILayout.Separator();
m_NodeExpanded = MaterialGraphStyles.Header("Selected", m_NodeExpanded);
if (m_NodeExpanded)
DrawableMaterialNode.OnGUI(m_Canvas.selection);
GUILayout.EndScrollView();
if (GUILayout.Button("Export"))
m_DataSource.Export(false);
GUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}*/
public void OnBeforeSerialize()
{
var o = m_LastSelection as ScriptableObject;
if (o != null)
m_LastSelectedGraphSerialized = o;
}
public void OnAfterDeserialize()
{
if (m_LastSelectedGraphSerialized != null)
m_LastSelection = m_LastSelectedGraphSerialized as T;
m_LastSelectedGraphSerialized = null;
}
}
}

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


using System;
using System.Collections.Generic;
using System.Linq;
using RMGUI.GraphView;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
class MaterialGraphDataSource : IDataSource
{
private List<GraphElementData> m_Elements = new List<GraphElementData>();
public IGraphAsset graphAsset { get; private set; }
public MaterialGraphDataSource(IGraphAsset graphAsset)
{
this.graphAsset = graphAsset;
if (graphAsset == null)
return;
var drawableNodes = new List<MaterialNodeData>();
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
var nodeData = new MaterialNodeData(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);
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
{
get { return m_Elements; }
}
public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using RMGUI.GraphView;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[Serializable]
public class MaterialGraphDataSource : IDataSource
{
private List<GraphElementData> m_Elements = new List<GraphElementData>();
public IGraphAsset graphAsset { get; private set; }
public MaterialGraphDataSource(IGraphAsset graphAsset)
{
this.graphAsset = graphAsset;
if (graphAsset == null)
return;
var drawableNodes = new List<MaterialNodeData>();
foreach (var node in graphAsset.graph.GetNodes<INode>())
{
var 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);
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
{
get { return m_Elements; }
}
public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
}

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


using System.Linq;
using RMGUI.GraphView;
using RMGUI.GraphView.Demo;
using UnityEditor.MaterialGraph;
using UnityEngine;
using UnityEngine.RMGUI;
using UnityEngine.RMGUI.StyleEnums.Values;

[CustomDataView(typeof(MaterialNodeData))]
public class MaterialGraphNode : GraphElement
{
VisualContainer m_InputContainer;
VisualContainer m_OutputContainer;
VisualContainer m_SlotContainer;
// VisualContainer m_ControlsContainer;
VisualContainer m_PreviewContainer;
m_InputContainer = new VisualContainer
m_SlotContainer = new VisualContainer
name = "input", // for USS&Flexbox
flexDirection = FlexDirection.Column,
name = "slots", // for USS&Flexbox
m_OutputContainer = new VisualContainer
/* m_ControlsContainer = new VisualContainer
name = "output", // for USS&Flexbox
name = "controls", // for USS&Flexbox
flexDirection = FlexDirection.Column,
};*/
m_PreviewContainer = new VisualContainer
{
name = "preview", // for USS&Flexbox
pickingMode = PickingMode.Ignore,
AddChild(m_InputContainer);
AddChild(m_OutputContainer);
}
public override void DoRepaint(PaintContext painter)

}
}
public override void OnDataChanged()
private void AddSlots(MaterialNodeData nodeData)
base.OnDataChanged();
m_SlotContainer.ClearChildren();
m_OutputContainer.ClearChildren();
m_InputContainer.ClearChildren();
if (!nodeData.elements.OfType<NodeAnchorData>().Any())
return;
var nodeData = (MaterialNodeData) dataProvider;
var inputs = new VisualContainer
{
name = "input", // for USS&Flexbox
pickingMode = PickingMode.Ignore,
};
m_SlotContainer.AddChild(inputs);
if (nodeData == null)
return;
// put a spacer here?
//m_SlotContainer.AddChild(new f);
var outputs = new VisualContainer
{
name = "input", // for USS&Flexbox
pickingMode = PickingMode.Ignore,
};
m_SlotContainer.AddChild(outputs);
m_InputContainer.AddChild(new RMGUI.GraphView.Demo.NodeAnchor(anchor));
inputs.AddChild(new NodeAnchor(anchor));
m_OutputContainer.AddChild(new RMGUI.GraphView.Demo.NodeAnchor(anchor));
outputs.AddChild(new NodeAnchor(anchor));
}
AddChild(m_SlotContainer);
}
private void AddPreview(MaterialNodeData nodeData)
{
m_PreviewContainer.ClearChildren();
if (!nodeData.elements.OfType<NodePreviewData>().Any())
return;
foreach (var preview in nodeData.elements.OfType<NodePreviewData>())
{
var image = preview.Render(new Vector2(200, 200));
m_PreviewContainer.AddChild(new Image { image = image });
AddChild(m_PreviewContainer);
}
public override void OnDataChanged()
{
base.OnDataChanged();
ClearChildren();
// m_ControlsContainer.ClearChildren();
m_PreviewContainer.ClearChildren();
var nodeData = dataProvider as MaterialNodeData;
if (nodeData == null)
return;
AddSlots(nodeData);
AddPreview(nodeData);
positionType = PositionType.Absolute;
positionLeft = nodeData.node.drawState.position.x;
positionTop = nodeData.node.drawState.position.y;
}
}
}

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


using System;
using System.Collections.Generic;
using System.Linq;
using RMGUI.GraphView.Demo;
using UnityEngine;
using UnityEditor.MaterialGraph;
using UnityEngine.MaterialGraph;
[Serializable]
public class MaterialNodeAnchorData : NodeAnchorData
{
public ISlot slot { get; private set; }
public MaterialNodeAnchorData(ISlot slot)
{
this.slot = slot;
name = slot.displayName;
type = typeof(Vector4);
direction = slot.isInputSlot ? Direction.Input : Direction.Output;
}
}
[Serializable]
public class MaterialNodeData : GraphElementData
{
[Serializable]
public class MaterialNodeData : GraphElementData
{
protected List<NodeAnchorData> m_Anchors = new List<NodeAnchorData>();
protected List<GraphElementData> m_Children = new List<GraphElementData>();
get { return m_Anchors.OfType<GraphElementData>(); }
get { return m_Children; }
public MaterialNodeData(INode inNode)
protected MaterialNodeData()
{}
public void Initialize(INode inNode)
capabilities |= Capabilities.Movable;
name = inNode.name;
name = inNode.name;
m_Anchors.Add(new MaterialNodeAnchorData(input));
var data = CreateInstance<MaterialNodeAnchorData>();
data.Initialize(input);
m_Children.Add(data);
position = new Rect(node.drawState.position.x, node.drawState.position.y, 100, 200);
capabilities |= Capabilities.Movable;
var materialNode = inNode as AbstractMaterialNode;
if (materialNode == null || !materialNode.hasPreview)
return;
var previewData = CreateInstance<NodePreviewData>();
previewData.Initialize(materialNode);
m_Children.Add(previewData);
//position = new Rect(node.drawState.position.x, node.drawState.position.y, 100, 200);
//position
}
}

108
MaterialGraphProject/Assets/NewUI/Editor/DataContainer.cs


using UnityEngine.RMGUI;
using Object = UnityEngine.Object;
namespace RMGUI.GraphView
{
public class DataContainer : VisualContainer
{
IDataSource m_DataProvider;
public IDataSource dataProvider
{
get { return m_DataProvider; }
set
{
if (m_DataProvider == value)
return;
RemoveWatch();
m_DataProvider = value;
OnDataChanged();
AddWatch();
}
}
public T GetData<T>() where T : GraphElementData
{
return dataProvider as T;
}
void AddWatch()
{
if (m_DataProvider != null && panel != null && m_DataProvider is Object)
// TODO: consider a disposable handle?
DataWatchService.AddDataSpy(this, (Object) m_DataProvider, OnDataChanged);
}
void RemoveWatch()
{
if (m_DataProvider != null && panel != null && m_DataProvider is Object)
DataWatchService.RemoveDataSpy((Object) m_DataProvider, OnDataChanged);
}
public DataContainer()
{
// trigger data source reset when entering leaving panel
onEnter += AddWatch;
onLeave += RemoveWatch;
}
// called when Serialized object has changed
// only works while widget is in a panel
public virtual void OnDataChanged()
{}
}
}
using UnityEngine.RMGUI;
using Object = UnityEngine.Object;
namespace RMGUI.GraphView
{
public class DataContainer : VisualContainer
{
IDataSource m_DataProvider;
public IDataSource dataProvider
{
get { return m_DataProvider; }
set
{
if (m_DataProvider == value)
return;
RemoveWatch();
m_DataProvider = value;
OnDataChanged();
AddWatch();
}
}
public T GetData<T>() where T : GraphElementData
{
return dataProvider as T;
}
void AddWatch()
{
if (m_DataProvider != null && panel != null && m_DataProvider is Object)
// TODO: consider a disposable handle?
DataWatchService.AddDataSpy(this, (Object) m_DataProvider, OnDataChanged);
}
void RemoveWatch()
{
if (m_DataProvider != null && panel != null && m_DataProvider is Object)
DataWatchService.RemoveDataSpy((Object) m_DataProvider, OnDataChanged);
}
public DataContainer()
{
// trigger data source reset when entering leaving panel
onEnter += AddWatch;
onLeave += RemoveWatch;
}
// called when Serialized object has changed
// only works while widget is in a panel
public virtual void OnDataChanged()
{}
}
}

4
MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Data/MiniMapData.cs


using System;
using UnityEngine;
namespace RMGUI.GraphView.Demo
{

public float maxHeight;
public float maxWidth;
[SerializeField]
public bool anchored;
}
}

2
MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/CustomEdge.cs


return;
}
IConnectable leftData = edgeData.Left;
IConnectable leftData = edgeData.left;
if (leftData == null)
return;

40
MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/Data/NodeData.cs


m_Anchors = new List<NodeAnchorData>();
// This is a demo version. We could have a ctor that takes in input and output types, etc.
var na = CreateInstance<NodeAnchorData>();
na.type = typeof (int);
na.direction = Direction.Input;
m_Anchors.Add(na);
var nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.type = typeof (int);
nodeAnchorData.direction = Direction.Input;
m_Anchors.Add(nodeAnchorData);
na = CreateInstance<NodeAnchorData>();
na.type = typeof (float);
na.direction = Direction.Input;
m_Anchors.Add(na);
nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.type = typeof (float);
nodeAnchorData.direction = Direction.Input;
m_Anchors.Add(nodeAnchorData);
na = CreateInstance<NodeAnchorData>();
na.type = typeof (Vector3);
na.direction = Direction.Input;
m_Anchors.Add(na);
nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.type = typeof (Vector3);
nodeAnchorData.direction = Direction.Input;
m_Anchors.Add(nodeAnchorData);
na = CreateInstance<NodeAnchorData>();
na.type = typeof (Texture2D);
na.direction = Direction.Input;
m_Anchors.Add(na);
nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.type = typeof (Texture2D);
nodeAnchorData.direction = Direction.Input;
m_Anchors.Add(nodeAnchorData);
na = CreateInstance<NodeAnchorData>();
na.type = typeof (Color);
na.direction = Direction.Input;
m_Anchors.Add(na);
nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.type = typeof (Color);
nodeAnchorData.direction = Direction.Input;
m_Anchors.Add(nodeAnchorData);
outputAnchor = CreateInstance<NodeAnchorData>();
outputAnchor.type = typeof(int);

10
MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/Graph/Data/VerticalNodeData.cs


base.OnEnable();
m_Anchors.Clear();
var vna = CreateInstance<NodeAnchorData>();
vna.orientation = Orientation.Vertical;
vna.direction = Direction.Input;
vna.type = typeof(float);
m_Anchors.Add(vna);
var nodeAnchorData = CreateInstance<NodeAnchorData>();
nodeAnchorData.orientation = Orientation.Vertical;
nodeAnchorData.direction = Direction.Input;
nodeAnchorData.type = typeof(float);
m_Anchors.Add(nodeAnchorData);
outputAnchor = CreateInstance<NodeAnchorData>();
outputAnchor.type = typeof (float);

54
MaterialGraphProject/Assets/NewUI/Editor/Demo/Elements/MiniMap.cs


private float m_PreviousContainerWidth = -1;
private float m_PreviousContainerHeight = -1;
private Dragger m_Dragger;
clipChildren = true; // TODO this is the source of UNI-459
clipChildren = false;
AddManipulator(new Dragger {activateButton = MouseButton.LeftMouse, clampToParentEdges = true});
m_Dragger = new Dragger {activateButton = MouseButton.LeftMouse, clampToParentEdges = true};
AddManipulator(new ContextualMenu((evt, customData) =>
{
var boxData = dataProvider as MiniMapData;
if (boxData != null)
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent(boxData.anchored ? "Make floating" : "Anchor"), false,
contentView =>
{
var bData = dataProvider as MiniMapData;
if (bData != null)
bData.anchored = !bData.anchored;
},
this);
menu.ShowAsContext();
}
return EventPropagation.Continue;
}));
AdjustAnchoring();
private void AdjustAnchoring()
{
var miniMapData = dataProvider as MiniMapData;
if (miniMapData == null)
{
return;
}
// TODO we might want to update the movable capability...
if (miniMapData.anchored)
{
RemoveManipulator(m_Dragger);
ResetPositionProperties();
AddToClassList("anchored");
}
else
{
AddManipulator(m_Dragger);
RemoveFromClassList("anchored");
}
}
private void Resize()
{
var miniMapData = dataProvider as MiniMapData;

public override void DoRepaint(PaintContext args)
{
var gView = this.GetFirstAncestorOfType<GraphView>();
var container = gView.contentViewContainer;
VisualContainer container = gView.contentViewContainer;
Matrix4x4 containerTransform = container.globalTransform;
Vector4 containerTranslation = containerTransform.GetColumn(3);

var containerWidth = parent.position.width / containerScale.x;
var containerHeight = parent.position.height / containerScale.y;
float containerWidth = parent.position.width / containerScale.x;
float containerHeight = parent.position.height / containerScale.y;
if ( (containerWidth != m_PreviousContainerWidth || containerHeight != m_PreviousContainerHeight) && dataProvider != null)
{

131
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/Data/IMGUISampleViewData.cs


using UnityEditor;
using UnityEngine;
namespace RMGUI.GraphView.Demo
{
public class IMGUISampleElementData : IMGUIData
{
private int m_ControlInteger;
private bool m_GUIToggle;
private float m_GUIFloatValue = 42.0f;
private string m_SomeText = "<enter some text>";
public override void OnGUIHandler()
{
EventType t = Event.current.type;
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, position.width, position.height), selected ? selectedColor : backgroundColor);
GUILayout.BeginVertical();
GUILayout.Label("Layout begins here");
GUILayout.Label("X = " + position.x + " Y = " + position.y + " W = " + position.width + " H = " + position.height);
if (GUILayout.Button("Layout Buttton" + m_ControlInteger, GUILayout.Width(150)))
{
m_ControlInteger++;
Debug.Log("Layout Button was pressed: " + m_ControlInteger);
}
m_GUIToggle = GUILayout.Toggle(m_GUIToggle, "GUI Toggle");
m_GUIFloatValue = GUILayout.HorizontalSlider(m_GUIFloatValue, 0.0f, 100.0f, GUILayout.Width(150));
m_SomeText = GUILayout.TextField(m_SomeText, GUILayout.Width(200));
GUILayout.Label("Layout ends here");
GUILayout.EndVertical();
float y = 150.0f;
GUI.Label(new Rect(0, y, 150, 30), "No-layout begins here");
if (GUI.Button(new Rect(0, y + 30.0f, 120, 30), "GUI Button:" + m_ControlInteger))
{
m_ControlInteger++;
Debug.Log("GUI Button was pressed: " + m_ControlInteger);
}
m_GUIToggle = GUI.Toggle(new Rect(120, y + 30.0f, 120, 30), m_GUIToggle, "GUI Toggle");
m_GUIFloatValue = GUI.HorizontalSlider(new Rect(0, y + 60.0f, 120, 30), m_GUIFloatValue, 0.0f, 100.0f);
GUI.Label(new Rect(0, y + 90.0f, 120, 30), "No-layout ends here");
}
}
public class IMGUISampleViewData : GraphViewDataSource
{
protected new void OnEnable()
{
var imguiSample = CreateInstance<IMGUISampleElementData>();
imguiSample.position = new Rect(100, 200, 230, 300);
imguiSample.title = "IMGUIControls: modal";
imguiSample.capabilities |= Capabilities.Resizable;
AddElement(imguiSample);
}
}
}
using UnityEditor;
using UnityEngine;
namespace RMGUI.GraphView.Demo
{
public class IMGUISampleElementData : IMGUIData
{
private int m_ControlInteger;
private bool m_GUIToggle;
private float m_GUIFloatValue = 42.0f;
private string m_SomeText = "<enter some text>";
public override void OnGUIHandler()
{
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, position.width, position.height), selected ? selectedColor : backgroundColor);
GUILayout.BeginVertical();
GUILayout.Label("Layout begins here");
GUILayout.Label("X = " + position.x + " Y = " + position.y + " W = " + position.width + " H = " + position.height);
if (GUILayout.Button("Layout Buttton" + m_ControlInteger, GUILayout.Width(150)))
{
m_ControlInteger++;
Debug.Log("Layout Button was pressed: " + m_ControlInteger);
}
m_GUIToggle = GUILayout.Toggle(m_GUIToggle, "GUI Toggle");
m_GUIFloatValue = GUILayout.HorizontalSlider(m_GUIFloatValue, 0.0f, 100.0f, GUILayout.Width(150));
m_SomeText = GUILayout.TextField(m_SomeText, GUILayout.Width(200));
GUILayout.Label("Layout ends here");
GUILayout.EndVertical();
float y = 150.0f;
GUI.Label(new Rect(0, y, 150, 30), "No-layout begins here");
if (GUI.Button(new Rect(0, y + 30.0f, 120, 30), "GUI Button:" + m_ControlInteger))
{
m_ControlInteger++;
Debug.Log("GUI Button was pressed: " + m_ControlInteger);
}
m_GUIToggle = GUI.Toggle(new Rect(120, y + 30.0f, 120, 30), m_GUIToggle, "GUI Toggle");
m_GUIFloatValue = GUI.HorizontalSlider(new Rect(0, y + 60.0f, 120, 30), m_GUIFloatValue, 0.0f, 100.0f);
GUI.Label(new Rect(0, y + 90.0f, 120, 30), "No-layout ends here");
}
}
public class IMGUISampleViewData : GraphViewDataSource
{
protected void OnEnable()
{
var imguiSample = CreateInstance<IMGUISampleElementData>();
imguiSample.position = new Rect(100, 200, 230, 300);
imguiSample.title = "IMGUIControls: modal";
imguiSample.capabilities |= Capabilities.Resizable;
AddElement(imguiSample);
}
}
}

14
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/Data/SimpleGraphView.cs


resizableElementData.position = new Rect(400, 100, 100, 100);
resizableElementData.title = "Resizable element";
resizableElementData.capabilities |= Capabilities.Resizable;
AddElement(resizableElementData);
AddElement(resizableElementData);
AddElement(imguiSampleData);
AddElement(imguiSampleData);
AddElement(movableElementData);
AddElement(movableElementData);
AddElement(miniMapData);
AddElement(miniMapData);
AddElement(circleData);
AddElement(circleData);
AddElement(wwwImageData);
AddElement(wwwImageData);
AddElement(invisibleBorderContainerData);
AddElement(invisibleBorderContainerData);
}
}
}

6
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/IMGUISampleView.cs


void OnEnable()
{
var zeView = new SimpleContentView
var view = new SimpleContentView
zeView.StretchToParentSize();
windowRoot.AddChild(zeView);
view.StretchToParentSize();
windowRoot.AddChild(view);
}
void OnDisable()

272
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.RMGUI;
namespace RMGUI.GraphView.Demo
{
[StyleSheet("Assets/Editor/Demo/NodalView.uss")]
class NodesContentView : SimpleContentView
{
System.Random rnd = new System.Random();
public NodesContentView()
{
// Shortcut handler to delete elements
var dictionary = new Dictionary<Event, ShortcutDelegate>();
dictionary[Event.KeyboardEvent("delete")] = DeleteSelection;
contentViewContainer.AddManipulator(new ShortcutHandler(dictionary));
// Contextual menu to create new nodes
contentViewContainer.AddManipulator(new ContextualMenu((evt, customData) =>
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("Create Operator"), false,
contentView => CreateOperator(),
this);
menu.ShowAsContext();
return EventPropagation.Continue;
}));
}
public void CreateOperator()
{
NodalViewData nodalViewData = dataProvider as NodalViewData;
if (nodalViewData != null)
{
var x = rnd.Next(0, 600);
var y = rnd.Next(0, 300);
nodalViewData.CreateOperator(typeof(Vector3), new Rect(x, y, 200, 176), "Shiny New Operator");
}
}
// TODO: this has data model knowledge, move this to GraphData
private EventPropagation DeleteSelection()
{
// and DeleteSelection would call that method.
var nodalViewData = dataProvider as NodalViewData;
if (nodalViewData == null)
return EventPropagation.Stop;
// TODO We will want to move this up to GraphView
var elementsToRemove = new List<GraphElementData>();
foreach (var selectedElement in selection.Cast<GraphElement>()
.Where(e => e != null && e.dataProvider != null))
{
var nodeData = selectedElement.dataProvider as NodeData;
if (nodeData != null)
{
// If there are connected edges, disconnect first (if such functionality is available) and delete
foreach (var element in allElements.OfType<GraphElement>())
{
var edge = element as Edge;
if (edge == null) continue;
var edgeData = edge.dataProvider as EdgeData;
if (edgeData == null) continue;
// Try output anchor first
if ((edgeData.Left != null && edgeData.Left == (IConnectable)nodeData.outputAnchor) ||
(edgeData.Right != null && edgeData.Right == (IConnectable)nodeData.outputAnchor))
{
elementsToRemove.Add(edgeData);
continue;
}
// Check each input anchor
if (nodeData.anchors.Any(a => (edgeData.Left != null && edgeData.Left == (IConnectable)a) ||
(edgeData.Right != null && edgeData.Right == (IConnectable)a)))
{
elementsToRemove.Add(edgeData);
}
}
}
elementsToRemove.Add(selectedElement.GetData<GraphElementData>());
}
// Notify node anchors of deconnection
foreach (var edgeData in elementsToRemove.OfType<EdgeData>())
{
if (edgeData.Left != null)
{
edgeData.Left.connected = false;
}
if (edgeData.Right != null)
{
edgeData.Right.connected = false;
}
}
foreach (var b in elementsToRemove.OfType<GraphElementData>())
nodalViewData.RemoveElement(b);
return EventPropagation.Stop;
}
}
class NodalView : EditorWindow
{
[MenuItem("Window/GraphView Demo/Nodal UI")]
public static void ShowWindow()
{
GetWindow<NodalView>();
}
void OnEnable()
{
var zeView = new NodesContentView
{
name = "theView",
dataProvider = CreateInstance<NodalViewData>()
};
zeView.StretchToParentSize();
windowRoot.AddChild(zeView);
}
void OnDisable()
{
windowRoot.ClearChildren();
}
}
}
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.RMGUI;
namespace RMGUI.GraphView.Demo
{
[StyleSheet("Assets/Editor/Demo/Views/NodalView.uss")]
class NodesContentView : SimpleContentView
{
System.Random rnd = new System.Random();
public NodesContentView()
{
// Shortcut handler to delete elements
var dictionary = new Dictionary<Event, ShortcutDelegate>();
dictionary[Event.KeyboardEvent("delete")] = DeleteSelection;
contentViewContainer.AddManipulator(new ShortcutHandler(dictionary));
// Contextual menu to create new nodes
contentViewContainer.AddManipulator(new ContextualMenu((evt, customData) =>
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("Create Operator"), false,
contentView => CreateOperator(),
this);
menu.ShowAsContext();
return EventPropagation.Continue;
}));
}
public void CreateOperator()
{
NodalViewData nodalViewData = dataProvider as NodalViewData;
if (nodalViewData != null)
{
var x = rnd.Next(0, 600);
var y = rnd.Next(0, 300);
nodalViewData.CreateOperator(typeof(Vector3), new Rect(x, y, 200, 176), "Shiny New Operator");
}
}
// TODO: this has data model knowledge, move this to GraphData
private EventPropagation DeleteSelection()
{
// and DeleteSelection would call that method.
var nodalViewData = dataProvider as NodalViewData;
if (nodalViewData == null)
return EventPropagation.Stop;
// TODO We will want to move this up to GraphView
var elementsToRemove = new List<GraphElementData>();
foreach (var selectedElement in selection.Cast<GraphElement>()
.Where(e => e != null && e.dataProvider != null))
{
var nodeData = selectedElement.dataProvider as NodeData;
if (nodeData != null)
{
// If there are connected edges, disconnect first (if such functionality is available) and delete
foreach (var element in allElements.OfType<GraphElement>())
{
var edge = element as Edge;
if (edge == null) continue;
var edgeData = edge.dataProvider as EdgeData;
if (edgeData == null) continue;
// Try output anchor first
if ((edgeData.left != null && edgeData.left == (IConnectable)nodeData.outputAnchor) ||
(edgeData.right != null && edgeData.right == (IConnectable)nodeData.outputAnchor))
{
elementsToRemove.Add(edgeData);
continue;
}
// Check each input anchor
if (nodeData.anchors.Any(a => (edgeData.left != null && edgeData.left == (IConnectable)a) ||
(edgeData.right != null && edgeData.right == (IConnectable)a)))
{
elementsToRemove.Add(edgeData);
}
}
}
elementsToRemove.Add(selectedElement.GetData<GraphElementData>());
}
// Notify node anchors of deconnection
foreach (var edgeData in elementsToRemove.OfType<EdgeData>())
{
if (edgeData.left != null)
{
edgeData.left.connected = false;
}
if (edgeData.right != null)
{
edgeData.right.connected = false;
}
}
foreach (var b in elementsToRemove)
nodalViewData.RemoveElement(b);
return EventPropagation.Stop;
}
}
class NodalView : EditorWindow
{
[MenuItem("Window/GraphView Demo/Nodal UI")]
public static void ShowWindow()
{
GetWindow<NodalView>();
}
void OnEnable()
{
var view = new NodesContentView
{
name = "theView",
dataProvider = CreateInstance<NodalViewData>()
};
view.StretchToParentSize();
windowRoot.AddChild(view);
}
void OnDisable()
{
windowRoot.ClearChildren();
}
}
}

3
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.cs


using UnityEngine;
using UnityEngine.RMGUI;
[StyleSheet("Assets/Editor/Demo/Views/SimpleContentView.uss")]
public class SimpleContentView : GraphView
{
public SimpleContentView()

6
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleGraphView.cs


void OnEnable()
{
var zeView = new SimpleContentView
var view = new SimpleContentView
zeView.StretchToParentSize();
view.StretchToParentSize();
windowRoot.AddChild(zeView);
windowRoot.AddChild(view);
}
void OnDisable()

4
MaterialGraphProject/Assets/NewUI/Editor/Elements/Data/EdgeData.cs


[Serializable]
internal class EdgeData : GraphElementData
{
public IConnectable Left;
public IConnectable Right;
public IConnectable left;
public IConnectable right;
public Vector2 candidatePosition;
public bool candidate;

120
MaterialGraphProject/Assets/NewUI/Editor/Elements/Data/GraphElementData.cs


using System;
using System.Collections.Generic;
using UnityEngine;
namespace RMGUI.GraphView
{
[Serializable]
public abstract class GraphElementData : ScriptableObject, IDataSource
{
[SerializeField]
private bool m_Selected;
[SerializeField]
private Rect m_Position;
[SerializeField]
private Capabilities m_Capabilities;
public Rect position
{
get { return m_Position; }
set { m_Position = 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;
}
public virtual IEnumerable<GraphElementData> elements
{
get { return new GraphElementData[0]; }
}
public virtual void AddElement(GraphElementData element)
{}
public virtual void RemoveElement(GraphElementData element)
{}
public Capabilities capabilities
{
get { return m_Capabilities; }
set { m_Capabilities = value; }
}
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
namespace RMGUI.GraphView
{
[Serializable]
public abstract class GraphElementData : ScriptableObject, IDataSource
{
[SerializeField]
private bool m_Selected;
[SerializeField]
private Rect m_Position;
[SerializeField]
private Capabilities m_Capabilities;
public Rect position
{
get { return m_Position; }
set { m_Position = 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;
}
public virtual IEnumerable<GraphElementData> elements
{
get { return new GraphElementData[0]; }
}
public virtual void AddElement(GraphElementData element)
{}
public virtual void RemoveElement(GraphElementData element)
{}
public Capabilities capabilities
{
get { return m_Capabilities; }
set { m_Capabilities = value; }
}
}
}

90
MaterialGraphProject/Assets/NewUI/Editor/Elements/Edge.cs


}
protected static void GetTangents(Direction direction, Orientation orientation, Vector2 start, Vector2 end, out Vector3[] points, out Vector3[] tangents)
{
if (direction == Direction.Output)
{
Vector2 t = end;
end = start;
start = t;
}
{
if (direction == Direction.Output)
{
Vector2 t = end;
end = start;
start = t;
}
bool invert = false;
if (end.x < start.x)
{
Vector3 t = start;
start = end;
end = t;
invert = true;
}
bool invert = false;
if (end.x < start.x)
{
Vector3 t = start;
start = end;
end = t;
invert = true;
}
points = new Vector3[] {start, end};
tangents = new Vector3[2];
points = new Vector3[] {start, end};
tangents = new Vector3[2];
const float minTangent = 30;
const float minTangent = 30;
float weight = .5f;
float weight2 = 1 - weight;
float y = 0;
float weight = .5f;
float weight2 = 1 - weight;
float y = 0;
float cleverness = Mathf.Clamp01(((start - end).magnitude - 10) / 50);
float cleverness = Mathf.Clamp01(((start - end).magnitude - 10) / 50);
if (orientation == Orientation.Horizontal)
{
tangents[0] = start + new Vector2((end.x - start.x) * weight + minTangent, y) * cleverness;
tangents[1] = end + new Vector2((end.x - start.x) * -weight2 - minTangent, -y) * cleverness;
}
else
{
float inverse = (invert) ? 1.0f : -1.0f;
tangents[0] = start + new Vector2(y, inverse * ((end.x - start.x) * weight + minTangent)) * cleverness;
tangents[1] = end + new Vector2(-y, inverse * ((end.x - start.x) * -weight2 - minTangent)) * cleverness;
}
}
if (orientation == Orientation.Horizontal)
{
tangents[0] = start + new Vector2((end.x - start.x) * weight + minTangent, y) * cleverness;
tangents[1] = end + new Vector2((end.x - start.x) * -weight2 - minTangent, -y) * cleverness;
}
else
{
float inverse = (invert) ? 1.0f : -1.0f;
tangents[0] = start + new Vector2(y, inverse * ((end.x - start.x) * weight + minTangent)) * cleverness;
tangents[1] = end + new Vector2(-y, inverse * ((end.x - start.x) * -weight2 - minTangent)) * cleverness;
}
}
public override bool Overlaps(Rect rect)
{

if (edgeData == null)
return false;
IConnectable leftData = edgeData.Left;
IConnectable rightData = edgeData.Right ?? leftData;
IConnectable leftData = edgeData.left;
IConnectable rightData = edgeData.right ?? leftData;
if (leftData == null || rightData == null)
return false;

if (edgeData == null)
return false;
IConnectable leftData = edgeData.Left;
IConnectable rightData = edgeData.Right ?? leftData;
IConnectable leftData = edgeData.left;
IConnectable rightData = edgeData.right ?? leftData;
if (leftData == null || rightData == null)
return false;

// exclude endpoints
if (Vector2.Distance(from, localPoint) <= 2 * k_EndPointRadius ||
Vector2.Distance(to, localPoint) <= 2 * k_EndPointRadius)
if (Vector2.Distance(from, localPoint) <= 2*k_EndPointRadius ||
Vector2.Distance(to, localPoint) <= 2*k_EndPointRadius)
{
return false;
}

if (edgeData == null)
return;
IConnectable leftData = edgeData.Left;
IConnectable rightData = edgeData.Right ?? leftData;
IConnectable leftData = edgeData.left;
IConnectable rightData = edgeData.right ?? leftData;
if (leftData == null)
return;

if (edgeData == null)
return;
IConnectable leftData = edgeData.Left;
IConnectable leftData = edgeData.left;
if (leftData == null)
return;

// dot on top of anchor showing it's connected
Handles.color = new Color(0.3f, 0.4f, 1.0f, 1.0f);
Handles.DrawSolidDisc(from, new Vector3(0.0f, 0.0f, -1.0f), k_EndPointRadius);
if (edgeData.Right == null)
if (edgeData.right == null)
}
}

11
MaterialGraphProject/Assets/NewUI/Editor/Elements/GraphElement.cs


foreach (VisualElement ve in children)
{
GraphElement ce = ve as GraphElement;
if (ce != null)
if (ce != null )
{
var childData = ce.dataProvider as GraphElementData;
if (childData != null)

}
}
// set absolute position from data
position = data.position;
SetPosition(data.position);
}
public virtual bool IsSelectable()

var center = position.center;
var globalCenter = new Vector3(center.x + parent.position.x, center.y + parent.position.y);
return parent.globalTransform.MultiplyPoint3x4(globalCenter);
}
public virtual void SetPosition(Rect newPos)
{
// set absolute position from data
position = newPos;
}
}
}

23
MaterialGraphProject/Assets/NewUI/Editor/Manipulators/Dragger.cs


using UnityEngine;
using UnityEngine.RMGUI;
using UnityEngine.RMGUI.StyleEnums.Values;
using UnityEngine.VR.WSA.WebCam;
namespace RMGUI.GraphView
{

switch (evt.type)
{
case EventType.MouseDown:
if (evt.button == (int) activateButton)
if (evt.button == (int)activateButton)
{
this.TakeCapture();

var t = graphView.contentViewContainer.transform;
graphView.contentViewContainer.transform = t * Matrix4x4.Translate(new Vector3(diff.x, diff.y, 0));
return EventPropagation.Stop;
return EventPropagation.Stop;
if (this.HasCapture() && evt.button == (int) activateButton)
if (this.HasCapture() && evt.button == (int)activateButton)
{
this.ReleaseCapture();
return EventPropagation.Stop;

public Vector2 panSpeed { get; set; }
// hold the data... maybe.
public GraphElementData m_data { get; set; }
// hold the data... maybe.
public GraphElementData m_data { get; set; }
public MouseButton activateButton { get; set; }

switch (evt.type)
{
case EventType.MouseDown:
if (evt.button == (int) activateButton)
if (evt.button == (int)activateButton)
{
this.TakeCapture();

if (m_data != null)
{
m_data.position = CalculatePosition(m_data.position.x + diff.x,
m_data.position.y + diff.y,
m_data.position.width, target.position.height);
m_data.position.y + diff.y,
m_data.position.width, target.position.height);
target.position.y + diff.y,
target.position.width, target.position.height);
target.position.y + diff.y,
target.position.width, target.position.height);
}
return EventPropagation.Stop;

case EventType.MouseUp:
if (this.HasCapture() && evt.button == (int) activateButton)
if (this.HasCapture() && evt.button == (int)activateButton)
{
m_data = null;
this.ReleaseCapture();

12
MaterialGraphProject/Assets/NewUI/Editor/Manipulators/EdgeConnector.cs


m_EdgeDataCandidate = ScriptableObject.CreateInstance<TEdgeData>();
m_EdgeDataCandidate.position = new Rect(0, 0, 1, 1);
m_EdgeDataCandidate.Left = graphElement.dataProvider as IConnectable;
m_EdgeDataCandidate.Right = null;
m_EdgeDataCandidate.left = graphElement.dataProvider as IConnectable;
m_EdgeDataCandidate.right = null;
m_EdgeDataCandidate.candidate = true;
m_EdgeDataCandidate.candidatePosition = target.LocalToGlobal(evt.mousePosition);

{
if (anchorElement.globalBound.Contains(target.LocalToGlobal(evt.mousePosition)))
{
m_EdgeDataCandidate.Right = compatibleAnchor;
m_EdgeDataCandidate.right = compatibleAnchor;
}
}
}

// Not a candidate anymore, let's see if we're actually going to add it to parent
m_EdgeDataCandidate.candidate = false;
if (m_EdgeDataCandidate.Right == null)
if (m_EdgeDataCandidate.right == null)
m_EdgeDataCandidate.Left.connected = true;
m_EdgeDataCandidate.Right.connected = true;
m_EdgeDataCandidate.left.connected = true;
m_EdgeDataCandidate.right.connected = true;
}
}

344
MaterialGraphProject/Assets/NewUI/Editor/Manipulators/Resizer.cs


using System;
using UnityEngine;
using UnityEngine.RMGUI;
using UnityEngine.RMGUI.StyleEnums.Values;
namespace RMGUI.GraphView
{
public class Resizer : Manipulator, IDecorator
{
public MouseButton activateButton { get; set; }
// When applyInvTransform is true, Resizer will apply target's inverse transform before drawing/picking
// (has the effect of being zoom factor independent)
public bool applyInvTransform { get; set; }
private Vector2 m_Start;
private Rect m_StartPos;
private string m_SizeStr;
private Vector2 m_MinimumSize;
// We need to delay style creation because we need to make sure we have a GUISkin loaded.
private GUIStyle m_StyleWidget;
private GUIStyle m_StyleLabel;
private readonly Rect k_WidgetRect = new Rect(0, 0, 10, 6);
private readonly Rect k_WidgetPickRect = new Rect(0, 0, 20, 20);
private readonly Rect k_WidgetTextOffset = new Rect(0, 0, 5, 5);
public Resizer()
{
m_MinimumSize = new Vector2(30.0f, 30.0f);
m_SizeStr = "";
activateButton = MouseButton.LeftMouse;
}
public Resizer(Vector2 minimumSize)
{
m_MinimumSize = minimumSize;
m_SizeStr = "";
}
public override EventPropagation HandleEvent(Event evt, VisualElement finalTarget)
{
GraphElement ce = target as GraphElement;
if (ce==null)
return EventPropagation.Continue;
var data = ce.GetData<GraphElementData>();
if (data==null)
return EventPropagation.Continue;
if ( (data.capabilities & Capabilities.Resizable) != Capabilities.Resizable)
return EventPropagation.Continue;
switch (evt.type)
{
case EventType.MouseDown:
if (evt.button == (int) activateButton)
{
m_Start = evt.mousePosition;
m_StartPos = target.position;
var adjustedWidget = k_WidgetPickRect;
if (applyInvTransform)
{
var inv = target.globalTransform.inverse;
adjustedWidget.width *= inv.m00; // Apply scale
adjustedWidget.height *= inv.m11;
}
var widget = m_StartPos;
widget.x = widget.width - adjustedWidget.width;
widget.y = widget.height - adjustedWidget.height;
widget.width = adjustedWidget.width;
widget.height = adjustedWidget.height;
if (widget.Contains(m_Start))
{
// Warn user if target uses a relative CSS position type
if (target.positionType != PositionType.Absolute)
{
Debug.LogWarning("Attempting to resize an object with a non absolute CSS position type");
}
this.TakeCapture();
return EventPropagation.Stop;
}
}
break;
case EventType.MouseDrag:
if (this.HasCapture() && target.positionType == PositionType.Absolute)
{
var diff = evt.mousePosition - m_Start;
var newSize = new Vector2(m_StartPos.width + diff.x, m_StartPos.height + diff.y);
if (newSize.x < m_MinimumSize.x)
newSize.x = m_MinimumSize.x;
if (newSize.y < m_MinimumSize.y)
newSize.y = m_MinimumSize.y;
data.position = new Rect(data.position.x, data.position.y, newSize.x, newSize.y);
m_SizeStr = String.Format("{0:0}", target.position.width) + "x" + String.Format("{0:0}", target.position.height);
return EventPropagation.Stop;
}
return EventPropagation.Continue;
case EventType.MouseUp:
if (this.HasCapture() && evt.button == (int)activateButton)
{
this.ReleaseCapture();
return EventPropagation.Stop;
}
break;
}
return EventPropagation.Continue;
}
public void PrePaint(VisualElement t, PaintContext pc)
{
}
public void PostPaint(VisualElement t, PaintContext pc)
{
// TODO: I would like to listen for skin change and create GUIStyle then and only then
if (m_StyleWidget == null)
{
m_StyleWidget = new GUIStyle("WindowBottomResize") { fixedHeight = 0 };
}
if (m_StyleLabel == null)
{
m_StyleLabel = new GUIStyle("Label");
}
// Draw resize widget
var widget = k_WidgetRect;
if (applyInvTransform)
{
var inv = pc.worldXForm.inverse;
widget.width *= inv.m00;
widget.height *= inv.m11;
}
widget.position = new Vector2(target.position.max.x - widget.width, target.position.max.y - widget.height);
// todo painter as drawimage
m_StyleWidget.Draw(widget, GUIContent.none, 0);
if (this.HasCapture())
{
// Get adjusted text offset
var adjustedWidget = k_WidgetTextOffset;
if (applyInvTransform)
{
var inv = pc.worldXForm.inverse;
adjustedWidget.width *= inv.m00; // Apply scale
adjustedWidget.height *= inv.m11;
}
// Now define widget to locate label
widget = new Rect(target.position.max.x + adjustedWidget.width,
target.position.max.y + adjustedWidget.height,
200.0f, 20.0f);
m_StyleLabel.Draw(widget, new GUIContent(m_SizeStr), false, false, false, false);
}
}
}
}
using System;
using UnityEngine;
using UnityEngine.RMGUI;
using UnityEngine.RMGUI.StyleEnums.Values;
namespace RMGUI.GraphView
{
public class Resizer : Manipulator, IDecorator
{
public MouseButton activateButton { get; set; }
// When applyInvTransform is true, Resizer will apply target's inverse transform before drawing/picking
// (has the effect of being zoom factor independent)
public bool applyInvTransform { get; set; }
private Vector2 m_Start;
private Rect m_StartPos;
private string m_SizeStr;
private Vector2 m_MinimumSize;
// We need to delay style creation because we need to make sure we have a GUISkin loaded.
private GUIStyle m_StyleWidget;
private GUIStyle m_StyleLabel;
private readonly Rect k_WidgetRect = new Rect(0, 0, 10, 6);
private readonly Rect k_WidgetPickRect = new Rect(0, 0, 20, 20);
private readonly Rect k_WidgetTextOffset = new Rect(0, 0, 5, 5);
public Resizer()
{
m_MinimumSize = new Vector2(30.0f, 30.0f);
m_SizeStr = "";
activateButton = MouseButton.LeftMouse;
}
public Resizer(Vector2 minimumSize)
{
m_MinimumSize = minimumSize;
m_SizeStr = "";
}
public override EventPropagation HandleEvent(Event evt, VisualElement finalTarget)
{
GraphElement ce = target as GraphElement;
if (ce==null)
return EventPropagation.Continue;
var data = ce.GetData<GraphElementData>();
if (data==null)
return EventPropagation.Continue;
if ( (data.capabilities & Capabilities.Resizable) != Capabilities.Resizable)
return EventPropagation.Continue;
switch (evt.type)
{
case EventType.MouseDown:
if (evt.button == (int) activateButton)
{
m_Start = evt.mousePosition;
m_StartPos = target.position;
var adjustedWidget = k_WidgetPickRect;
if (applyInvTransform)
{
var inv = target.globalTransform.inverse;
adjustedWidget.width *= inv.m00; // Apply scale
adjustedWidget.height *= inv.m11;
}
var widget = m_StartPos;
widget.x = widget.width - adjustedWidget.width;
widget.y = widget.height - adjustedWidget.height;
widget.width = adjustedWidget.width;
widget.height = adjustedWidget.height;
if (widget.Contains(m_Start))
{
// Warn user if target uses a relative CSS position type
if (target.positionType != PositionType.Absolute)
{
Debug.LogWarning("Attempting to resize an object with a non absolute CSS position type");
}
this.TakeCapture();
return EventPropagation.Stop;
}
}
break;
case EventType.MouseDrag:
if (this.HasCapture() && target.positionType == PositionType.Absolute)
{
var diff = evt.mousePosition - m_Start;
var newSize = new Vector2(m_StartPos.width + diff.x, m_StartPos.height + diff.y);
if (newSize.x < m_MinimumSize.x)
newSize.x = m_MinimumSize.x;
if (newSize.y < m_MinimumSize.y)
newSize.y = m_MinimumSize.y;
data.position = new Rect(data.position.x, data.position.y, newSize.x, newSize.y);
m_SizeStr = String.Format("{0:0}", target.position.width) + "x" + String.Format("{0:0}", target.position.height);
return EventPropagation.Stop;
}
return EventPropagation.Continue;
case EventType.MouseUp:
if (this.HasCapture() && evt.button == (int)activateButton)
{
this.ReleaseCapture();
return EventPropagation.Stop;
}
break;
}
return EventPropagation.Continue;
}
public void PrePaint(VisualElement t, PaintContext pc)
{
}
public void PostPaint(VisualElement t, PaintContext pc)
{
// TODO: I would like to listen for skin change and create GUIStyle then and only then
if (m_StyleWidget == null)
{
m_StyleWidget = new GUIStyle("WindowBottomResize") { fixedHeight = 0 };
}
if (m_StyleLabel == null)
{
m_StyleLabel = new GUIStyle("Label");
}
// Draw resize widget
var widget = k_WidgetRect;
if (applyInvTransform)
{
var inv = pc.worldXForm.inverse;
widget.width *= inv.m00;
widget.height *= inv.m11;
}
widget.position = new Vector2(target.position.max.x - widget.width, target.position.max.y - widget.height);
// todo painter as drawimage
m_StyleWidget.Draw(widget, GUIContent.none, 0);
if (this.HasCapture())
{
// Get adjusted text offset
var adjustedWidget = k_WidgetTextOffset;
if (applyInvTransform)
{
var inv = pc.worldXForm.inverse;
adjustedWidget.width *= inv.m00; // Apply scale
adjustedWidget.height *= inv.m11;
}
// Now define widget to locate label
widget = new Rect(target.position.max.x + adjustedWidget.width,
target.position.max.y + adjustedWidget.height,
200.0f, 20.0f);
m_StyleLabel.Draw(widget, new GUIContent(m_SizeStr), false, false, false, false);
}
}
}
}

19
MaterialGraphProject/Assets/NewUI/Editor/NodeAdapter.cs


foreach (MethodInfo method in GetExtensionMethods(assembly, typeof(NodeAdapter)))
{
var methodParams = method.GetParameters();
if (methodParams.Count() == 3)
if (methodParams.Length == 3)
{
string pa = methodParams[1].ParameterType + methodParams[2].ParameterType.ToString();
s_NodeAdapterDictionary.Add(pa.GetHashCode(), method);

string s = a.GetType().ToString() + b.GetType();
try
{
return s_NodeAdapterDictionary[s.GetHashCode()];
}
catch (Exception)
{ }
return null;
MethodInfo methodInfo;
return s_NodeAdapterDictionary.TryGetValue(s.GetHashCode(), out methodInfo) ? methodInfo : null;
}
public MethodInfo GetTypeAdapter(Type from, Type to)

foreach (MethodInfo i in methodInfos)
{
object[] allAttrs = i.GetCustomAttributes(typeof(TypeAdapter), false);
if (allAttrs.Count() > 0)
if (allAttrs.Any())
{
s_TypeAdapters.Add(i);
}

}
}
}
foreach (MethodInfo i in s_TypeAdapters)
{

if (allParams.Count() == 1)
if (allParams.Length == 1)
{
if (allParams[0].ParameterType == from)
return i;

return null;
}
};
}
}

64
MaterialGraphProject/Assets/NewUI/Editor/Views/Data/GraphViewDataSource.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace RMGUI.GraphView
{
public interface IDataSource
{
IEnumerable<GraphElementData> elements { get; }
void AddElement(GraphElementData element);
void RemoveElement(GraphElementData element);
}
[Serializable]
public abstract class GraphViewDataSource : ScriptableObject, IDataSource
{
[SerializeField]
private List<GraphElementData> m_Elements = new List<GraphElementData>();
public IEnumerable<GraphElementData> elements
{
get { return m_Elements.OfType<GraphElementData>(); }
}
public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
namespace RMGUI.GraphView
{
[Serializable]
public abstract class GraphViewDataSource : ScriptableObject, IDataSource
{
[SerializeField]
private List<GraphElementData> m_Elements = new List<GraphElementData>();
public IEnumerable<GraphElementData> elements
{
get { return m_Elements; }
}
public void AddElement(GraphElementData element)
{
m_Elements.Add(element);
}
public void RemoveElement(GraphElementData element)
{
m_Elements.RemoveAll(x => x == element);
}
}
}

12
MaterialGraphProject/Assets/NewUI/Editor/Views/GraphView.cs


contentViewContainer = new ContentiewContainer
{
name = "contentViewContainer",
clipChildren = false
clipChildren = false,
position = new Rect(0, 0, 0, 0)
contentViewContainer.position = new Rect(0,0,0,0);
AddChild(contentViewContainer);
}

// functions to ISelection extensions
public void AddToSelection(ISelectable e)
{
if (e is GraphView)
return;
GraphElement ce = e as GraphElement;
if (ce != null && ce.GetData<GraphElementData>() != null)
ce.GetData<GraphElementData>().selected = true;

public void RemoveFromSelection(ISelectable e)
{
if (e is GraphView)
return;
GraphElement ce = e as GraphElement;
if (ce != null && ce.GetData<GraphElementData>() != null)
ce.GetData<GraphElementData>().selected = false;

return;
}
newElem.position = elementData.position;
newElem.SetPosition(elementData.position);
newElem.classList = elementsClassList;
newElem.dataProvider = elementData;

25
MaterialGraphProject/Assets/NewUI/Editor/Views/GraphView.uss


border-right:2;
border-bottom:2;
}
WWWImageBox {
/* TODO refactor with two containers.
Here reseting the padding-top will offset the text content as well*/
/*padding-top: 0;*/
padding-left: 0;
padding-right: 0;
padding-bottom: 0;
}
WWWImageBox > Image {
flex:1;
}
MiniMapBox Label {
position-type:absolute;
position-top:0;
position-left:0;
position-right:0;
height: 16;
}
MiniMapBox {
padding-top:20;
}

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


using System;
using System.Reflection;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(AbstractMaterialNode))]
public class AbstractMaterialNodeUI : ICustomNodeUi
{
private MaterialGraphPreviewGenerator m_PreviewGenerator;
[NonSerialized]
private int m_LastShaderVersion = -1;
[NonSerialized]
private Material m_PreviewMaterial;
[NonSerialized]
private Shader m_PreviewShader;
private AbstractMaterialNode m_Node;
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
public Material previewMaterial
{
get
{
if (m_PreviewMaterial == null)
{
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
}
return m_PreviewMaterial;
}
}
private MaterialGraphPreviewGenerator previewGenerator
{
get
{
if (m_PreviewGenerator == null)
{
m_PreviewGenerator = new MaterialGraphPreviewGenerator();
}
return m_PreviewGenerator;
}
}
private float m_PreviewWidth;
public virtual float GetNodeUiHeight(float width)
{
if (!m_Node.drawState.expanded)
return 0;
if (m_Node.hasPreview == false)
return 0;
m_PreviewWidth = width - 20;
return m_PreviewWidth;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as AbstractMaterialNode;
if (materialNode != null)
m_Node = materialNode;
}
}
public PreviewMode generatedShaderMode
{
get { return m_GeneratedShaderMode; }
set { m_GeneratedShaderMode = value; }
}
public virtual float GetNodeWidth()
{
return 200;
}
public virtual GUIModificationType Render(Rect area)
{
if (m_Node == null || !m_Node.drawState.expanded)
return GUIModificationType.None;
if (m_Node.hasPreview == false)
return GUIModificationType.None;
if (m_LastShaderVersion != m_Node.version)
{
if (UpdatePreviewShader())
m_LastShaderVersion = m_Node.version;
}
var preview = RenderPreview(area);
GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear;
GUI.DrawTexture(area, preview, ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
return GUIModificationType.None;
}
protected virtual string GetPreviewShaderString()
{
return ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode);
}
private bool UpdatePreviewShader()
{
if (m_Node == null || m_Node.hasError)
return false;
var resultShader = GetPreviewShaderString();
Debug.Log("RecreateShaderAndMaterial : " + m_Node.GetVariableNameForNode() + Environment.NewLine + resultShader);
if (string.IsNullOrEmpty(resultShader))
return false;
// workaround for some internal shader compiler weirdness
// if we are in error we sometimes to not properly clean
// out the error flags and will stay in error, even
// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
Object.DestroyImmediate(m_PreviewShader, true);
m_PreviewShader = null;
}
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideAndDontSave;
}
else
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
}
return !ShaderHasError(m_PreviewShader);
}
public static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] {shader});
return (int)result != 0;
}
/// <summary>
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
/// RenderPreview and do their own rendering to the render texture
/// </summary>
public Texture RenderPreview(Rect targetSize)
{
previewMaterial.shader = m_PreviewShader;
UpdateMaterialProperties(m_Node, previewMaterial);
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, targetSize);
}
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
{
switch (previewProperty.m_PropType)
{
case PropertyType.Texture2D:
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
break;
case PropertyType.Color:
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
break;
case PropertyType.Vector2:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector3:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector4:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Float:
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
break;
}
}
public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
{
var childNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
var pList = ListPool<PreviewProperty>.Get();
for (var index = 0; index < childNodes.Count; index++)
{
var node = childNodes[index] as AbstractMaterialNode;
if (node == null)
continue;
node.CollectPreviewMaterialProperties(pList);
}
foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<INode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}
}
}
using System;
using System.Reflection;
using RMGUI.GraphView;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph
{
/* [CustomDataView(typeof(NodePreviewData))]
public class NodePreview : GraphElement
{
public NodePreview(NodePreviewData preview)
{
dataProvider = preview;
}
public override void DoRepaint(PaintContext args)
{
base.DoRepaint(args);
m_WwwTexture = new Texture2D(4, 4, TextureFormat.DXT1, false);
AddChild(new Image { image = m_WwwTexture });
Handles.DrawSolidRectangleWithOutline(parent.position, Color.red, Color.blue);
}
}*/
[Serializable]
public class NodePreviewData : GraphElementData
{
protected NodePreviewData()
{ }
private MaterialGraphPreviewGenerator m_PreviewGenerator;
[NonSerialized]
private int m_LastShaderVersion = -1;
[NonSerialized]
private Material m_PreviewMaterial;
[NonSerialized]
private Shader m_PreviewShader;
private AbstractMaterialNode m_Node;
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
public Material previewMaterial
{
get
{
if (m_PreviewMaterial == null)
{
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
}
return m_PreviewMaterial;
}
}
private MaterialGraphPreviewGenerator previewGenerator
{
get
{
if (m_PreviewGenerator == null)
{
m_PreviewGenerator = new MaterialGraphPreviewGenerator();
}
return m_PreviewGenerator;
}
}
public void Initialize(AbstractMaterialNode node)
{
m_Node = node;
}
public Texture Render(Vector2 dimension)
{
if (m_Node == null)
return null;
if (m_Node.hasPreview == false)
return null;
if (m_LastShaderVersion != m_Node.version)
{
if (UpdatePreviewShader())
m_LastShaderVersion = m_Node.version;
}
return RenderPreview(dimension);
}
protected virtual string GetPreviewShaderString()
{
return ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode);
}
private bool UpdatePreviewShader()
{
if (m_Node == null || m_Node.hasError)
return false;
var resultShader = GetPreviewShaderString();
Debug.Log("RecreateShaderAndMaterial : " + m_Node.GetVariableNameForNode() + Environment.NewLine + resultShader);
if (string.IsNullOrEmpty(resultShader))
return false;
// workaround for some internal shader compiler weirdness
// if we are in error we sometimes to not properly clean
// out the error flags and will stay in error, even
// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
Object.DestroyImmediate(m_PreviewShader, true);
m_PreviewShader = null;
}
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideAndDontSave;
}
else
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
}
return !ShaderHasError(m_PreviewShader);
}
public static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] {shader});
return (int)result != 0;
}
/// <summary>
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
/// RenderPreview and do their own rendering to the render texture
/// </summary>
private Texture RenderPreview(Vector2 targetSize)
{
previewMaterial.shader = m_PreviewShader;
UpdateMaterialProperties(m_Node, previewMaterial);
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, new Rect(0, 0, targetSize.x, targetSize.y));
}
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
{
switch (previewProperty.m_PropType)
{
case PropertyType.Texture2D:
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
break;
case PropertyType.Color:
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
break;
case PropertyType.Vector2:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector3:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector4:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Float:
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
break;
}
}
public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
{
var childNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
var pList = ListPool<PreviewProperty>.Get();
for (var index = 0; index < childNodes.Count; index++)
{
var node = childNodes[index] as AbstractMaterialNode;
if (node == null)
continue;
node.CollectPreviewMaterialProperties(pList);
}
foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<INode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Editors/MaterialGraphEditor.cs


if (m_PreviewUtility == null)
{
m_PreviewUtility = new PreviewRenderUtility();
//EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
}
if (s_Meshes[0] == null)

{
m_PreviewUtility.m_Camera.transform.position = -Vector3.forward * 5;
m_PreviewUtility.m_Camera.transform.rotation = Quaternion.identity;
//EditorUtility.SetCameraAnimateMaterialsTime(m_PreviewUtility.m_Camera, time);
EditorUtility.SetCameraAnimateMaterialsTime(m_PreviewUtility.m_Camera, time);
var amb = new Color(.2f, .2f, .2f, 0);
m_PreviewUtility.m_Light[0].intensity = 1.0f;
m_PreviewUtility.m_Light[0].transform.rotation = Quaternion.Euler(50f, 50f, 0);

}
else
{
//EditorUtility.UpdateGlobalShaderProperties(Time.realtimeSinceStartup);
EditorUtility.UpdateGlobalShaderProperties(Time.realtimeSinceStartup);
Graphics.Blit(null, mat);
}
return m_PreviewUtility.EndPreview();

22
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Styles/NodalView.uss


MaterialGraphNode {
flex-direction: column;
}
MaterialGraphNode #slots {
MaterialGraphNode #input {
MaterialGraphNode #slots #input {
flex-direction: column;
MaterialGraphNode #output {
MaterialGraphNode #slots #output {
justify-content: flex-end;
flex-direction: column;
}
MaterialGraphNode #controls {
flex-direction: column;
}
MaterialGraphNode #preview {
flex-direction: column;
height: 200;
width: 200;
width: 100;
}
/* Example of dynamic properties

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/MaterialGraphProject.sln.DotSettings.user


<s:String x:Key="/Default/Environment/ContinuousTesting/PersistentDataLocation/@EntryValue">C:\Users\Tim\AppData\Local\Temp\JetBrains\ContinuousTesting\7e95cb10-f230-442a-ba1f-a26bdb4193cb</s:String>
<s:String x:Key="/Default/Environment/ContinuousTesting/ScopeCriterion/@EntryValue">9b0nIQIAAACJbLoh9b0nIQIAAADP4jFoJAAAADwATQBhAHQAZQByAGkAYQBsAEcAcgBhAHAAaABQAHIAbwBqAGUAYwB0AC4AQwBTAGgAYQByAHAALgBFAGQAaQB0AG8AcgA+AC0AAABDADoAXABjAG8AZABlAFwATQBhAHQAZQByAGkAYQBsAEcAcgBhAHAAaABHAGkAdABcAE0AYQB0AGUAcgBpAGEAbABHAHIAYQBwAGgAUAByAG8AagBlAGMAdAA4rDtD+4tkDSUAAABVAG4AaQB0AHkARQBkAGkAdABvAHIALgBHAHIAYQBwAGgAaQBuAGcALgBJAG4AdABlAGcAcgBhAHQAaQBvAG4AVABlAHMAdABzAA==</s:String>
<s:String x:Key="/Default/Environment/ContinuousTesting/SnapshotLocation/@EntryValue">C:\Users\Tim\AppData\Local\Temp\ssm.Hirafoj.tmp</s:String>
<s:String x:Key="/Default/Environment/ContinuousTesting/SnapshotLocation/@EntryValue">C:\Users\Tim\AppData\Local\Temp\ssm.Gazizer.tmp</s:String>
<s:String x:Key="/Default/Environment/ContinuousTesting/Strategy/@EntryValue">RunTests</s:String>
<s:String x:Key="/Default/Environment/ContinuousTesting/TriggerMode/@EntryValue">OnBuild</s:String></wpf:ResourceDictionary>

2
MaterialGraphProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 5.5.0a4
m_EditorVersion: 5.5.0b1

25
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;
}
}
}

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/MaterialNodeAnchorData.cs.meta


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

43
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.uss


VerticalNode #top {
flex: 1;
align-items: flex-start;
flex-direction: row;
}
VerticalNode #bottom {
flex: 1;
align-items: flex-start;
flex-direction: row;
}
VerticalNode NodeAnchor {
height: 50;
flex:1;
}
Node {
flex-direction: row;
}
Node #input {
flex:1;
}
Node #output {
flex:1;
justify-content: flex-end;
}
NodeAnchor {
height: 26;
}
/* Example of dynamic properties
Read from the GridBackground decorator */
#contentViewContainer {
background-color:#404749;
line-color:#20293F;
thick-line-color:#030C22;
spacing:50.0;
thick-lines:10;
}

8
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/NodalView.uss.meta


fileFormatVersion: 2
guid: b3dd47151f230aa41a6182074b34fc0a
timeCreated: 1475841339
licenseType: Pro
StyleSheetImporter:
userData:
assetBundleName:
assetBundleVariant:

34
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.uss


WWWImage {
/* TODO refactor with two containers.
Here reseting the padding-top will offset the text content as well*/
/*padding-top: 0;*/
padding-left: 0;
padding-right: 0;
padding-bottom: 0;
}
WWWImage > Image {
flex:1;
}
MiniMap Label {
position-type:absolute;
position-top:0;
position-left:0;
position-right:0;
height: 16;
}
MiniMap {
position-type:absolute;
padding-top:20;
}
MiniMap.anchored {
position-left:20;
position-bottom:20;
}
MiniMap.anchored Label{
color:#aaaa00
}

8
MaterialGraphProject/Assets/NewUI/Editor/Demo/Views/SimpleContentView.uss.meta


fileFormatVersion: 2
guid: 19a7fac700a3cd14789ff6cd06ff8e74
timeCreated: 1475841339
licenseType: Pro
StyleSheetImporter:
userData:
assetBundleName:
assetBundleVariant:

11
MaterialGraphProject/Assets/NewUI/Editor/Views/Data/IDataSource.cs


using System.Collections.Generic;
namespace RMGUI.GraphView
{
public interface IDataSource
{
IEnumerable<GraphElementData> elements { get; }
void AddElement(GraphElementData element);
void RemoveElement(GraphElementData element);
}
}

12
MaterialGraphProject/Assets/NewUI/Editor/Views/Data/IDataSource.cs.meta


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

51
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(Vector4Node))]
public class Vector4NodeUI : ICustomNodeUi
{
private Vector4Node m_Node;
public float GetNodeUiHeight(float width)
{
return 2 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
EditorGUI.BeginChangeCheck();
m_Node.value = EditorGUI.Vector4Field(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Value", m_Node.value);
if (EditorGUI.EndChangeCheck())
{
//TODO:tidy this shit.
//EditorUtility.SetDirty(materialGraphOwner.owner);
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as Vector4Node;
if (materialNode != null)
m_Node = materialNode;
}
}
public float GetNodeWidth()
{
return 200;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs.meta


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

65
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(PixelShaderNode))]
public class PixelShaderNodeUI : AbstractMaterialNodeUI
{
public override float GetNodeWidth()
{
return 300;
}
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as PixelShaderNode;
if (localNode == null)
return base.Render(area);
var lightFunctions = PixelShaderNode.GetLightFunctions();
var lightFunction = localNode.lightFunction.GetType();
int lightFuncIndex = 0;
if (lightFunction != null)
lightFuncIndex = lightFunctions.Select(x => x.GetType()).ToList().IndexOf(lightFunction);
EditorGUI.BeginChangeCheck();
lightFuncIndex = EditorGUI.Popup(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), lightFuncIndex, lightFunctions.Select(x => x.lightFunctionName).ToArray(), EditorStyles.popup);
localNode.lightFunction = lightFunctions[lightFuncIndex];
var toReturn = GUIModificationType.None;
if (EditorGUI.EndChangeCheck())
{
localNode.UpdateNodeAfterDeserialization();
toReturn = GUIModificationType.ModelChanged;
}
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
protected override string GetPreviewShaderString()
{
var localNode = node as PixelShaderNode;
if (localNode == null)
return string.Empty;
var shaderName = "Hidden/PreviewShader/" + localNode.GetVariableNameForNode();
List<PropertyGenerator.TextureInfo> defaultTextures;
//TODO: Need to get the real options somehow
var resultShader = ShaderGenerator.GenerateSurfaceShader(localNode, new MaterialOptions(), shaderName, true, out defaultTextures);
generatedShaderMode = PreviewMode.Preview3D;
return resultShader;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs.meta


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

49
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/ColorNodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(ColorNode))]
public class ColorNodeUI : ICustomNodeUi
{
private ColorNode m_Node;
public float GetNodeUiHeight(float width)
{
return 2 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
EditorGUI.BeginChangeCheck();
m_Node.color = EditorGUI.ColorField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Value", m_Node.color);
if (EditorGUI.EndChangeCheck())
{
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as ColorNode;
if (materialNode != null)
m_Node = materialNode;
}
}
public float GetNodeWidth()
{
return 200;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/ColorNodeUI.cs.meta


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

37
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/CombineNodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(CombineNode))]
public class CombineNodeUI : AbstractMaterialNodeUI
{
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as CombineNode;
if (localNode == null)
return base.Render(area);
EditorGUI.BeginChangeCheck();
localNode.operation = (CombineNode.Operation)EditorGUI.EnumPopup(area, localNode.operation);
var toReturn = GUIModificationType.None;
if (EditorGUI.EndChangeCheck())
{
toReturn = GUIModificationType.DataChanged;
}
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/CombineNodeUI.cs.meta


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

41
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector1NodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(Vector1Node))]
public class Vector1NodeUI : PropertyNodeUI
{
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as Vector1Node;
if (localNode == null)
return base.Render(area);
EditorGUI.BeginChangeCheck();
localNode.value = EditorGUI.FloatField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Value", localNode.value);
var toReturn = GUIModificationType.None;
if (EditorGUI.EndChangeCheck())
{
//TODO:tidy this shit.
//EditorUtility.SetDirty(materialGraphOwner.owner);
toReturn |= GUIModificationType.Repaint;
}
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector1NodeUI.cs.meta


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

51
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector2NodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(Vector2Node))]
public class Vector2NodeUI : ICustomNodeUi
{
private Vector2Node m_Node;
public float GetNodeUiHeight(float width)
{
return 2 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
EditorGUI.BeginChangeCheck();
m_Node.value = EditorGUI.Vector2Field(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Value", m_Node.value);
if (EditorGUI.EndChangeCheck())
{
//TODO:tidy this shit.
//EditorUtility.SetDirty(materialGraphOwner.owner);
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as Vector2Node;
if (materialNode != null)
m_Node = materialNode;
}
}
public float GetNodeWidth()
{
return 200;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector2NodeUI.cs.meta


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

51
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector3NodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(Vector3Node))]
public class Vector3NodeUI : ICustomNodeUi
{
private Vector3Node m_Node;
public float GetNodeUiHeight(float width)
{
return 2 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
EditorGUI.BeginChangeCheck();
m_Node.value = EditorGUI.Vector3Field(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Value", m_Node.value);
if (EditorGUI.EndChangeCheck())
{
//TODO:tidy this shit.
//EditorUtility.SetDirty(materialGraphOwner.owner);
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as Vector3Node;
if (materialNode != null)
m_Node = materialNode;
}
}
public float GetNodeWidth()
{
return 200;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector3NodeUI.cs.meta


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

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs.meta


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

55
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(AbstractSubGraphIONode))]
public class SubGraphIONodeUI : ICustomNodeUi
{
private AbstractSubGraphIONode m_Node;
public float GetNodeUiHeight(float width)
{
return 2 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
var modification = GUIModificationType.None;
if (GUI.Button(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Add Slot"))
{
m_Node.AddSlot();
modification |= GUIModificationType.ModelChanged;
}
if (GUI.Button(new Rect(area.x, area.y + EditorGUIUtility.singleLineHeight, area.width, EditorGUIUtility.singleLineHeight), "Remove Slot"))
{
m_Node.RemoveSlot();
modification |= GUIModificationType.ModelChanged;
}
return modification;
}
public INode node
{
get { return m_Node; }
set
{
var materialNode = value as AbstractSubGraphIONode;
if (materialNode != null)
m_Node = materialNode;
}
}
public float GetNodeWidth()
{
return 100;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs.meta


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

39
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(SubGraphNode))]
public class SubgraphNodeUI : AbstractMaterialNodeUI
{
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as SubGraphNode;
if (localNode == null)
return base.Render(area);
EditorGUI.BeginChangeCheck();
localNode.subGraphAsset = (MaterialSubGraphAsset)EditorGUI.ObjectField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight),
new GUIContent("SubGraph"),
localNode.subGraphAsset,
typeof(MaterialSubGraphAsset), false);
var toReturn = GUIModificationType.None;
if (EditorGUI.EndChangeCheck())
toReturn |= GUIModificationType.ModelChanged;
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs.meta


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

87
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(PropertyNode))]
public class PropertyNodeUI : AbstractMaterialNodeUI
{
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight * 1;
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as PropertyNode;
if (localNode == null)
return base.Render(area);
var toReturn = GUIModificationType.None;
EditorGUI.BeginChangeCheck();
localNode.exposedState = (PropertyNode.ExposedState)EditorGUI.EnumPopup(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), new GUIContent("Exposed"), localNode.exposedState);
if (EditorGUI.EndChangeCheck())
toReturn |= GUIModificationType.DataChanged;
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
[CustomNodeUI(typeof(TextureNode))]
public class TextureNodeUI : PropertyNodeUI
{
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight * 2;
}
private string[] m_TextureTypeNames;
private string[] textureTypeNames
{
get
{
if (m_TextureTypeNames == null)
m_TextureTypeNames = Enum.GetNames(typeof(TextureType));
return m_TextureTypeNames;
}
}
public override GUIModificationType Render(Rect area)
{
var localNode = node as TextureNode;
if (localNode == null)
return base.Render(area);
EditorGUI.BeginChangeCheck();
//localNode.defaultTexture = EditorGUI.MiniThumbnailObjectField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), new GUIContent("Texture"), localNode.defaultTexture, typeof(Texture2D), null) as Texture2D;
var texureChanged = EditorGUI.EndChangeCheck();
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
EditorGUI.BeginChangeCheck();
localNode.textureType = (TextureType)EditorGUI.Popup(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), (int)localNode.textureType, textureTypeNames, EditorStyles.popup);
var typeChanged = EditorGUI.EndChangeCheck();
var toReturn = GUIModificationType.None;
if (typeChanged)
{
toReturn |= GUIModificationType.DataChanged;
}
if (texureChanged)
toReturn |= GUIModificationType.Repaint;
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
}
正在加载...
取消
保存