浏览代码

Move slot compatibility check code into MaterialSlot

Validate commands directly in window class, rather than through MaterialGraphPresenter
Move a few things from MaterialGraphPresenter to GraphEditorView
Create manipulator for node creation (NodeCreator), rather than manually doing it in MaterialGraph
Move things from MaterialGraph constructor into GraphEditorView
Completely remove GridBackground, as we were not using it
Remove Clicker manipulator, as it was not used
/main
Peter Bay Bastian 7 年前
当前提交
9dbfb5c3
共有 10 个文件被更改,包括 118 次插入227 次删除
  1. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  2. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  3. 60
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
  4. 19
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  5. 98
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs
  6. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
  7. 73
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs
  8. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs.meta
  9. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Clicker.cs.meta
  10. 47
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Clicker.cs

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs


return false;
}
public bool IsCompatibleWith(MaterialSlot otherSlot)
{
return otherSlot != null
&& otherSlot.owner != owner
&& otherSlot.isInputSlot != isInputSlot
&& (isInputSlot
? otherSlot.IsCompatibleWithInputSlotType(concreteValueType)
: IsCompatibleWithInputSlotType(otherSlot.concreteValueType));
}
public virtual string GetDefaultValue(GenerationMode generationMode)
{
var matOwner = owner as AbstractMaterialNode;

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


var presenter = graphEditorView.graphPresenter;
var e = Event.current;
var graphViewHasSelection = graphEditorView.graphView.selection.Any();
e.commandName == "Copy" && presenter.canCopy
|| e.commandName == "Paste" && presenter.canPaste
|| e.commandName == "Duplicate" && presenter.canDuplicate
|| e.commandName == "Cut" && presenter.canCut
|| (e.commandName == "Delete" || e.commandName == "SoftDelete") && presenter.canDelete))
e.commandName == "Copy" && graphViewHasSelection
|| e.commandName == "Paste" && CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer) != null
|| e.commandName == "Duplicate" && graphViewHasSelection
|| e.commandName == "Cut" && graphViewHasSelection
|| (e.commandName == "Delete" || e.commandName == "SoftDelete") && graphViewHasSelection))
{
e.Use();
}

60
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs


public void Initialize(GraphView graphView, IGraph graph, PreviewSystem previewSystem)
{
m_GraphView = graphView;
m_PreviewSystem = previewSystem;
this.graph = graph;

void EdgeRemoved(EdgeRemovedGraphChange change)
{
var edgeView = m_GraphView.graphElements.ToList().OfType<Edge>().FirstOrDefault(p => p.userData is IEdge && (IEdge)p.userData == change.edge);
var edgeView = m_GraphView.graphElements.ToList().OfType<Edge>().FirstOrDefault(p => p.userData is IEdge && Equals((IEdge)p.userData, change.edge));
if (edgeView != null)
{
edgeView.output.Disconnect(edgeView);

}
public void AddNode(INode node)
{
graph.owner.RegisterCompleteObjectUndo("Add " + node.name);
graph.AddNode(node);
}
public void RemoveElements(IEnumerable<MaterialNodeView> nodes, IEnumerable<Edge> edges)
{
graph.RemoveElements(nodes.Select(x => x.node as INode), edges.Select(x => x.userData as IEdge));

public void Connect(NodeAnchor left, NodeAnchor right)
{
if (left != null && right != null)
{
graph.owner.RegisterCompleteObjectUndo("Connect Edge");
var leftSlot = left.userData as ISlot;
var rightSlot = right.userData as ISlot;
if (leftSlot == null || rightSlot == null)
return;
graph.Connect(leftSlot.slotReference, rightSlot.slotReference);
}
}
static CopyPasteGraph CreateCopyPasteGraph(IEnumerable<GraphElement> selection)
static CopyPasteGraph CreateCopyPasteGraph(IEnumerable<ISelectable> selection)
{
var graph = new CopyPasteGraph();
foreach (var element in selection)

m_AddToSelection = false;
}
public bool canCopy
{
get { return m_GraphView != null && m_GraphView.selection.OfType<GraphElement>().Any(e => e.selected); }
}
var graph = CreateCopyPasteGraph(m_GraphView.selection.OfType<GraphElement>());
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graph, true);
}
public bool canCut
{
get { return canCopy; }
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(CreateCopyPasteGraph(m_GraphView.selection), true);
}
public void Cut()

m_GraphView.selection.OfType<Edge>());
}
public bool canPaste
{
get { return CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer) != null; }
}
var pastedGraph = CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer);
InsertCopyPasteGraph(pastedGraph);
}
public bool canDuplicate
{
get { return canCopy; }
InsertCopyPasteGraph(CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer));
var deserializedGraph = CopyPasteGraph.FromJson(JsonUtility.ToJson(CreateCopyPasteGraph(m_GraphView.selection.OfType<GraphElement>()), true));
InsertCopyPasteGraph(deserializedGraph);
}
public bool canDelete
{
get { return canCopy; }
InsertCopyPasteGraph(CopyPasteGraph.FromJson(JsonUtility.ToJson(CreateCopyPasteGraph(m_GraphView.selection), false)));
}
public void Delete()

19
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


{
public class GraphEditorView : VisualElement, IDisposable
{
AbstractMaterialGraph m_Graph;
MaterialGraphView m_GraphView;
GraphInspectorView m_GraphInspectorView;
ToolbarView m_ToolbarView;

public GraphEditorView(AbstractMaterialGraph graph, string assetName)
{
m_Graph = graph;
AddStyleSheetPath("Styles/MaterialGraph");
previewSystem = new PreviewSystem(graph);

var content = new VisualElement { name = "content" };
{
m_GraphView = new MaterialGraphView(m_GraphPresenter) { name = "GraphView" };
m_GraphView = new MaterialGraphView() { name = "GraphView" };
m_GraphView.SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
m_GraphView.AddManipulator(new ContentDragger());
m_GraphView.AddManipulator(new RectangleSelector());
m_GraphView.AddManipulator(new SelectionDragger());
m_GraphView.AddManipulator(new ClickSelector());
m_GraphView.AddManipulator(new NodeCreator(graph));
content.Add(m_GraphView);
content.Add(m_GraphView);
content.Add(m_GraphInspectorView);
m_GraphView.graphViewChanged = GraphViewChanged;

{
foreach (var edge in graphViewChange.edgesToCreate)
{
m_GraphPresenter.Connect(edge.output, edge.input);
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");
var leftSlot = edge.output.userData as ISlot;
var rightSlot = edge.input.userData as ISlot;
if (leftSlot != null && rightSlot != null)
m_Graph.Connect(leftSlot.slotReference, rightSlot.slotReference);
}
graphViewChange.edgesToCreate.Clear();
}

98
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs


{
public sealed class MaterialGraphView : GraphView
{
MaterialGraphPresenter m_Presenter;
public MaterialGraphView(MaterialGraphPresenter presenter)
{
m_Presenter = presenter;
RegisterCallback<MouseUpEvent>(DoContextMenu, Capture.Capture);
SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
this.AddManipulator(new ContentDragger());
this.AddManipulator(new RectangleSelector());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new ClickSelector());
Insert(0, new GridBackground());
AddStyleSheetPath("Styles/MaterialGraph");
}
public bool CanAddToNodeMenu(Type type)
{
return true;
}
public override List<NodeAnchor> GetCompatibleAnchors(NodeAnchor startAnchor, NodeAdapter nodeAdapter)
{
var compatibleAnchors = new List<NodeAnchor>();

foreach (var candidateAnchor in anchors.ToList())
{
if (!candidateAnchor.IsConnectable())
continue;
if (candidateAnchor.orientation != startAnchor.orientation)
continue;
if (candidateAnchor.direction == startAnchor.direction)
continue;
if (nodeAdapter.GetAdapter(candidateAnchor.source, startAnchor.source) == null)
continue;
if (candidateSlot == null)
continue;
if (candidateSlot.owner == startSlot.owner)
continue;
if (!startSlot.IsCompatibleWithInputSlotType(candidateSlot.concreteValueType))
if (!startSlot.IsCompatibleWith(candidateSlot))
continue;
if (startStage != ShaderStage.Dynamic)

compatibleAnchors.Add(candidateAnchor);
}
return compatibleAnchors;
}
void DoContextMenu(MouseUpEvent evt)
{
if (evt.button == (int)MouseButton.RightMouse)
{
var gm = new GenericMenu();
foreach (Type type in Assembly.GetAssembly(typeof(AbstractMaterialNode)).GetTypes())
{
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))))
{
var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[];
if (attrs != null && attrs.Length > 0 && CanAddToNodeMenu(type))
{
gm.AddItem(new GUIContent(attrs[0].m_Title), false, AddNode, new AddNodeCreationObject(type, evt.mousePosition));
}
}
}
gm.ShowAsContext();
}
evt.StopPropagation();
}
class AddNodeCreationObject
{
public Vector2 m_Pos;
public readonly Type m_Type;
public AddNodeCreationObject(Type t, Vector2 p)
{
m_Type = t;
m_Pos = p;
}
};
void AddNode(object obj)
{
var posObj = obj as AddNodeCreationObject;
if (posObj == null)
return;
INode node;
try
{
node = Activator.CreateInstance(posObj.m_Type) as INode;
}
catch (Exception e)
{
Debug.LogErrorFormat("Could not construct instance of: {0} - {1}", posObj.m_Type, e);
return;
}
if (node == null)
return;
var drawstate = node.drawState;
Vector3 localPos = contentViewContainer.transform.matrix.inverse.MultiplyPoint3x4(posObj.m_Pos);
drawstate.position = new Rect(localPos.x, localPos.y, 0, 0);
node.drawState = drawstate;
m_Presenter.AddNode(node);
}
public delegate void OnSelectionChanged(IEnumerable<INode> nodes);

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss


width: 400;
}
MaterialGraphView {
background-color: rgb(20, 21, 21);
}
MaterialNodeView > .mainContainer > #left > #preview.active {
width: 200;
}

MaterialNodeView > #resize:active {
background-color: rgb(0, 225, 25);
}
GridBackground {
grid-background-color: rgb(20, 21, 21);
line-color: rgb(20, 21, 21);
thick-line-color: rgb(20, 21, 21);
spacing: 75.0;
thick-lines: 10;
}
GraphInspectorView {

73
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs


using System;
using System.Reflection;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph.Drawing
{
public class NodeCreator : MouseManipulator
{
VisualElement m_ContentViewContainer;
IGraph m_Graph;
Vector2 m_MouseUpPosition;
GenericMenu m_Menu;
public NodeCreator(IGraph graph)
{
m_Graph = graph;
activators.Add(new ManipulatorActivationFilter { button = MouseButton.RightMouse });
m_Menu = new GenericMenu();
foreach (var type in Assembly.GetAssembly(typeof(AbstractMaterialNode)).GetTypes())
{
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))))
{
var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[];
if (attrs != null && attrs.Length > 0)
m_Menu.AddItem(new GUIContent(attrs[0].m_Title), false, OnAddNode, type);
}
}
}
void OnAddNode(object userData)
{
var type = userData as Type;
var node = Activator.CreateInstance(type) as INode;
if (node == null)
return;
var drawState = node.drawState;
drawState.position = new Rect(m_MouseUpPosition.x, m_MouseUpPosition.y, 0, 0);
node.drawState = drawState;
m_Graph.owner.RegisterCompleteObjectUndo("Add " + node.name);
m_Graph.AddNode(node);
}
protected override void RegisterCallbacksOnTarget()
{
var graphView = target as GraphView;
if (graphView == null)
return;
m_ContentViewContainer = graphView.contentViewContainer;
target.RegisterCallback<MouseUpEvent>(OnMouseUp);
}
void OnMouseUp(MouseUpEvent evt)
{
if (CanStartManipulation(evt))
{
m_MouseUpPosition = m_ContentViewContainer.transform.matrix.inverse.MultiplyPoint3x4(evt.localMousePosition);
m_Menu.ShowAsContext();
evt.StopPropagation();
}
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback<MouseUpEvent>(OnMouseUp);
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs.meta


fileFormatVersion: 2
guid: 48d2349cc7ed41d9bf77231b69efbc05
timeCreated: 1508752297

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Clicker.cs.meta


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

47
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Clicker.cs


using UnityEngine.Experimental.UIElements;
using MouseManipulator = UnityEngine.Experimental.UIElements.MouseManipulator;
using ManipulatorActivationFilter = UnityEngine.Experimental.UIElements.ManipulatorActivationFilter;
using MouseButton = UnityEngine.Experimental.UIElements.MouseButton;
namespace UnityEditor.MaterialGraph.Drawing
{
public enum ClickerState
{
Inactive,
Active
}
// TODO JOCE: This is to mimic the behavior of a button. Remove and replace with actual button in TitleBar.
public class Clicker : MouseManipulator
{
public delegate void StateChangeCallback(ClickerState newState);
public delegate void ClickCallback();
public StateChangeCallback onStateChange { get; set; }
public ClickCallback onClick { get; set; }
VisualElement initialTarget;
ClickerState state;
public Clicker()
{
activators.Add(new ManipulatorActivationFilter {button = MouseButton.LeftMouse});
}
protected override void RegisterCallbacksOnTarget()
{
target.RegisterCallback<MouseUpEvent>(OnMouseUp, Capture.Capture);
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback<MouseUpEvent>(OnMouseUp, Capture.Capture);
}
void OnMouseUp(MouseUpEvent evt)
{
onClick();
}
}
}
正在加载...
取消
保存