浏览代码
Unify {Abstract,Serializable,Material}GraphEditWindow, {Abstract,Serializable,Material}GraphPresenter and {Serializable,Material}GraphView
/main
Unify {Abstract,Serializable,Material}GraphEditWindow, {Abstract,Serializable,Material}GraphPresenter and {Serializable,Material}GraphView
/main
Peter Bay Bastian
7 年前
当前提交
d470f1f1
共有 17 个文件被更改,包括 604 次插入 和 974 次删除
-
5MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Drawer/GraphEditorDrawer.cs
-
3MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Manipulators/ClickGlobalSelector.cs
-
15MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/Presenters/TitleBarPresenter.cs
-
12MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Drawer/MaterialNodeDrawer.cs
-
155MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
-
182MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphView.cs
-
317MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs.meta
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs.meta
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs.meta
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs.meta
-
12MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializedGraphPresenter.cs.meta
-
328MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphPresenter.cs
-
322MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/AbstractGraphEditWindow.cs
-
17MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
-
150MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/SerializableGraphView.cs
|
|||
fileFormatVersion: 2 |
|||
guid: 6f78144783978984fbcfe74ef28bd314 |
|||
timeCreated: 1445419780 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 322c21863b8e2024e85c4f0e0dee0b94 |
|||
timeCreated: 1476711073 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 0f06001291d4e32479f71557abf52944 |
|||
timeCreated: 1476710182 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine.Graphing; |
|||
|
|||
namespace UnityEditor.Graphing.Drawing |
|||
{ |
|||
public class SerializedGraphPresenter : AbstractGraphPresenter |
|||
{ |
|||
protected SerializedGraphPresenter() |
|||
{ |
|||
typeMapper[typeof(SerializableNode)] = typeof(GraphNodePresenter); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 194f855484623804c819a9132a24268f |
|||
timeCreated: 1476707366 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: d7466f2e9546aaa409ea2125e36a0342 |
|||
timeCreated: 1476711073 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEditor.Experimental.UIElements.GraphView; |
|||
using UnityEditor.Graphing.Util; |
|||
using UnityEngine; |
|||
using UnityEngine.Graphing; |
|||
|
|||
namespace UnityEditor.Graphing.Drawing |
|||
{ |
|||
[Serializable] |
|||
public abstract class AbstractGraphPresenter : GraphViewPresenter |
|||
{ |
|||
protected GraphTypeMapper typeMapper { get; set; } |
|||
|
|||
public IGraphAsset graphAsset { get; private set; } |
|||
|
|||
[SerializeField] |
|||
private TitleBarPresenter m_TitleBar; |
|||
|
|||
[SerializeField] |
|||
private EditorWindow m_Container; |
|||
|
|||
public TitleBarPresenter titleBar |
|||
{ |
|||
get { return m_TitleBar; } |
|||
} |
|||
|
|||
protected AbstractGraphPresenter() |
|||
{ |
|||
typeMapper = new GraphTypeMapper(typeof(GraphNodePresenter)); |
|||
} |
|||
|
|||
void OnNodeChanged(INode inNode, ModificationScope scope) |
|||
{ |
|||
var dependentNodes = new List<INode>(); |
|||
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, inNode); |
|||
foreach (var node in dependentNodes) |
|||
{ |
|||
var theElements = m_Elements.OfType<GraphNodePresenter>().ToList(); |
|||
var found = theElements.Where(x => x.node.guid == node.guid).ToList(); |
|||
foreach (var drawableNodeData in found) |
|||
drawableNodeData.OnModified(scope); |
|||
} |
|||
|
|||
if (scope == ModificationScope.Topological) |
|||
UpdateData(); |
|||
|
|||
EditorUtility.SetDirty(graphAsset.GetScriptableObject()); |
|||
|
|||
if (m_Container != null) |
|||
m_Container.Repaint(); |
|||
} |
|||
|
|||
private void UpdateData() |
|||
{ |
|||
// Find all nodes currently being drawn which are no longer in the graph (i.e. deleted)
|
|||
var deletedElements = m_Elements |
|||
.OfType<GraphNodePresenter>() |
|||
.Where(nd => !graphAsset.graph.GetNodes<INode>().Contains(nd.node)) |
|||
.OfType<GraphElementPresenter>() |
|||
.ToList(); |
|||
|
|||
var deletedEdges = m_Elements.OfType<GraphEdgePresenter>() |
|||
.Where(ed => !graphAsset.graph.edges.Contains(ed.edge)); |
|||
|
|||
// Find all edges currently being drawn which are no longer in the graph (i.e. deleted)
|
|||
foreach (var edgeData in deletedEdges) |
|||
{ |
|||
// Make sure to disconnect the node, otherwise new connections won't be allowed for the used slots
|
|||
edgeData.output.Disconnect(edgeData); |
|||
edgeData.input.Disconnect(edgeData); |
|||
|
|||
var toNodeGuid = edgeData.edge.inputSlot.nodeGuid; |
|||
var toNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(nd => nd.node.guid == toNodeGuid); |
|||
if (toNode != null) |
|||
{ |
|||
// Make the input node (i.e. right side of the connection) re-render
|
|||
OnNodeChanged(toNode.node, ModificationScope.Graph); |
|||
} |
|||
|
|||
deletedElements.Add(edgeData); |
|||
} |
|||
|
|||
// Remove all nodes and edges marked for deletion
|
|||
foreach (var deletedElement in deletedElements) |
|||
{ |
|||
m_Elements.Remove(deletedElement); |
|||
} |
|||
|
|||
var addedNodes = new List<GraphNodePresenter>(); |
|||
|
|||
// Find all new nodes and mark for addition
|
|||
foreach (var node in graphAsset.graph.GetNodes<INode>()) |
|||
{ |
|||
// Check whether node already exists
|
|||
if (m_Elements.OfType<GraphNodePresenter>().Any(e => e.node == node)) |
|||
continue; |
|||
|
|||
var nodeData = (GraphNodePresenter)typeMapper.Create(node); |
|||
|
|||
node.onModified += OnNodeChanged; |
|||
|
|||
nodeData.Initialize(node); |
|||
addedNodes.Add(nodeData); |
|||
} |
|||
|
|||
// Create edge data for nodes marked for addition
|
|||
var drawableEdges = new List<GraphEdgePresenter>(); |
|||
foreach (var addedNode in addedNodes) |
|||
{ |
|||
var baseNode = addedNode.node; |
|||
foreach (var slot in baseNode.GetOutputSlots<ISlot>()) |
|||
{ |
|||
var sourceAnchors = addedNode.elements.OfType<GraphAnchorPresenter>(); |
|||
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 = addedNodes.FirstOrDefault(x => x.node == toNode); |
|||
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>(); |
|||
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot); |
|||
|
|||
var edgeData = CreateInstance<GraphEdgePresenter>(); |
|||
edgeData.Initialize(edge); |
|||
edgeData.output = sourceAnchor; |
|||
edgeData.output.Connect(edgeData); |
|||
edgeData.input = targetAnchor; |
|||
edgeData.input.Connect(edgeData); |
|||
drawableEdges.Add(edgeData); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Add nodes marked for addition
|
|||
m_Elements.AddRange(addedNodes.OfType<GraphElementPresenter>()); |
|||
|
|||
// Find edges in the graph that are not being drawn and create edge data for them
|
|||
foreach (var edge in graphAsset.graph.edges) |
|||
{ |
|||
if (!m_Elements.OfType<GraphEdgePresenter>().Any(ed => ed.edge == edge)) |
|||
{ |
|||
var fromNode = graphAsset.graph.GetNodeFromGuid(edge.outputSlot.nodeGuid); |
|||
var fromSlot = fromNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId); |
|||
var sourceNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == fromNode); |
|||
var sourceAnchors = sourceNode.elements.OfType<GraphAnchorPresenter>(); |
|||
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == fromSlot); |
|||
|
|||
var toNode = graphAsset.graph.GetNodeFromGuid(edge.inputSlot.nodeGuid); |
|||
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId); |
|||
var targetNode = m_Elements.OfType<GraphNodePresenter>().FirstOrDefault(x => x.node == toNode); |
|||
var targetAnchors = targetNode.elements.OfType<GraphAnchorPresenter>(); |
|||
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot); |
|||
|
|||
OnNodeChanged(targetNode.node, ModificationScope.Graph); |
|||
|
|||
var edgeData = CreateInstance<GraphEdgePresenter>(); |
|||
edgeData.Initialize(edge); |
|||
edgeData.output = sourceAnchor; |
|||
edgeData.output.Connect(edgeData); |
|||
edgeData.input = targetAnchor; |
|||
edgeData.input.Connect(edgeData); |
|||
drawableEdges.Add(edgeData); |
|||
} |
|||
} |
|||
|
|||
m_Elements.AddRange(drawableEdges.OfType<GraphElementPresenter>()); |
|||
} |
|||
|
|||
public virtual void Initialize(IGraphAsset graphAsset, AbstractGraphEditWindow container) |
|||
{ |
|||
this.graphAsset = graphAsset; |
|||
m_Container = container; |
|||
|
|||
m_TitleBar = CreateInstance<TitleBarPresenter>(); |
|||
m_TitleBar.Initialize(container); |
|||
|
|||
if (graphAsset == null) |
|||
return; |
|||
|
|||
UpdateData(); |
|||
} |
|||
|
|||
public void AddNode(INode node) |
|||
{ |
|||
graphAsset.graph.AddNode(node); |
|||
EditorUtility.SetDirty(graphAsset.GetScriptableObject()); |
|||
UpdateData(); |
|||
} |
|||
|
|||
public void RemoveElements(IEnumerable<GraphNodePresenter> nodes, IEnumerable<GraphEdgePresenter> edges) |
|||
{ |
|||
graphAsset.graph.RemoveElements(nodes.Select(x => x.node), edges.Select(x => x.edge)); |
|||
graphAsset.graph.ValidateGraph(); |
|||
EditorUtility.SetDirty(graphAsset.GetScriptableObject()); |
|||
UpdateData(); |
|||
} |
|||
|
|||
public void Connect(GraphAnchorPresenter left, GraphAnchorPresenter right) |
|||
{ |
|||
if (left != null && right != null) |
|||
{ |
|||
graphAsset.graph.Connect(left.slot.slotReference, right.slot.slotReference); |
|||
EditorUtility.SetDirty(graphAsset.GetScriptableObject()); |
|||
UpdateData(); |
|||
} |
|||
} |
|||
|
|||
private CopyPasteGraph CreateCopyPasteGraph(IEnumerable<GraphElementPresenter> selection) |
|||
{ |
|||
var graph = new CopyPasteGraph(); |
|||
foreach (var presenter in selection) |
|||
{ |
|||
var nodePresenter = presenter as GraphNodePresenter; |
|||
if (nodePresenter != null) |
|||
{ |
|||
graph.AddNode(nodePresenter.node); |
|||
foreach (var edge in NodeUtils.GetAllEdges(nodePresenter.node)) |
|||
graph.AddEdge(edge); |
|||
} |
|||
|
|||
var edgePresenter = presenter as GraphEdgePresenter; |
|||
if (edgePresenter != null) |
|||
graph.AddEdge(edgePresenter.edge); |
|||
} |
|||
return graph; |
|||
} |
|||
|
|||
private CopyPasteGraph DeserializeCopyBuffer(string copyBuffer) |
|||
{ |
|||
try |
|||
{ |
|||
return JsonUtility.FromJson<CopyPasteGraph>(copyBuffer); |
|||
} |
|||
catch |
|||
{ |
|||
// ignored. just means copy buffer was not a graph :(
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private void InsertCopyPasteGraph(CopyPasteGraph graph) |
|||
{ |
|||
if (graph == null || graphAsset == null || graphAsset.graph == null) |
|||
return; |
|||
|
|||
var addedNodes = new List<INode>(); |
|||
|
|||
var nodeGuidMap = new Dictionary<Guid, Guid>(); |
|||
foreach (var node in graph.GetNodes<INode>()) |
|||
{ |
|||
var oldGuid = node.guid; |
|||
var newGuid = node.RewriteGuid(); |
|||
nodeGuidMap[oldGuid] = newGuid; |
|||
|
|||
var drawState = node.drawState; |
|||
var position = drawState.position; |
|||
position.x += 30; |
|||
position.y += 30; |
|||
drawState.position = position; |
|||
node.drawState = drawState; |
|||
graphAsset.graph.AddNode(node); |
|||
addedNodes.Add(node); |
|||
} |
|||
|
|||
// only connect edges within pasted elements, discard
|
|||
// external edges.
|
|||
var addedEdges = new List<IEdge>(); |
|||
|
|||
foreach (var edge in graph.edges) |
|||
{ |
|||
var outputSlot = edge.outputSlot; |
|||
var inputSlot = edge.inputSlot; |
|||
|
|||
Guid remappedOutputNodeGuid; |
|||
Guid remappedInputNodeGuid; |
|||
if (nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid) |
|||
&& nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid)) |
|||
{ |
|||
var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); |
|||
var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); |
|||
addedEdges.Add(graphAsset.graph.Connect(outputSlotRef, inputSlotRef)); |
|||
} |
|||
} |
|||
|
|||
graphAsset.graph.ValidateGraph(); |
|||
UpdateData(); |
|||
|
|||
graphAsset.drawingData.selection = addedNodes.Select(n => n.guid); |
|||
} |
|||
|
|||
public void Copy(IEnumerable<GraphElementPresenter> selection) |
|||
{ |
|||
var graph = CreateCopyPasteGraph(selection); |
|||
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graph, true); |
|||
} |
|||
|
|||
public void Duplicate(IEnumerable<GraphElementPresenter> selection) |
|||
{ |
|||
var graph = DeserializeCopyBuffer(JsonUtility.ToJson(CreateCopyPasteGraph(selection), true)); |
|||
InsertCopyPasteGraph(graph); |
|||
} |
|||
|
|||
public void Paste() |
|||
{ |
|||
var pastedGraph = DeserializeCopyBuffer(EditorGUIUtility.systemCopyBuffer); |
|||
InsertCopyPasteGraph(pastedGraph); |
|||
} |
|||
|
|||
public override void AddElement(EdgePresenter edge) |
|||
{ |
|||
Connect(edge.output as GraphAnchorPresenter, edge.input as GraphAnchorPresenter); |
|||
} |
|||
|
|||
public override void AddElement(GraphElementPresenter element) |
|||
{ |
|||
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store"); |
|||
} |
|||
|
|||
public override void RemoveElement(GraphElementPresenter element) |
|||
{ |
|||
throw new ArgumentException("Not supported on Serializable Graph, data comes from data store"); |
|||
} |
|||
} |
|||
} |
|
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using UnityEditor.Experimental.UIElements.GraphView; |
|||
using UnityEngine; |
|||
using UnityEngine.Graphing; |
|||
using UnityEngine.MaterialGraph; |
|||
using Object = UnityEngine.Object; |
|||
|
|||
namespace UnityEditor.Graphing.Drawing |
|||
{ |
|||
public abstract class AbstractGraphEditWindow : EditorWindow, ISerializationCallbackReceiver |
|||
{ |
|||
public abstract IGraphAsset inMemoryAsset { get; set; } |
|||
public abstract Object selected { get; set; } |
|||
|
|||
public static bool allowAlwaysRepaint = true; |
|||
|
|||
private bool shouldRepaint |
|||
{ |
|||
get |
|||
{ |
|||
return allowAlwaysRepaint && inMemoryAsset != null && inMemoryAsset.shouldRepaint; |
|||
} |
|||
} |
|||
|
|||
protected GraphView graphView |
|||
{ |
|||
get { return m_GraphEditorDrawer.graphView; } |
|||
} |
|||
|
|||
private GraphEditorDrawer m_GraphEditorDrawer; |
|||
|
|||
public virtual AbstractGraphPresenter CreateDataSource() |
|||
{ |
|||
return CreateInstance<SerializedGraphPresenter>(); |
|||
} |
|||
|
|||
public virtual GraphView CreateGraphView() |
|||
{ |
|||
return new SerializableGraphView(this); |
|||
} |
|||
|
|||
void OnEnable() |
|||
{ |
|||
m_GraphEditorDrawer = new GraphEditorDrawer(CreateGraphView()); |
|||
rootVisualContainer.Add(m_GraphEditorDrawer); |
|||
var source = CreateDataSource(); |
|||
source.Initialize(inMemoryAsset, this); |
|||
m_GraphEditorDrawer.presenter = source; |
|||
} |
|||
|
|||
void OnDisable() |
|||
{ |
|||
rootVisualContainer.Clear(); |
|||
} |
|||
|
|||
void Update() |
|||
{ |
|||
if (shouldRepaint) |
|||
Repaint(); |
|||
} |
|||
|
|||
public void PingAsset() |
|||
{ |
|||
if (selected != null) |
|||
EditorGUIUtility.PingObject(selected); |
|||
} |
|||
|
|||
public void UpdateAsset() |
|||
{ |
|||
if (selected != null && inMemoryAsset != null) |
|||
{ |
|||
var path = AssetDatabase.GetAssetPath(selected); |
|||
if (string.IsNullOrEmpty(path) || inMemoryAsset == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var masterNode = ((MaterialGraphAsset)inMemoryAsset).materialGraph.masterNode; |
|||
if (masterNode == null) |
|||
return; |
|||
|
|||
List<PropertyGenerator.TextureInfo> configuredTextures; |
|||
masterNode.GetFullShader(GenerationMode.ForReals, "NotNeeded", out configuredTextures); |
|||
|
|||
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter; |
|||
if (shaderImporter == null) |
|||
return; |
|||
|
|||
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()); |
|||
File.WriteAllText(path, EditorJsonUtility.ToJson(inMemoryAsset.graph)); |
|||
shaderImporter.SaveAndReimport(); |
|||
AssetDatabase.ImportAsset(path); |
|||
|
|||
} |
|||
} |
|||
|
|||
public virtual void ToggleRequiresTime() |
|||
{ |
|||
allowAlwaysRepaint = !allowAlwaysRepaint; |
|||
} |
|||
|
|||
public void ChangeSelction(Object newSelection) |
|||
{ |
|||
if (!EditorUtility.IsPersistent (newSelection)) |
|||
return; |
|||
|
|||
if (selected == newSelection) |
|||
return; |
|||
|
|||
if (selected != null) |
|||
{ |
|||
if (EditorUtility.DisplayDialog ("Save Old Graph?", "Save Old Graph?", "yes!", "no")) { |
|||
UpdateAsset (); |
|||
} |
|||
} |
|||
|
|||
selected = newSelection; |
|||
|
|||
var mGraph = CreateInstance<MaterialGraphAsset>(); |
|||
var path = AssetDatabase.GetAssetPath(newSelection); |
|||
var textGraph = File.ReadAllText(path, Encoding.UTF8); |
|||
mGraph.materialGraph = JsonUtility.FromJson<UnityEngine.MaterialGraph.MaterialGraph>(textGraph); |
|||
|
|||
inMemoryAsset = mGraph; |
|||
var graph = inMemoryAsset.graph; |
|||
graph.OnEnable (); |
|||
graph.ValidateGraph (); |
|||
|
|||
var source = CreateDataSource (); |
|||
source.Initialize (inMemoryAsset, this) ; |
|||
m_GraphEditorDrawer.presenter = source; |
|||
//m_GraphView.StretchToParentSize();
|
|||
Repaint (); |
|||
/*if (refocus) |
|||
{ |
|||
focused = false; |
|||
m_GraphEditorDrawer.graphView.Schedule (Focus).StartingIn (1).Until (() => focused); |
|||
}*/ |
|||
} |
|||
|
|||
public void OnBeforeSerialize() |
|||
{ |
|||
//m_ToLoad = m_Selected as ScriptableObject;
|
|||
} |
|||
|
|||
public void OnAfterDeserialize() |
|||
{} |
|||
|
|||
/* |
|||
private void ConvertSelectionToSubGraph() |
|||
{ |
|||
if (m_Canvas.presenter == null) |
|||
return; |
|||
|
|||
var presenter = m_Canvas.presenter as GraphDataSource; |
|||
if (presenter == null) |
|||
return; |
|||
|
|||
var asset = presenter.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(); |
|||
presenter.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(); |
|||
}*/ |
|||
|
|||
|
|||
} |
|||
} |
|
|||
using UnityEngine; |
|||
using UnityEngine.Graphing; |
|||
|
|||
namespace UnityEditor.Graphing.Drawing |
|||
{ |
|||
public class GraphEditWindow : AbstractGraphEditWindow |
|||
{ |
|||
public override IGraphAsset inMemoryAsset { get; set; } |
|||
|
|||
public override Object selected { get; set; } |
|||
|
|||
public GraphEditWindow(string path) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEditor.Experimental.UIElements.GraphView; |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.UIElements; |
|||
|
|||
namespace UnityEditor.Graphing.Drawing |
|||
{ |
|||
// TODO JOCE Maybe bring SimpleGraphView public. This implements pretty much all that it does.
|
|||
public class SerializableGraphView : GraphView |
|||
{ |
|||
private ShortcutHandler m_ShortcutHandler; |
|||
private EditorWindow m_EditorWindow; |
|||
|
|||
public SerializableGraphView(EditorWindow editorWindow) |
|||
{ |
|||
m_EditorWindow = editorWindow; |
|||
m_ShortcutHandler = new ShortcutHandler( |
|||
new Dictionary<Event, ShortcutDelegate> |
|||
{ |
|||
{Event.KeyboardEvent("a"), FrameAll}, |
|||
{Event.KeyboardEvent("f"), FrameSelection}, |
|||
{Event.KeyboardEvent("o"), FrameOrigin}, |
|||
{Event.KeyboardEvent("delete"), DeleteSelection}, |
|||
{Event.KeyboardEvent("#tab"), FramePrev}, |
|||
{Event.KeyboardEvent("tab"), FrameNext}, |
|||
{Event.KeyboardEvent("#c"), CopySelection}, |
|||
{Event.KeyboardEvent("#v"), Paste}, |
|||
{Event.KeyboardEvent("#d"), DuplicateSelection} |
|||
}); |
|||
|
|||
onEnter += () => m_EditorWindow.rootVisualContainer.parent.AddManipulator(m_ShortcutHandler); |
|||
onLeave += () => m_EditorWindow.rootVisualContainer.parent.RemoveManipulator(m_ShortcutHandler); |
|||
|
|||
this.AddManipulator(new Commandable |
|||
{ |
|||
{ "Duplicate", () => true, () => Debug.Log("Duplicate!") }, |
|||
{ "Copy", () => true, () => Debug.Log("Copy!") } |
|||
}); |
|||
|
|||
this.AddManipulator(new ClickGlobalSelector()); |
|||
this.AddManipulator(new ContentZoomer()); |
|||
this.AddManipulator(new ContentDragger()); |
|||
this.AddManipulator(new RectangleSelector()); |
|||
this.AddManipulator(new SelectionDragger()); |
|||
this.AddManipulator(new ClickSelector()); |
|||
|
|||
Insert(0, new GridBackground()); |
|||
|
|||
typeFactory[typeof(GraphNodePresenter)] = typeof(NodeDrawer); |
|||
} |
|||
|
|||
// TODO JOCE Remove the "new" here. Use the base class' impl
|
|||
private new EventPropagation DeleteSelection() |
|||
{ |
|||
var nodalViewData = GetPresenter<AbstractGraphPresenter>(); |
|||
if (nodalViewData == null) |
|||
return EventPropagation.Stop; |
|||
|
|||
nodalViewData.RemoveElements( |
|||
selection.OfType<NodeDrawer>().Select(x => x.GetPresenter<GraphNodePresenter>()), |
|||
selection.OfType<Edge>().Select(x => x.GetPresenter<GraphEdgePresenter>()) |
|||
); |
|||
|
|||
return EventPropagation.Stop; |
|||
} |
|||
|
|||
public override void OnDataChanged() |
|||
{ |
|||
base.OnDataChanged(); |
|||
|
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (graphDataSource == null) |
|||
return; |
|||
|
|||
var graphAsset = graphDataSource.graphAsset; |
|||
if (graphAsset == null || graphAsset.drawingData.selection.SequenceEqual(selection.OfType<NodeDrawer>().Select(d => ((GraphNodePresenter) d.presenter).node.guid))) return; |
|||
|
|||
var selectedDrawers = graphDataSource.graphAsset.drawingData.selection |
|||
.Select(guid => contentViewContainer |
|||
.OfType<NodeDrawer>() |
|||
.FirstOrDefault(drawer => ((GraphNodePresenter) drawer.presenter).node.guid == guid)) |
|||
.ToList(); |
|||
|
|||
ClearSelection(); |
|||
foreach (var drawer in selectedDrawers) |
|||
AddToSelection(drawer); |
|||
} |
|||
|
|||
public void SetGlobalSelection() |
|||
{ |
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (graphDataSource == null || graphDataSource.graphAsset == null) |
|||
return; |
|||
//Selection.activeObject = graphDataSource.graphAsset.GetScriptableObject();
|
|||
} |
|||
|
|||
private void PropagateSelection() |
|||
{ |
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (graphDataSource == null || graphDataSource.graphAsset == null) |
|||
return; |
|||
|
|||
var selectedNodeGuids = selection.OfType<NodeDrawer>().Select(x => ((GraphNodePresenter) x.presenter).node.guid); |
|||
graphDataSource.graphAsset.drawingData.selection = selectedNodeGuids; |
|||
} |
|||
|
|||
public override void AddToSelection(ISelectable selectable) |
|||
{ |
|||
base.AddToSelection(selectable); |
|||
PropagateSelection(); |
|||
} |
|||
|
|||
public override void RemoveFromSelection(ISelectable selectable) |
|||
{ |
|||
base.RemoveFromSelection(selectable); |
|||
PropagateSelection(); |
|||
} |
|||
|
|||
public override void ClearSelection() |
|||
{ |
|||
base.ClearSelection(); |
|||
PropagateSelection(); |
|||
} |
|||
|
|||
public EventPropagation CopySelection() |
|||
{ |
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (selection.Any() && graphDataSource != null) |
|||
graphDataSource.Copy(selection.OfType<GraphElement>().Select(ge => ge.presenter)); |
|||
return EventPropagation.Stop; |
|||
} |
|||
|
|||
public EventPropagation DuplicateSelection() |
|||
{ |
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (selection.Any() && graphDataSource != null) |
|||
graphDataSource.Duplicate(selection.OfType<GraphElement>().Select(ge => ge.presenter)); |
|||
return EventPropagation.Stop; |
|||
} |
|||
|
|||
public EventPropagation Paste() |
|||
{ |
|||
var graphDataSource = GetPresenter<AbstractGraphPresenter>(); |
|||
if (graphDataSource != null) |
|||
graphDataSource.Paste(); |
|||
return EventPropagation.Stop; |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue