//Create Object from Data public static NodeGraph LoadData(NodeGraphData graphdata) { NodeGraph graph = CreateInstance<NodeGraph>(); graph.Name = graphdata.Name; graph.scrollPos = graphdata.scrollPos; for (int i = 0; i < graphdata.nodes.Count; i++) { Node node = ScriptableObject.CreateInstance(graphdata.nodes[i].NodeType) as Node; node.ID = graphdata.nodes[i].NodeID; node = node.Create(graphdata.nodes[i].NodePos); node.properties.CopyPropertiesDataFrom(graphdata.nodes[i].properties); graph.nodes.Add(node); } for (int i = 0; i < graphdata.connections.Count; i++) { Connection connection = new Connection(); connection.ID = graphdata.connections[i].ID; connection.startSocket = (SocketOut)GetSocket(graph, graphdata.connections[i].OutNodeID, graphdata.connections[i].OutNodeSocketID); connection.endSocket = (SocketIn)GetSocket(graph, graphdata.connections[i].InNodeID, graphdata.connections[i].InNodeSocketID); //TODO: cleaner structure connection.startSocket.connections.Add(connection); connection.endSocket.connections.Add(connection); } return graph; }
public static bool IsConnectionLoop(SocketIn inSocket, Connection connection) { if (inSocket.parentNode == connection.startSocket.parentNode) return true; else { //var nodes = GetAllOutputConnections(inSocket.parentNode); return RekursivLoopingCheck(inSocket, connection, inSocket.parentNode); } }
private static bool RekursivLoopingCheck(SocketIn inSocket, Connection connection, Node node) { var connections = GetAllOutputConnections(node); if (connections == null || connections.Length == 0) return false; bool isLooping = false; for (int i = 0; i < connections.Length; i++) { if (connections[i].endSocket.parentNode == connection.startSocket.parentNode) { isLooping = true; break; } else isLooping = RekursivLoopingCheck(inSocket, connection, connections[i].endSocket.parentNode); } return isLooping; }
void OnGUI() { GUI.skin = GUIx.I.skin; Event e = Event.current; //remove mousewheel input if (e.type == EventType.ScrollWheel) e.Use(); if (editorWindow) editorWindow.minSize = new Vector2(512, 512); else ShowEditor(); //init rects sideWindowRect = new Rect(0, 0, 155, editorWindow.position.height); scrollViewRect = new Rect(sideWindowRect.width, 0, editorWindow.position.width - sideWindowRect.width, editorWindow.position.height); if (Graph != null) { if (Graph.nodes.Count > 0) { if (Graph.nodes[0] == null) { Debug.LogWarning("Reload from XML..."); ImportGraphFromXML(Graph.Name); return; } } //Init NodeEditor NodeEditor.mousePos = e.mousePosition; NodeEditor.viewOffset.x = scrollViewRect.x; NodeEditor.viewOffset.y = scrollViewRect.y; NodeEditor.canvasSize = new Vector2(4000,4000); //Update Hover NodeEditor.hoveredNode = GetNodeFromMousePos(NodeEditor.mousePos, Graph.nodes); if (NodeEditor.hoveredNode != null) NodeEditor.hoveredSocket = GetSocketFromMousePos(NodeEditor.hoveredNode, NodeEditor.mousePos); Repaint(); //Create nodes ContextMenu(e); //check if select output socket if (e.button == 0 && e.type == EventType.MouseDown && !NodeEditor.IsDragging) { var node = GetNodeFromMousePos(NodeEditor.mousePos, Graph.nodes); //Debug.LogWarning("node: " + node); if (node != null) { var socket = GetSocketFromMousePos(node, NodeEditor.mousePos); //Debug.LogWarning("socket: " + socket); if (socket != null && socket is SocketOut) { Debug.LogWarning("socket: " + socket); NodeEditor.CreateConnectionMode = true; NodeEditor.startSocket = socket as SocketOut; NodeEditor.tentativeConnection = new Connection(); NodeEditor.tentativeConnection.startSocket = NodeEditor.startSocket; e.Use(); } //else //Debug.LogWarning("no socket clicked!"); } //else //Debug.LogWarning("no node clicked!"); } if (e.button == 0 && e.type == EventType.MouseUp && NodeEditor.CreateConnectionMode && !NodeEditor.IsDragging) { var node = GetNodeFromMousePos(NodeEditor.mousePos, Graph.nodes); if (node != null) { var socket = GetSocketFromMousePos(node, NodeEditor.mousePos); if (socket != null && socket is SocketIn && socket.parentNode != NodeEditor.startSocket.parentNode && !NodeEditor.IsConnectionLoop(socket as SocketIn, NodeEditor.tentativeConnection) && !NodeEditor.IsDoubleConnection(socket as SocketIn, NodeEditor.tentativeConnection.startSocket) && socket.typeData.Type == NodeEditor.startSocket.typeData.Type) { //Debug.LogWarning("socket: " + socket); NodeEditor.CreateConnectionMode = false; NodeEditor.endSocket = socket as SocketIn; var link = new Connection(); link.ID = NodeEditor.CreateID(); link.startSocket = NodeEditor.startSocket; link.endSocket = NodeEditor.endSocket; NodeEditor.startSocket.connections.Add(link); NodeEditor.endSocket.connections.Add(link); //DestroyImmediate(NodeEditor.tentativeConnection); NodeEditor.tentativeConnection = null; e.Use(); } } NodeEditor.CreateConnectionMode = false; //DestroyImmediate(NodeEditor.tentativeConnection); NodeEditor.tentativeConnection = null; } //handle input first => !draw order if (!NodeEditor.CreateConnectionMode && GUI.GetNameOfFocusedControl() == "") DragNodes(e, Graph.nodes); //GUI.Box(scrollViewRect, GUIx.empty, GUIx.I.window); try { Graph.scrollPos = GUI.BeginScrollView(scrollViewRect, Graph.scrollPos, new Rect(0, 0, NodeEditor.canvasSize.x, NodeEditor.canvasSize.y), false, false); //background //TODO: only draw visible for (int i = 0; i < NodeEditor.canvasSize.x / GUIx.I.background.fixedWidth; i++) { GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, 0, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 2, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 3, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 4, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 5, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 6, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 7, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); //GUI.DrawTexture(new Rect(GUIx.I.background.fixedWidth * i, GUIx.I.background.fixedWidth * 8, GUIx.I.background.fixedWidth, GUIx.I.background.fixedHeight), GUIx.I.background.normal.background); } // Draw nodes for (int i = 0; i < Graph.nodes.Count; i++) { Graph.nodes[i].DrawNode(); } //GUILayout.EndScrollView(); GUI.EndScrollView(); // Check if the mouse is above our scrollview. if (e.button == 2 && e.type == EventType.MouseDown && scrollViewRect.Contains(Event.current.mousePosition) && !NodeEditor.isPanning) NodeEditor.isPanning = true; else if (e.button == 2 && e.type == EventType.MouseUp && NodeEditor.isPanning) NodeEditor.isPanning = false; //Debug.LogWarning(NodeEditor.isPanning); if (NodeEditor.isPanning) { // Only move if the distance between the last mouse position and the current is less than 50. // Without this it jumps during the drag. if (Vector2.Distance(NodeEditor.mousePos, NodeEditor.lastMousePos) < 50) { // Calculate the delta x and y. float x = NodeEditor.lastMousePos.x - NodeEditor.mousePos.x; float y = NodeEditor.lastMousePos.y - NodeEditor.mousePos.y; // Add the delta moves to the scroll position. Graph.scrollPos.x += x; Graph.scrollPos.y += y; //Event.current.Use(); Repaint(); } } if (Event.current.button == 0 && NodeEditor.CreateConnectionMode) { NodeEditor.tentativeConnection.DrawConnection(new Rect(NodeEditor.mousePos.x, NodeEditor.mousePos.y, 1, 1)); Repaint(); } //draw curves for (int i = Graph.nodes.Count - 1; i >= 0; i -= 1) { for (int n = 0; n < Graph.nodes[i].Outputs.Count; n++) { for (int k = 0; k < Graph.nodes[i].Outputs[n].connections.Count; k++) { Graph.nodes[i].Outputs[n].connections[k].DrawConnection(); Repaint(); } } } } catch (System.Exception) { } } if (!sideWindowRect.Contains(Event.current.mousePosition) && (Event.current.button == 0 || Event.current.button == 1) && Event.current.type == EventType.MouseDown) GUI.FocusControl(""); //Debug.LogWarning(sideWindowRect); try { GUILayout.BeginArea(sideWindowRect, GUI.skin.box); //DrawSideWindow(); if (Graph == null) StatusMsg = "nothing loaded!"; else StatusMsg = "loaded " + Graph.Name; GUILayout.Label("Status: " + StatusMsg); NodeEditor.NodeGraphName = GUILayout.TextField(NodeEditor.NodeGraphName, 32, GUILayout.ExpandWidth(true)); GUI.enabled = NodeEditor.NodeGraphName != ""; if (GUILayout.Button("Create")) { if (!File.Exists("Assets/Resources/" + NodeEditor.NodeGraphName + ".asset")) { var asset = CreateInstance<NodeGraph>(); asset.Name = NodeEditor.NodeGraphName; DataAssetCreator.CreateDataAsset(NodeEditor.NodeGraphName, asset); if (!File.Exists("NodeGraphs/" + NodeEditor.NodeGraphName + ".xml")) { string path = "NodeGraphs/" + NodeEditor.NodeGraphName + ".xml"; var data = NodeGraph.CreateData(asset); Serialization.SaveToUTF8XmlFile(data, path); } if (asset != null) { asset.Name = NodeEditor.NodeGraphName; NodeEditor.Graph = asset; StatusMsg = "created " + Graph.Name; } } else Debug.LogWarning("Asset already exists!"); } GUI.enabled = NodeEditor.NodeGraphName != ""; if (GUILayout.Button("Load")) { NodeGraph tmp = Resources.Load<NodeGraph>(NodeEditor.NodeGraphName); if (tmp != null) { StatusMsg = "loaded " + tmp.Name; NodeEditor.Graph = tmp; } } GUI.enabled = Graph != null; if (GUILayout.Button("Center View")) { Graph.scrollPos = new Vector2(NodeEditor.canvasSize.x * 0.5f, NodeEditor.canvasSize.y * 0.5f); } GUI.enabled = true; GUI.enabled = Graph != null; if (GUILayout.Button("Calc Order")) { CalculateNodeOrder(); } GUI.enabled = true; GUI.enabled = Graph != null; if (GUILayout.Button("Export to XML")) { string path = "NodeGraphs/" + Graph.Name + ".xml"; var data = NodeGraph.CreateData(Graph); Serialization.SaveToUTF8XmlFile(data, path); } GUI.enabled = true; //GUI.enabled = Graph != null; if (GUILayout.Button("Import from XML")) { ImportGraphFromXML(NodeEditor.NodeGraphName); } GUILayout.EndArea(); } catch (System.Exception) { } NodeEditor.lastMousePos = Event.current.mousePosition; }