From 280cc60549945fa9b5b669f8b95546c21a48f4e2 Mon Sep 17 00:00:00 2001 From: Sebastien Grenier Date: Thu, 3 Feb 2022 10:32:51 -0500 Subject: [PATCH] Backport better elbow connectors. --- .../Dependencies/Graph/DependencyDatabase.cs | 2 +- .../Graph/DependencyGraphViewer.cs | 121 ++++++++++++++---- .../Dependencies/Graph/DependencyUtilities.cs | 58 +++++++++ 3 files changed, 153 insertions(+), 28 deletions(-) diff --git a/package/Dependencies/Graph/DependencyDatabase.cs b/package/Dependencies/Graph/DependencyDatabase.cs index 7870556..484ada5 100644 --- a/package/Dependencies/Graph/DependencyDatabase.cs +++ b/package/Dependencies/Graph/DependencyDatabase.cs @@ -56,7 +56,7 @@ public int instanceID get { if (!m_InstanceID.HasValue) - m_InstanceID = Utils.GetMainAssetInstanceID(path); + m_InstanceID = DependencyUtils.GetMainAssetInstanceID(path); return m_InstanceID.Value; } } diff --git a/package/Dependencies/Graph/DependencyGraphViewer.cs b/package/Dependencies/Graph/DependencyGraphViewer.cs index ed8d904..f0d6525 100644 --- a/package/Dependencies/Graph/DependencyGraphViewer.cs +++ b/package/Dependencies/Graph/DependencyGraphViewer.cs @@ -11,7 +11,9 @@ namespace UnityEditor.Search enum EdgeDisplay { Bezier, + #if USE_SEARCH_DEPENDENCY_VIEWER Elbow, + #endif } class DependencyGraphViewer : EditorWindow @@ -28,6 +30,7 @@ class DependencyGraphViewer : EditorWindow const float kBorderRadius = 2.0f; const float kBorderWidth = 0f; const float kExpandButtonHeight = 20f; + const float kElbowCornerRadius = 10f; static class Colors { @@ -134,10 +137,10 @@ void Add(ICollection objects, in Vector2 pos) } var deps = db.GetResourceDependencies(depID).Where(did => graph.FindNode(did) != null); - graph.AddNodes(n, deps.ToArray(), LinkType.DirectIn, null); + graph.AddNodes(n, deps.ToArray(), LinkType.DirectOut, null); var refs = db.GetResourceReferences(depID).Where(did => graph.FindNode(did) != null); - graph.AddNodes(n, refs.ToArray(), LinkType.DirectOut, null); + graph.AddNodes(n, refs.ToArray(), LinkType.DirectIn, null); } if (graphLayout == null) @@ -322,33 +325,35 @@ void DrawEdge(in Rect viewportRect, in Edge edge, in Vector2 from, in Vector2 to #if USE_SEARCH_DEPENDENCY_VIEWER void DrawElbowEdge(in Edge edge, in Vector2 from, in Vector2 to, in Color edgeColor, in float edgeWidth) { + var sourceRect = edge.Source.rect.OffsetBy(pan); + var targetRect = edge.Target.rect.OffsetBy(pan); var points = new List(); - var anchorOffset = new Vector2(kNodeMargin * 2, 0f); - var fromOutsidePoint = from + anchorOffset; - var toOutsidePoint = to - anchorOffset; - // Out segment - points.Add(from); - points.Add(fromOutsidePoint); - - if (fromOutsidePoint.x <= toOutsidePoint.x) + if (sourceRect.xMax <= targetRect.xMin) { - var diff = toOutsidePoint - fromOutsidePoint; - - // Add a segment to middle point - var halfPointFrom = fromOutsidePoint + new Vector2(diff.x / 2, 0); - points.Add(halfPointFrom); + var diff = to - from; + points.Add(from); if (diff.y != 0) { - var halfPointTo = toOutsidePoint - new Vector2(diff.x / 2, 0); - points.Add(halfPointTo); + // Add a segment to middle point + var halfPointFrom = from + new Vector2(diff.x / 2, 0); + var halfPointTo = to - new Vector2(diff.x / 2, 0); + + AddElbowEdgeCornerPoints(from, halfPointFrom, halfPointTo, points, kElbowCornerRadius, false, true); + AddElbowEdgeCornerPoints(halfPointFrom, halfPointTo, to, points, kElbowCornerRadius, true, false); } + + // In segment + points.Add(to); } else { - var sourceRect = edge.Source.rect.OffsetBy(pan); - var targetRect = edge.Target.rect.OffsetBy(pan); + var anchorOffset = new Vector2(kNodeMargin * 2, 0f); + var fromOutsidePoint = from + anchorOffset; + var toOutsidePoint = to - anchorOffset; + + points.Add(from); var cornerSource = new Vector2(fromOutsidePoint.x, (sourceRect.center.y + targetRect.center.y) / 2f); @@ -365,18 +370,80 @@ void DrawElbowEdge(in Edge edge, in Vector2 from, in Vector2 to, in Color edgeCo cornerSource.y = sourceRect.yMax + kNodeMargin; } } - - points.Add(cornerSource); var cornerTarget = new Vector2(toOutsidePoint.x, cornerSource.y); - points.Add(cornerTarget); - } - // In segment - points.Add(toOutsidePoint); - points.Add(to); + AddElbowEdgeCornerPoints(from, fromOutsidePoint, cornerSource, points, kElbowCornerRadius, false, true); + AddElbowEdgeCornerPoints(fromOutsidePoint, cornerSource, cornerTarget, points, kElbowCornerRadius, true, true); + AddElbowEdgeCornerPoints(cornerSource, cornerTarget, toOutsidePoint, points, kElbowCornerRadius, true, true); + AddElbowEdgeCornerPoints(cornerTarget, toOutsidePoint, to, points, kElbowCornerRadius, true, false); + + // In segment + points.Add(to); + } Handles.DrawAAPolyLine(edgeWidth, Enumerable.Repeat(edgeColor, points.Count).ToArray(), points.ToArray()); } + + void AddElbowEdgeCornerPoints(in Vector2 from, in Vector2 corner, in Vector2 to, List points, float cornerRadius, bool fromCorner, bool toCorner) + { + if (cornerRadius == 0) + { + points.Add(corner); + return; + } + + var fromDiff = from - corner; + var toDiff = to - corner; + if (fromDiff.magnitude <= cornerRadius * (fromCorner ? 2f : 1f) || toDiff.magnitude <= cornerRadius * (toCorner ? 2f : 1f)) + { + cornerRadius = Mathf.Min(fromDiff.magnitude / (fromCorner ? 2.1f : 1.1f), toDiff.magnitude / (toCorner ? 2.1f : 1.1f)); + } + + if (cornerRadius < 1f) + { + points.Add(corner); + return; + } + + var startOffset = (from - corner).normalized * cornerRadius; + var endOffset = (to - corner).normalized * cornerRadius; + var startPoint = corner + startOffset; + var endPoint = corner + endOffset; + var pivotPoint = corner + startOffset + endOffset; + + var startRelDir = (startPoint - pivotPoint).normalized; + var endRelDir = (endPoint - pivotPoint).normalized; + var startAngle = NormalizeAngle(Mathf.Atan2(-startRelDir.y, startRelDir.x)); + var endAngle = NormalizeAngle(Mathf.Atan2(-endRelDir.y, endRelDir.x)); + + var deltaAngle = Mathf.Deg2Rad * 90f; + + points.Add(startPoint); + var nbPoint = 10; + if (cornerRadius < 2f) + nbPoint = 2; + var angleIncrement = deltaAngle / (nbPoint + 1); + if (startAngle > endAngle) + angleIncrement *= -1f; + // Flip it for this special case where one angle is 0 and the other is 3*Pi/2 + if (startRelDir == Vector2.right && endRelDir == Vector2.up || startRelDir == Vector2.up && endRelDir == Vector2.right) + angleIncrement *= -1f; + for (var i = 1; i <= nbPoint; ++i) + { + var angle = startAngle + i * angleIncrement; + var newPoint = new Vector2(Mathf.Cos(angle), -Mathf.Sin(angle)) * cornerRadius + pivotPoint; + points.Add(newPoint); + } + + points.Add(endPoint); + } + + float NormalizeAngle(float angle) + { + if (angle < 0f) + return angle + Mathf.PI * 2; + return angle; + } #endif protected void DrawNode(Event evt, in Rect viewportRect, Node node) @@ -728,7 +795,7 @@ void ToggleShowStatusBar() internal static void OpenNew() { var win = CreateWindow(); - win.position = Utils.GetMainWindowCenteredPosition(new Vector2(800, 500)); + win.position = DependencyUtils.GetMainWindowCenteredPosition(new Vector2(800, 500)); win.Show(); } diff --git a/package/Dependencies/Graph/DependencyUtilities.cs b/package/Dependencies/Graph/DependencyUtilities.cs index 1b678e3..0a8bbb9 100644 --- a/package/Dependencies/Graph/DependencyUtilities.cs +++ b/package/Dependencies/Graph/DependencyUtilities.cs @@ -1,4 +1,5 @@ #if !USE_SEARCH_DEPENDENCY_VIEWER || USE_SEARCH_MODULE +using System; using UnityEngine; [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("com.unity.search.extensions.tests")] @@ -106,5 +107,62 @@ public static void End() GUI.BeginGroup(s_WorldBoundRect); } } + + static class DependencyUtils + { + public static string FormatCount(ulong count) + { + #if !USE_SEARCH_EXTENSION_API + return Utils.FormatCount(count); + #else + return SearchUtils.FormatCount(count); + #endif + } + + public static int GetMainAssetInstanceID(string path) + { + #if !USE_SEARCH_EXTENSION_API + return Utils.GetMainAssetInstanceID(path); + #else + return SearchUtils.GetMainAssetInstanceID(path); + #endif + } + + public static bool TryParse(string expression, out T result) + { + #if !USE_SEARCH_EXTENSION_API + return Utils.TryParse(expression, out result); + #else + return SearchUtils.TryParse(expression, out result); + #endif + } + + public static void PingAsset(string path) + { + #if !USE_SEARCH_EXTENSION_API + Utils.PingAsset(path); + #else + SearchUtils.PingAsset(path); + #endif + } + + public static void StartDrag(UnityEngine.Object[] objects, string[] paths, string label) + { + #if !USE_SEARCH_EXTENSION_API + Utils.StartDrag(objects, paths, label); + #else + SearchUtils.StartDrag(objects, paths, label); + #endif + } + + public static Rect GetMainWindowCenteredPosition(Vector2 size) + { + #if !USE_SEARCH_EXTENSION_API + return Utils.GetMainWindowCenteredPosition(size); + #else + return SearchUtils.GetMainWindowCenteredPosition(size); + #endif + } + } } #endif