1
0
mirror of https://github.com/Siccity/xNode.git synced 2025-12-20 09:16:01 +08:00

Added experimental node culling for performance boost

This commit is contained in:
Thor Brigsted 2018-05-22 16:25:21 +02:00
parent 8f658d2762
commit f04629a120
3 changed files with 38 additions and 10 deletions

View File

@ -420,7 +420,7 @@ namespace XNodeEditor {
//Get node position //Get node position
Vector2 nodePos = GridToWindowPosition(node.position); Vector2 nodePos = GridToWindowPosition(node.position);
float width = 200; float width = 200;
if (nodeWidths.ContainsKey(node)) width = nodeWidths[node]; if (nodeSizes.ContainsKey(node)) width = nodeSizes[node].x;
Rect windowRect = new Rect(nodePos, new Vector2(width / zoom, 30 / zoom)); Rect windowRect = new Rect(nodePos, new Vector2(width / zoom, 30 / zoom));
return windowRect.Contains(mousePos); return windowRect.Contains(mousePos);
} }

View File

@ -8,6 +8,7 @@ namespace XNodeEditor {
public partial class NodeEditorWindow { public partial class NodeEditorWindow {
public NodeGraphEditor graphEditor; public NodeGraphEditor graphEditor;
private List<UnityEngine.Object> selectionCache; private List<UnityEngine.Object> selectionCache;
private List<XNode.Node> culledNodes;
private void OnGUI() { private void OnGUI() {
Event e = Event.current; Event e = Event.current;
@ -280,10 +281,6 @@ namespace XNodeEditor {
if (e.type == EventType.Layout) { if (e.type == EventType.Layout) {
selectionCache = new List<UnityEngine.Object>(Selection.objects); selectionCache = new List<UnityEngine.Object>(Selection.objects);
} }
if (e.type == EventType.Repaint) {
portConnectionPoints.Clear();
nodeWidths.Clear();
}
//Active node is hashed before and after node GUI to detect changes //Active node is hashed before and after node GUI to detect changes
int nodeHash = 0; int nodeHash = 0;
@ -313,6 +310,8 @@ namespace XNodeEditor {
//Save guiColor so we can revert it //Save guiColor so we can revert it
Color guiColor = GUI.color; Color guiColor = GUI.color;
if (e.type == EventType.Layout) culledNodes = new List<XNode.Node>();
for (int n = 0; n < graph.nodes.Count; n++) { for (int n = 0; n < graph.nodes.Count; n++) {
// Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable. // Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable.
if (graph.nodes[n] == null) continue; if (graph.nodes[n] == null) continue;
@ -320,6 +319,17 @@ namespace XNodeEditor {
XNode.Node node = graph.nodes[n]; XNode.Node node = graph.nodes[n];
NodeEditor nodeEditor = NodeEditor.GetEditor(node); NodeEditor nodeEditor = NodeEditor.GetEditor(node);
// Culling
if (e.type == EventType.Layout) {
// Cull unselected nodes outside view
if (!Selection.Contains(node) && ShouldBeCulled(nodeEditor)) {
culledNodes.Add(node);
continue;
}
} else if (culledNodes.Contains(node)) continue;
Debug.Log("Draw " + n);
NodeEditor.portPositions = new Dictionary<XNode.NodePort, Vector2>(); NodeEditor.portPositions = new Dictionary<XNode.NodePort, Vector2>();
//Get node position //Get node position
@ -358,18 +368,23 @@ namespace XNodeEditor {
if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node); if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
} }
GUILayout.EndVertical();
//Cache data about the node for next frame
if (e.type == EventType.Repaint) { if (e.type == EventType.Repaint) {
nodeWidths.Add(node, nodeEditor.GetWidth()); Vector2 size = GUILayoutUtility.GetLastRect().size;
if (nodeSizes.ContainsKey(node)) nodeSizes[node] = size;
else nodeSizes.Add(node, size);
foreach (var kvp in NodeEditor.portPositions) { foreach (var kvp in NodeEditor.portPositions) {
Vector2 portHandlePos = kvp.Value; Vector2 portHandlePos = kvp.Value;
portHandlePos += node.position; portHandlePos += node.position;
Rect rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16); Rect rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16);
portConnectionPoints.Add(kvp.Key, rect); if (portConnectionPoints.ContainsKey(kvp.Key)) portConnectionPoints[kvp.Key] = rect;
else portConnectionPoints.Add(kvp.Key, rect);
} }
} }
GUILayout.EndVertical();
if (selected) GUILayout.EndVertical(); if (selected) GUILayout.EndVertical();
if (e.type != EventType.Layout) { if (e.type != EventType.Layout) {
@ -414,6 +429,19 @@ namespace XNodeEditor {
} }
} }
/// <summary> Returns true if outside window area </summary>
private bool ShouldBeCulled(XNodeEditor.NodeEditor nodeEditor) {
Vector2 nodePos = GridToWindowPositionNoClipped(nodeEditor.target.position);
if (nodePos.x / _zoom > position.width) return true; // Right
else if (nodePos.y / _zoom > position.height) return true; // Bottom
else if (nodeSizes.ContainsKey(nodeEditor.target)) {
Vector2 size = nodeSizes[nodeEditor.target];
if (nodePos.x + size.x < 0) return true; // Left
else if (nodePos.y + size.y < 0) return true; // Top
}
return false;
}
private void DrawTooltip() { private void DrawTooltip() {
if (hoveredPort != null) { if (hoveredPort != null) {
Type type = hoveredPort.ValueType; Type type = hoveredPort.ValueType;

View File

@ -11,8 +11,8 @@ namespace XNodeEditor {
/// <summary> Stores node positions for all nodePorts. </summary> /// <summary> Stores node positions for all nodePorts. </summary>
public Dictionary<XNode.NodePort, Rect> portConnectionPoints { get { return _portConnectionPoints; } } public Dictionary<XNode.NodePort, Rect> portConnectionPoints { get { return _portConnectionPoints; } }
private Dictionary<XNode.NodePort, Rect> _portConnectionPoints = new Dictionary<XNode.NodePort, Rect>(); private Dictionary<XNode.NodePort, Rect> _portConnectionPoints = new Dictionary<XNode.NodePort, Rect>();
public Dictionary<XNode.Node, float> nodeWidths { get { return _nodeWidths; } } public Dictionary<XNode.Node, Vector2> nodeSizes { get { return _nodeSizes; } }
private Dictionary<XNode.Node, float> _nodeWidths = new Dictionary<XNode.Node, float>(); private Dictionary<XNode.Node, Vector2> _nodeSizes = new Dictionary<XNode.Node, Vector2>();
public XNode.NodeGraph graph; public XNode.NodeGraph graph;
public Vector2 panOffset { get { return _panOffset; } set { _panOffset = value; Repaint(); } } public Vector2 panOffset { get { return _panOffset; } set { _panOffset = value; Repaint(); } }
private Vector2 _panOffset; private Vector2 _panOffset;