void DrawConnections(MarrowNode node) { for (int i = 0; i < node.GetOutputSize(); i++) { MarrowNode connectTo = node.GetOutput(i); if (connectTo == null) { break; } Handles.BeginGUI(); Handles.color = Color.black; Rect startBox = GetConnectionBox(false, i, node); Vector3 startPos = new Vector3(node.editorPosition.xMax, node.editorPosition.y + startBox.center.y - 5, 0); Rect endBox = GetConnectionBox(true, node.GetOutputConnection(i), node); Vector3 endPos = new Vector3(connectTo.editorPosition.x, connectTo.editorPosition.y + endBox.center.y - 5, 0); Vector3 startTangent = startPos + Vector3.right * (Vector3.Distance(startPos, endPos) / 3F); Vector3 endTangent = endPos + Vector3.left * (Vector3.Distance(startPos, endPos) / 3F); Handles.DrawBezier(startPos, endPos, startTangent, endTangent, Color.black, null, 2); Handles.EndGUI(); } }
/// <summary> /// Sets the number of outputs. /// </summary> /// <param name='size'> /// Size. /// </param> public virtual void SetOutputSize(int size) { if (outputs == null) { outputs = new MarrowNode[size]; outputConnections = new int[size]; } else { MarrowNode[] newOutputs = new MarrowNode[size]; if (size > outputs.Length) { outputs.CopyTo(newOutputs, 0); } else { System.Array.Copy(outputs, 0, newOutputs, 0, size); } outputs = newOutputs; int[] newConnections = new int[size]; if (size > outputConnections.Length) { outputConnections.CopyTo(newConnections, 0); } else { System.Array.Copy(outputConnections, 0, newConnections, 0, size); } outputConnections = newConnections; } }
void OnEnable() { NodeTypes = GetNodeTypes(); NodeFoldouts = new bool[System.Enum.GetNames(typeof(NodeDescription.Type)).Length]; inspected = null; OnSelectionChange(); }
void RemoveNode(MarrowNode toRemove) { foreach (MarrowNode node in nodes) { node.Sever(toRemove); } nodes.Remove(toRemove); DestroyImmediate(toRemove); }
Rect GetConnectionBox(bool isInput, int num, MarrowNode node) { if (isInput) { return(new Rect(0, (num * 18) + 20, node.editorPosition.width, 24)); } else { return(new Rect(0, (num * 18) + 20 + (node.GetInputSize() * 18), node.editorPosition.width, 24)); } }
/// <summary> /// Sever the specified node. /// </summary> /// <param name='node'> /// Node. /// </param> public void Sever(MarrowNode node) { for (int i = 0; i < outputs.Length; i++) { if (outputs[i] == node) { outputs[i].SetInput(outputConnections[i], null); outputs[i] = null; outputConnections[i] = 0; } } }
void DrawToolbar(int windowID) { GUILayout.Label("Add Node"); nodeTypeScrollPosition = GUILayout.BeginScrollView( nodeTypeScrollPosition); foreach (KeyValuePair <NodeDescription.Type, List <System.Type> > kvp in NodeTypes) { NodeFoldouts[(int)kvp.Key] = EditorGUILayout.Foldout(NodeFoldouts[(int)kvp.Key], kvp.Key.ToString()); if (NodeFoldouts[(int)kvp.Key]) { foreach (System.Type t in kvp.Value) { string label = "Undefined Name"; System.Attribute[] attrs = (System.Attribute[])t.GetCustomAttributes(false); foreach (System.Attribute attr in attrs) { if (attr is NodeDescription) { label = ((NodeDescription)attr).GetName(); } } if (GUILayout.Button(label)) { System.Reflection.MethodInfo method = this.GetType().GetMethod("AddNode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); System.Reflection.MethodInfo generic = method.MakeGenericMethod(new System.Type[] { t }); generic.Invoke(this, null); } } } } GUILayout.EndScrollView(); if (GUILayout.Button("Clear All")) { if (nodes != null) { foreach (MarrowNode node in nodes) { DestroyImmediate(node); } inspected = null; nodes.Clear(); } } GUI.DragWindow(); }
void AddNode <T>() where T : MarrowNode { MarrowNode node = CreateInstance <T>(); node.editorPosition = new Rect(position.width / 3, position.height / 2, 100, 100); node.SetInputSize(node.GetDefaultInputs()); node.SetOutputSize(node.GetDefaultOutputs()); node.OnCreate(); node.gameObject = Selection.activeGameObject; nodes.Add(node); Repaint(); EditorUtility.SetDirty(Selection.activeGameObject); }
void OnSelectionChange() { if (Selection.activeGameObject != null && Selection.activeGameObject.GetComponent <Marrow>() != null) { nodes = Selection.activeGameObject.GetComponent <Marrow>().GetNodes(); } else { nodes = null; } inspected = null; Repaint(); }
Dictionary <string, System.Reflection.FieldInfo> GetNodeProperties(MarrowNode node) { Dictionary <string, System.Reflection.FieldInfo> nodeProperties = new Dictionary <string, System.Reflection.FieldInfo>(); System.Reflection.FieldInfo[] fields = node.GetType().GetFields(); foreach (System.Reflection.FieldInfo field in fields) { foreach (System.Attribute attr in field.GetCustomAttributes(false)) { if (attr is MarrowProperty) { nodeProperties.Add(field.ToString(), field); } } } return(nodeProperties); }
void NodeSelect(MarrowNode node) { if (Event.current.type == EventType.MouseDown) { Rect window = new Rect(0, 0, node.editorPosition.width, node.editorPosition.height); if (window.Contains(Event.current.mousePosition)) { if (Event.current.button == 0) { inspected = node; inspectorFields = GetNodeProperties(inspected); } else if (Event.current.button == 1 && Event.current.modifiers == EventModifiers.Control) { RemoveNode(node); } } } }
void DrawNode(int nodeID) { MarrowNode node = nodes[nodeID]; for (int i = 0; i < node.GetInputSize(); i++) { Rect connectionBox = GetConnectionBox(true, i, node); if (ClickBox(new Rect(0, connectionBox.y + 3, 10, 10), node.editorPosition)) { link.input = node; link.inputNumber = i; OnLink(); } GUI.Label(new Rect(12, connectionBox.y, connectionBox.width, connectionBox.height), node.InputLabels[i]); } for (int i = 0; i < node.GetOutputSize(); i++) { Rect connectionBox = GetConnectionBox(false, i, node); if (ClickBox(new Rect(connectionBox.xMax - 10, connectionBox.y + 3, 10, 10), node.editorPosition)) { link.output = node; link.outputNumber = i; OnLink(); } GUI.Label(new Rect(0, connectionBox.y, connectionBox.width, connectionBox.height), node.OutputLabels[i]); } NodeSelect(node); GUI.DragWindow(); if (snap) { node.editorPosition.x = Mathf.Floor(node.editorPosition.x / gridSize) * gridSize; node.editorPosition.y = Mathf.Floor(node.editorPosition.y / gridSize) * gridSize; } node.editorPosition.width = 100; node.editorPosition.height = 30 + ((node.GetOutputSize() + node.GetInputSize()) * 18); }
/// <summary> /// Sets the number of inputs. /// </summary> /// <param name='size'> /// Size. /// </param> public virtual void SetInputSize(int size) { if (inputs == null) { inputs = new MarrowNode[size]; } else { MarrowNode[] newInputs = new MarrowNode[size]; if (size > inputs.Length) { inputs.CopyTo(newInputs, 0); } else { System.Array.Copy(inputs, 0, newInputs, 0, size); } inputs = newInputs; } }
/// <summary> /// Sets the input. Usually, you won't need to use this. /// Instead just set the output on the other side of the /// connection. /// </summary> /// <param name='number'> /// Number of the input. /// </param> /// <param name='item'> /// Node to connect. /// </param> public void SetInput(int number, MarrowNode item) { inputs[number] = item; }
/// <summary> /// Sets the output. /// </summary> /// <param name='number'> /// Number of the output. /// </param> /// <param name='item'> /// Node that this output will connect to. /// </param> /// <param name='input'> /// The receiving input. /// </param> public void SetOutput(int number, MarrowNode item, int input) { outputs[number] = item; outputConnections[number] = input; item.SetInput(input, this); }
/// <summary> /// Sets the number of outputs. /// </summary> /// <param name='size'> /// Size. /// </param> public virtual void SetOutputSize(int size) { if (outputs == null) { outputs = new MarrowNode[size]; outputConnections = new int[size]; } else { MarrowNode[] newOutputs = new MarrowNode[size]; if (size > outputs.Length) outputs.CopyTo(newOutputs, 0); else System.Array.Copy(outputs, 0, newOutputs, 0, size); outputs = newOutputs; int[] newConnections = new int[size]; if (size > outputConnections.Length) outputConnections.CopyTo(newConnections, 0); else System.Array.Copy(outputConnections, 0, newConnections, 0, size); outputConnections = newConnections; } }
/// <summary> /// Sets the number of inputs. /// </summary> /// <param name='size'> /// Size. /// </param> public virtual void SetInputSize(int size) { if (inputs == null) { inputs = new MarrowNode[size]; } else { MarrowNode[] newInputs = new MarrowNode[size]; if (size > inputs.Length) inputs.CopyTo(newInputs, 0); else System.Array.Copy(inputs, 0, newInputs, 0, size); inputs = newInputs; } }