1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-03-26 22:49:02 +08:00

Now uses gradient instead of color

This commit is contained in:
Igor Vasiak 2019-10-06 18:00:12 -03:00
parent 810960e4a6
commit 49c0f40539
3 changed files with 111 additions and 21 deletions

View File

@ -473,6 +473,9 @@ namespace XNodeEditor {
Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType); Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);
col.a = draggedOutputTarget != null ? 1.0f : 0.6f; col.a = draggedOutputTarget != null ? 1.0f : 0.6f;
Gradient g = new Gradient();
g.SetKeys(new GradientColorKey[] { new GradientColorKey(col, 0f) }, new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f) });
Rect fromRect; Rect fromRect;
if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return; if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return;
List<Vector2> gridPoints = new List<Vector2>(); List<Vector2> gridPoints = new List<Vector2>();
@ -483,7 +486,7 @@ namespace XNodeEditor {
if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center); if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition)); else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition));
DrawNoodle(col, gridPoints); DrawNoodle(g, gridPoints, true);
Color bgcol = Color.black; Color bgcol = Color.black;
Color frcol = col; Color frcol = col;

View File

@ -117,39 +117,80 @@ namespace XNodeEditor {
} }
/// <summary> Draw a bezier from output to input in grid coordinates </summary> /// <summary> Draw a bezier from output to input in grid coordinates </summary>
public void DrawNoodle(Color col, List<Vector2> gridPoints) { public void DrawNoodle(Gradient grad, List<Vector2> gridPoints, bool disableHover = false) {
Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray(); Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray();
Handles.color = col; Handles.color = grad.Evaluate(0f);
int length = gridPoints.Count; int length = gridPoints.Count;
switch (NodeEditorPreferences.GetSettings().noodleType) { switch (NodeEditorPreferences.GetSettings().noodleType) {
case NodeEditorPreferences.NoodleType.Curve: case NodeEditorPreferences.NoodleType.Curve:
Vector2 outputTangent = Vector2.right; Vector2 outputTangent = Vector2.right;
for (int i = 0; i < length - 1; i++) { for (int i = 0; i < length - 1; i++) {
Vector2 inputTangent = Vector2.left; Vector2 inputTangent = Vector2.left;
// Cached most variables that repeat themselves here to avoid so many indexer calls :p
if (i == 0) outputTangent = Vector2.right * Vector2.Distance(windowPoints[i], windowPoints[i + 1]) * 0.01f * zoom; Vector2 point_a = windowPoints[i];
Vector2 point_b = windowPoints[i + 1];
float dist_ab = Vector2.Distance(point_a, point_b);
if (i == 0) outputTangent = Vector2.right * dist_ab * 0.01f * zoom;
if (i < length - 2) { if (i < length - 2) {
Vector2 ab = (windowPoints[i + 1] - windowPoints[i]).normalized; Vector2 point_c = windowPoints[i + 2];
Vector2 cb = (windowPoints[i + 1] - windowPoints[i + 2]).normalized; Vector2 ab = (point_b - point_a).normalized;
Vector2 ac = (windowPoints[i + 2] - windowPoints[i]).normalized; Vector2 cb = (point_b - point_c).normalized;
Vector2 ac = (point_c - point_a).normalized;
Vector2 p = (ab + cb) * 0.5f; Vector2 p = (ab + cb) * 0.5f;
float tangentLength = (Vector2.Distance(windowPoints[i], windowPoints[i + 1]) + Vector2.Distance(windowPoints[i + 1], windowPoints[i + 2])) * 0.005f * zoom; float tangentLength = (dist_ab + Vector2.Distance(point_b, point_c)) * 0.005f * zoom;
float side = ((ac.x * (windowPoints[i + 1].y - windowPoints[i].y)) - (ac.y * (windowPoints[i + 1].x - windowPoints[i].x))); float side = ((ac.x * (point_b.y - point_a.y)) - (ac.y * (point_b.x - point_a.x)));
p = new Vector2(-p.y, p.x) * Mathf.Sign(side) * tangentLength; p = new Vector2(-p.y, p.x) * Mathf.Sign(side) * tangentLength;
inputTangent = p; inputTangent = p;
} }
else { else {
inputTangent = Vector2.left * Vector2.Distance(windowPoints[i], windowPoints[i + 1]) * 0.01f * zoom; inputTangent = Vector2.left * dist_ab * 0.01f * zoom;
} }
Handles.DrawBezier(windowPoints[i], windowPoints[i + 1], windowPoints[i] + ((outputTangent * 50) / zoom), windowPoints[i + 1] + ((inputTangent * 50) / zoom), col, null, 4); // Calculates the tangents for the bezier's curves.
Vector2 tangent_a = point_a + outputTangent * 50 / zoom;
Vector2 tangent_b = point_b + inputTangent * 50 / zoom;
// Hover effect.
int bezier_width = 4;
int division = Mathf.RoundToInt(.1f * dist_ab) + 3;
Vector3[] points = Handles.MakeBezierPoints(point_a, point_b, tangent_a, tangent_b, division);
if (!disableHover) {
for (int j = 0; j < points.Length; j++) {
Vector3 current = points[j];
bool next_has_mouse = false;
if (j + 1 < points.Length) {
Vector3 next = points[j + 1];
next_has_mouse = ContainsMouse(current, next);
}
if (next_has_mouse) {
bezier_width += 2;
break;
}
}
}
// Coloring and bezier drawing.
for (int j = 0; j < points.Length - 1; j++) {
Handles.color = grad.Evaluate((j + 1f) / (points.Length));
Handles.DrawAAPolyLine(bezier_width / zoom, points[j], points[j + 1]);
}
outputTangent = -inputTangent; outputTangent = -inputTangent;
} }
break; break;
case NodeEditorPreferences.NoodleType.Line: case NodeEditorPreferences.NoodleType.Line:
for (int i = 0; i < length - 1; i++) { for (int i = 0; i < length - 1; i++) {
Handles.DrawAAPolyLine(5, windowPoints[i], windowPoints[i + 1]); Vector2 point_a = windowPoints[i];
Vector2 point_b = windowPoints[i + 1];
// Hover effect.
int line_width = 5;
if (!disableHover && LineContainsMouse(point_a, point_b)) line_width += 2;
// Draws the line with the coloring.
Vector2 prev_point = point_a;
for (float j = 0; j < 1; j += 10f / Vector2.Distance(point_a, point_b)) {
Vector2 lerp = Vector2.Lerp(point_a, point_b, j);
Handles.color = grad.Evaluate(j);
Handles.DrawAAPolyLine(line_width / zoom, prev_point, lerp);
prev_point = lerp;
}
} }
break; break;
case NodeEditorPreferences.NoodleType.Angled: case NodeEditorPreferences.NoodleType.Angled:
@ -161,8 +202,11 @@ namespace XNodeEditor {
Vector2 end_1 = windowPoints[i + 1]; Vector2 end_1 = windowPoints[i + 1];
start_1.x = midpoint; start_1.x = midpoint;
end_1.x = midpoint; end_1.x = midpoint;
Handles.color = grad.Evaluate(0f);
Handles.DrawAAPolyLine(5, windowPoints[i], start_1); Handles.DrawAAPolyLine(5, windowPoints[i], start_1);
Handles.color = grad.Evaluate(0.5f);
Handles.DrawAAPolyLine(5, start_1, end_1); Handles.DrawAAPolyLine(5, start_1, end_1);
Handles.color = grad.Evaluate(1f);
Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]);
} else { } else {
float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f; float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f;
@ -174,10 +218,15 @@ namespace XNodeEditor {
Vector2 end_2 = end_1; Vector2 end_2 = end_1;
start_2.y = midpoint; start_2.y = midpoint;
end_2.y = midpoint; end_2.y = midpoint;
Handles.color = grad.Evaluate(0f);
Handles.DrawAAPolyLine(5, windowPoints[i], start_1); Handles.DrawAAPolyLine(5, windowPoints[i], start_1);
Handles.color = grad.Evaluate(0.25f);
Handles.DrawAAPolyLine(5, start_1, start_2); Handles.DrawAAPolyLine(5, start_1, start_2);
Handles.color = grad.Evaluate(0.5f);
Handles.DrawAAPolyLine(5, start_2, end_2); Handles.DrawAAPolyLine(5, start_2, end_2);
Handles.color = grad.Evaluate(0.75f);
Handles.DrawAAPolyLine(5, end_2, end_1); Handles.DrawAAPolyLine(5, end_2, end_1);
Handles.color = grad.Evaluate(1f);
Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(5, end_1, windowPoints[i + 1]);
} }
} }
@ -185,6 +234,34 @@ namespace XNodeEditor {
} }
} }
/// <summary>
/// Verifies if the cursor is anywhere between the given coordinates.
/// </summary>
/// <param name="point_a"></param>
/// <param name="point_b"></param>
bool ContainsMouse(Vector2 point_a, Vector2 point_b) {
Vector2 min = new Vector2(point_a.x < point_b.x ? point_a.x : point_b.x, point_a.y < point_b.y ? point_a.y : point_b.y);
Vector2 max = new Vector2(point_a.x > point_b.x ? point_a.x : point_b.x, point_a.y > point_b.y ? point_a.y : point_b.y);
bool equals_x = lastMousePosition.x >= min.x && lastMousePosition.x <= max.x;
bool equals_y = lastMousePosition.y >= min.y && lastMousePosition.y <= max.y;
return equals_x && equals_y;
}
/// <summary>
/// Splits a line in various points and verifies if any of those points contain the mouse position.
/// </summary>
/// <param name="point_a"></param>
/// <param name="point_b"></param>
bool LineContainsMouse(Vector2 point_a, Vector2 point_b) {
Vector2 prev_point = point_a;
for (float j = 0; j < 1; j += 10f / Vector2.Distance(point_a, point_b)) {
Vector2 lerp = Vector2.Lerp(point_a, point_b, j);
if (ContainsMouse(prev_point, lerp)) return true;
prev_point = lerp;
}
return false;
}
/// <summary> Draws all connections </summary> /// <summary> Draws all connections </summary>
public void DrawConnections() { public void DrawConnections() {
Vector2 mousePos = Event.current.mousePosition; Vector2 mousePos = Event.current.mousePosition;
@ -202,10 +279,11 @@ namespace XNodeEditor {
Rect fromRect; Rect fromRect;
if (!_portConnectionPoints.TryGetValue(output, out fromRect)) continue; if (!_portConnectionPoints.TryGetValue(output, out fromRect)) continue;
Color portColor = graphEditor.GetPortColor(output);
for (int k = 0; k < output.ConnectionCount; k++) { for (int k = 0; k < output.ConnectionCount; k++) {
XNode.NodePort input = output.GetConnection(k); XNode.NodePort input = output.GetConnection(k);
Color noodleColor = graphEditor.GetNoodleColor(output, input); Gradient noodleGradient = graphEditor.GetNoodleGradient(output, input);
// Error handling // Error handling
if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return. if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
@ -235,7 +313,7 @@ namespace XNodeEditor {
GUI.DrawTexture(rect, NodeEditorResources.dotOuter); GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
} }
GUI.color = noodleColor; GUI.color = portColor;
GUI.DrawTexture(rect, NodeEditorResources.dot); GUI.DrawTexture(rect, NodeEditorResources.dot);
if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef); if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef);
if (rect.Contains(mousePos)) hoveredReroute = rerouteRef; if (rect.Contains(mousePos)) hoveredReroute = rerouteRef;

View File

@ -64,11 +64,20 @@ namespace XNodeEditor {
} }
/// <summary> Returned color is used to color noodles </summary> /// <summary> Returned color is used to color noodles </summary>
public virtual Color GetNoodleColor(XNode.NodePort output, XNode.NodePort input) { public virtual Gradient GetNoodleGradient(XNode.NodePort output, XNode.NodePort input) {
Color col = GetTypeColor(output.ValueType); Color a = GetTypeColor(output.ValueType);
if (window.hoveredPort == output || window.hoveredPort == input) return Color.Lerp(col, Color.white, 0.8f); Color b = GetTypeColor(input.ValueType);
return col; if (window.hoveredPort == output || window.hoveredPort == input) {
} a = Color.Lerp(a, Color.white, 0.8f);
b = Color.Lerp(b, Color.white, 0.8f);
}
Gradient grad = new Gradient();
grad.SetKeys(
new GradientColorKey[] { new GradientColorKey(a, 0f), new GradientColorKey(b, 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
);
return grad;
}
/// <summary> Returned color is used to color ports </summary> /// <summary> Returned color is used to color ports </summary>
public virtual Color GetPortColor(XNode.NodePort port) { public virtual Color GetPortColor(XNode.NodePort port) {