예제 #1
0
        /// <summary> Draw a connection as we are dragging it </summary>
        public void DrawDraggedConnection()
        {
            if (IsDraggingPort)
            {
                Gradient     gradient  = graphEditor.GetNoodleGradient(draggedOutput, null);
                float        thickness = graphEditor.GetNoodleThickness(draggedOutput, null);
                NoodlePath   path      = graphEditor.GetNoodlePath(draggedOutput, null);
                NoodleStroke stroke    = graphEditor.GetNoodleStroke(draggedOutput, null);

                Rect fromRect;
                if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect))
                {
                    return;
                }
                List <Vector2> gridPoints = new List <Vector2>();
                gridPoints.Add(fromRect.center);
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    gridPoints.Add(draggedOutputReroutes[i]);
                }
                if (draggedOutputTarget != null)
                {
                    gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
                }
                else
                {
                    gridPoints.Add(WindowToGridPosition(Event.current.mousePosition));
                }

                DrawNoodle(gradient, path, stroke, thickness, gridPoints);

                GUIStyle portStyle = NodeEditorWindow.current.graphEditor.GetPortStyle(draggedOutput);
                Color    bgcol     = Color.black;
                Color    frcol     = gradient.colorKeys[0].color;
                bgcol.a = 0.6f;
                frcol.a = 0.6f;

                // Loop through reroute points again and draw the points
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    // Draw reroute point at position
                    Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
                    rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
                    rect          = GridToWindowRect(rect);

                    NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol, portStyle.normal.background, portStyle.active.background);
                }
            }
        }
예제 #2
0
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!_portConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color portColor = graphEditor.GetPortColor(output);
                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);

                        Gradient     noodleGradient  = graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = graphEditor.GetNoodleThickness(output, input);
                        NoodlePath   noodlePath      = graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = graphEditor.GetNoodleStroke(output, input);

                        // 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.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        Rect toRect;
                        if (!_portConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = output.GetReroutePoints(k);

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);


                        float tempT = noodleThickness;


                        if (output.ValueType.ToString() == "BehaviorNode")
                        {
                            tempT *= 1.25f;
                        }

                        DrawNoodle(noodleGradient, noodlePath, noodleStroke, tempT, gridPoints);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // Draw selected reroute points with an outline
                            if (selectedReroutes.Contains(rerouteRef))
                            {
                                GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                                GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            }

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            if (rect.Overlaps(selectionBox))
                            {
                                selection.Add(rerouteRef);
                            }
                            if (rect.Contains(mousePos))
                            {
                                hoveredReroute = rerouteRef;
                            }
                        }
                    }
                }
            }
            GUI.color = col;
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                selectedReroutes = selection;
            }
        }
예제 #3
0
        /// <summary> Draw a bezier from output to input in grid coordinates </summary>
        public void DrawNoodle(Gradient gradient, NoodlePath path, NoodleStroke stroke, float thickness, List <Vector2> gridPoints)
        {
            // convert grid points to window points
            for (int i = 0; i < gridPoints.Count; ++i)
            {
                gridPoints[i] = GridToWindowPosition(gridPoints[i]);
            }

            Handles.color = gradient.Evaluate(0f);
            int length = gridPoints.Count;

            switch (path)
            {
            case NoodlePath.Curvy:
                Vector2 outputTangent = Vector2.right;
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 inputTangent;
                    // Cached most variables that repeat themselves here to avoid so many indexer calls :p
                    Vector2 point_a = gridPoints[i];
                    Vector2 point_b = gridPoints[i + 1];
                    float   dist_ab = Vector2.Distance(point_a, point_b);
                    if (i == 0)
                    {
                        outputTangent = zoom * dist_ab * 0.01f * Vector2.right;
                    }
                    if (i < length - 2)
                    {
                        Vector2 point_c       = gridPoints[i + 2];
                        Vector2 ab            = (point_b - point_a).normalized;
                        Vector2 cb            = (point_b - point_c).normalized;
                        Vector2 ac            = (point_c - point_a).normalized;
                        Vector2 p             = (ab + cb) * 0.5f;
                        float   tangentLength = (dist_ab + Vector2.Distance(point_b, point_c)) * 0.005f * zoom;
                        float   side          = ((ac.x * (point_b.y - point_a.y)) - (ac.y * (point_b.x - point_a.x)));

                        p            = tangentLength * Mathf.Sign(side) * new Vector2(-p.y, p.x);
                        inputTangent = p;
                    }
                    else
                    {
                        inputTangent = zoom * dist_ab * 0.01f * Vector2.left;
                    }

                    // Calculates the tangents for the bezier's curves.
                    float   zoomCoef  = 50 / zoom;
                    Vector2 tangent_a = point_a + outputTangent * zoomCoef;
                    Vector2 tangent_b = point_b + inputTangent * zoomCoef;
                    // Hover effect.
                    int division = Mathf.RoundToInt(.2f * dist_ab) + 3;    //here
                    // Coloring and bezier drawing.
                    int     draw           = 0;
                    Vector2 bezierPrevious = point_a;
                    for (int j = 1; j <= division; ++j)
                    {
                        if (stroke == NoodleStroke.Dashed)
                        {
                            draw++;
                            if (draw >= 2)
                            {
                                draw = -2;
                            }
                            if (draw < 0)
                            {
                                continue;
                            }
                            if (draw == 0)
                            {
                                bezierPrevious = CalculateBezierPoint(point_a, tangent_a, tangent_b, point_b, (j - 1f) / (float)division);
                            }
                        }
                        if (i == length - 2)
                        {
                            Handles.color = gradient.Evaluate((j + 1f) / division);
                        }
                        Vector2 bezierNext = CalculateBezierPoint(point_a, tangent_a, tangent_b, point_b, j / (float)division);
                        DrawAAPolyLineNonAlloc(thickness, bezierPrevious, bezierNext);
                        bezierPrevious = bezierNext;
                    }
                    outputTangent = -inputTangent;
                }
                break;

            case NoodlePath.Straight:
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 point_a = gridPoints[i];
                    Vector2 point_b = gridPoints[i + 1];
                    // Draws the line with the coloring.
                    Vector2 prev_point = point_a;
                    // Approximately one segment per 5 pixels
                    int segments = (int)Vector2.Distance(point_a, point_b) / 5;
                    segments = Math.Max(segments, 1);

                    int draw = 0;
                    for (int j = 0; j <= segments; j++)
                    {
                        draw++;
                        float   t    = j / (float)segments;
                        Vector2 lerp = Vector2.Lerp(point_a, point_b, t);
                        if (draw > 0)
                        {
                            if (i == length - 2)
                            {
                                Handles.color = gradient.Evaluate(t);
                            }
                            DrawAAPolyLineNonAlloc(thickness, prev_point, lerp);
                        }
                        prev_point = lerp;
                        if (stroke == NoodleStroke.Dashed && draw >= 2)
                        {
                            draw = -2;
                        }
                    }
                }
                break;

            case NoodlePath.Angled:
                for (int i = 0; i < length - 1; i++)
                {
                    if (i == length - 1)
                    {
                        continue;                      // Skip last index
                    }
                    if (gridPoints[i].x <= gridPoints[i + 1].x - (50 / zoom))
                    {
                        float   midpoint = (gridPoints[i].x + gridPoints[i + 1].x) * 0.5f;
                        Vector2 start_1  = gridPoints[i];
                        Vector2 end_1    = gridPoints[i + 1];
                        start_1.x = midpoint;
                        end_1.x   = midpoint;
                        if (i == length - 2)
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1);
                            Handles.color = gradient.Evaluate(0.5f);
                            DrawAAPolyLineNonAlloc(thickness, start_1, end_1);
                            Handles.color = gradient.Evaluate(1f);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1]);
                        }
                        else
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1);
                            DrawAAPolyLineNonAlloc(thickness, start_1, end_1);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1]);
                        }
                    }
                    else
                    {
                        float   midpoint = (gridPoints[i].y + gridPoints[i + 1].y) * 0.5f;
                        Vector2 start_1  = gridPoints[i];
                        Vector2 end_1    = gridPoints[i + 1];
                        start_1.x += 25 / zoom;
                        end_1.x   -= 25 / zoom;
                        Vector2 start_2 = start_1;
                        Vector2 end_2   = end_1;
                        start_2.y = midpoint;
                        end_2.y   = midpoint;
                        if (i == length - 2)
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1);
                            Handles.color = gradient.Evaluate(0.25f);
                            DrawAAPolyLineNonAlloc(thickness, start_1, start_2);
                            Handles.color = gradient.Evaluate(0.5f);
                            DrawAAPolyLineNonAlloc(thickness, start_2, end_2);
                            Handles.color = gradient.Evaluate(0.75f);
                            DrawAAPolyLineNonAlloc(thickness, end_2, end_1);
                            Handles.color = gradient.Evaluate(1f);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1]);
                        }
                        else
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1);
                            DrawAAPolyLineNonAlloc(thickness, start_1, start_2);
                            DrawAAPolyLineNonAlloc(thickness, start_2, end_2);
                            DrawAAPolyLineNonAlloc(thickness, end_2, end_1);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1]);
                        }
                    }
                }
                break;

            case NoodlePath.ShaderLab:



                Vector2 start = gridPoints[0];
                Vector2 end   = gridPoints[length - 1];
                //Modify first and last point in array so we can loop trough them nicely.
                gridPoints[0]          = gridPoints[0] + Vector2.right * (20 / zoom);
                gridPoints[length - 1] = gridPoints[length - 1] + Vector2.left * (20 / zoom);
                //Draw first vertical lines going out from nodes
                Handles.color = gradient.Evaluate(0f);
                //DrawAAPolyLineNonAlloc(thickness, start, gridPoints[0]);
                Vector2 midPoint = ((gridPoints[0] + Vector2.right * (5 / zoom)) + (gridPoints[length - 1] + Vector2.left * (5 / zoom))) / 2;
                Vector2 startBez = CalculateBezierPoint(gridPoints[0], midPoint, gridPoints[0] + Vector2.right * (25 / zoom), (gridPoints[0] + midPoint) / 2f, .1f);
                Vector3 endBez   = CalculateBezierPoint(gridPoints[length - 1], midPoint, gridPoints[length - 1] + Vector2.left * (25 / zoom), (gridPoints[length - 1] + midPoint) / 2f, .1f);

                //draw the bendy parts
                Handles.DrawBezier((gridPoints[0] + start) / 2, startBez, new Vector2(((gridPoints[0].x + startBez.x) / 2 + gridPoints[0].x) / 2, gridPoints[0].y), gridPoints[0], gradient.Evaluate(0f), null, thickness);
                //2nd bendy
                Handles.DrawBezier((gridPoints[length - 1] + end) / 2, endBez, new Vector2(((gridPoints[length - 1].x + endBez.x) / 2 + gridPoints[length - 1].x) / 2, gridPoints[length - 1].y), gridPoints[length - 1], gradient.Evaluate(0f), null, thickness);


                //Handles.DrawBezier(end,endBez,gridPoints[length-1]+Vector2.left*(25/zoom),gridPoints[length-1]+Vector2.left*(20/zoom),gradient.Evaluate(0f),null,thickness);

                //draw the middle
                Handles.DrawBezier(startBez, endBez, startBez, endBez, gradient.Evaluate(0f), null, thickness);

                //draw the roots
                Handles.DrawBezier(start, (gridPoints[0] + start) / 2, start, (gridPoints[0] + start) / 2, gradient.Evaluate(0f), null, thickness);
                Handles.DrawBezier(end, (gridPoints[length - 1] + end) / 2, end, (gridPoints[length - 1] + end) / 2, gradient.Evaluate(0f), null, thickness);
                //Handles.color = gradient.Evaluate(1f);
                //DrawAAPolyLineNonAlloc(thickness, end, gridPoints[length - 1]);

                //Handles.DrawBezier(gridPoints[0],gridPoints[length-1],gridPoints[0]+Vector2.right*(20/zoom),gridPoints[length-1]+Vector2.left*(20/zoom),gradient.Evaluate(0f),null,thickness);

                /*
                 * for (int i = 0; i < length - 1; i++) {
                 *  Vector2 point_a = gridPoints[i];
                 *  Vector2 point_b = gridPoints[i + 1];
                 *  // Draws the line with the coloring.
                 *  Vector2 prev_point = point_a;
                 *  // Approximately one segment per 5 pixels
                 *  int segments = (int) Vector2.Distance(point_a, point_b) / 5;
                 *  segments = Math.Max(segments, 1);
                 *
                 *  int draw = 0;
                 *  for (int j = 0; j <= segments; j++) {
                 *      draw++;
                 *      float t = j / (float) segments;
                 *      Vector2 lerp = Vector2.Lerp(point_a, point_b, t);
                 *      if (draw > 0) {
                 *          if (i == length - 2) Handles.color = gradient.Evaluate(t);
                 *          DrawAAPolyLineNonAlloc(thickness, prev_point, lerp);
                 *      }
                 *      prev_point = lerp;
                 *      if (stroke == NoodleStroke.Dashed && draw >= 1) draw = -1;
                 *  }
                 * }*/


                gridPoints[0]          = start;
                gridPoints[length - 1] = end;
                break;
            }
        }
예제 #4
0
        public void DrawLinks()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                var links = XNode.NodeDataCache.GetOutputLinks(node.GetType()).Select(x => new NodeLinkPort(node, x));

                // Draw full connections and output > reroute
                foreach (var output in links)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!linkConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color           portColor   = graphEditor.GetLinkColor(output.Item2);
                    List <NodeLink> connections = output.GetConnections();

                    for (int k = 0; k < connections.Count; k++)
                    {
                        NodeLink link = connections[k];
                        if (!link)
                        {
                            Debug.LogWarning("There was a null entry in a node's connected links list. Removing.");
                            output.VerifyConnections();
                            connections.RemoveAt(k);
                            k--;
                            continue;
                        }
                        NodeLinkPort input = link.GetToPort();

                        Gradient     noodleGradient  = graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = graphEditor.GetNoodleThickness(link);
                        NoodlePath   noodlePath      = graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = graphEditor.GetNoodleStroke(output, input);

                        // 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.IsConnectedTo(output)) input.Connect(output);
                        Rect toRect;
                        if (!linkConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = link.reroutePoints;

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);
                        DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints, link);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            //RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // TODO:
                            //// Draw selected reroute points with an outline
                            //if (selectedReroutes.Contains(rerouteRef)) {
                            //    GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                            //    GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            //}

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            //if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef);
                            //if (rect.Contains(mousePos)) hoveredReroute = rerouteRef;
                        }
                    }
                }
                GUI.color = col;
                if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
                {
                    selectedReroutes = selection;
                }
            }
        }
예제 #5
0
        /// <summary> Draw a bezier from output to input in grid coordinates </summary>
        public void DrawNoodle(Gradient gradient, NoodlePath path, NoodleStroke stroke, float thickness, List <Vector2> gridPoints, UnityEngine.Object select = null)
        {
            // convert grid points to window points
            for (int i = 0; i < gridPoints.Count; ++i)
            {
                gridPoints[i] = GridToWindowPosition(gridPoints[i]);
            }

            Handles.color = gradient.Evaluate(0f);
            int length = gridPoints.Count;

            switch (path)
            {
            case NoodlePath.Curvy:
                Vector2 outputTangent = Vector2.right;
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 inputTangent;
                    // Cached most variables that repeat themselves here to avoid so many indexer calls :p
                    Vector2 point_a = gridPoints[i];
                    Vector2 point_b = gridPoints[i + 1];
                    float   dist_ab = Vector2.Distance(point_a, point_b);
                    if (i == 0)
                    {
                        outputTangent = zoom * dist_ab * 0.01f * Vector2.right;
                    }
                    if (i < length - 2)
                    {
                        Vector2 point_c       = gridPoints[i + 2];
                        Vector2 ab            = (point_b - point_a).normalized;
                        Vector2 cb            = (point_b - point_c).normalized;
                        Vector2 ac            = (point_c - point_a).normalized;
                        Vector2 p             = (ab + cb) * 0.5f;
                        float   tangentLength = (dist_ab + Vector2.Distance(point_b, point_c)) * 0.005f * zoom;
                        float   side          = ((ac.x * (point_b.y - point_a.y)) - (ac.y * (point_b.x - point_a.x)));

                        p            = tangentLength * Mathf.Sign(side) * new Vector2(-p.y, p.x);
                        inputTangent = p;
                    }
                    else
                    {
                        inputTangent = zoom * dist_ab * 0.01f * Vector2.left;
                    }

                    // Calculates the tangents for the bezier's curves.
                    float   zoomCoef  = 50 / zoom;
                    Vector2 tangent_a = point_a + outputTangent * zoomCoef;
                    Vector2 tangent_b = point_b + inputTangent * zoomCoef;
                    // Hover effect.
                    int division = Mathf.RoundToInt(.2f * dist_ab) + 3;
                    // Coloring and bezier drawing.
                    int     draw           = 0;
                    Vector2 bezierPrevious = point_a;
                    for (int j = 1; j <= division; ++j)
                    {
                        if (stroke == NoodleStroke.Dashed)
                        {
                            draw++;
                            if (draw >= 2)
                            {
                                draw = -2;
                            }
                            if (draw < 0)
                            {
                                continue;
                            }
                            if (draw == 0)
                            {
                                bezierPrevious = CalculateBezierPoint(point_a, tangent_a, tangent_b, point_b, (j - 1f) / (float)division);
                            }
                        }
                        if (i == length - 2)
                        {
                            Handles.color = gradient.Evaluate((j + 1f) / division);
                        }
                        Vector2 bezierNext = CalculateBezierPoint(point_a, tangent_a, tangent_b, point_b, j / (float)division);
                        DrawAAPolyLineNonAlloc(thickness, bezierPrevious, bezierNext, select);
                        bezierPrevious = bezierNext;
                    }
                    outputTangent = -inputTangent;
                }
                break;

            case NoodlePath.Straight:
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 point_a = gridPoints[i];
                    Vector2 point_b = gridPoints[i + 1];
                    // Draws the line with the coloring.
                    Vector2 prev_point = point_a;
                    // Approximately one segment per 5 pixels
                    int segments = (int)Vector2.Distance(point_a, point_b) / 5;

                    int draw = 0;
                    for (int j = 0; j <= segments; j++)
                    {
                        draw++;
                        float   t    = j / (float)segments;
                        Vector2 lerp = Vector2.Lerp(point_a, point_b, t);
                        if (draw > 0)
                        {
                            if (i == length - 2)
                            {
                                Handles.color = gradient.Evaluate(t);
                            }
                            DrawAAPolyLineNonAlloc(thickness, prev_point, lerp, select);
                        }
                        prev_point = lerp;
                        if (stroke == NoodleStroke.Dashed && draw >= 2)
                        {
                            draw = -2;
                        }
                    }
                }
                break;

            case NoodlePath.Angled:
                for (int i = 0; i < length - 1; i++)
                {
                    if (i == length - 1)
                    {
                        continue;                      // Skip last index
                    }
                    if (gridPoints[i].x <= gridPoints[i + 1].x - (50 / zoom))
                    {
                        float   midpoint = (gridPoints[i].x + gridPoints[i + 1].x) * 0.5f;
                        Vector2 start_1  = gridPoints[i];
                        Vector2 end_1    = gridPoints[i + 1];
                        start_1.x = midpoint;
                        end_1.x   = midpoint;
                        if (i == length - 2)
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1, select);
                            Handles.color = gradient.Evaluate(0.5f);
                            DrawAAPolyLineNonAlloc(thickness, start_1, end_1, select);
                            Handles.color = gradient.Evaluate(1f);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1], select);
                        }
                        else
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1, select);
                            DrawAAPolyLineNonAlloc(thickness, start_1, end_1, select);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1], select);
                        }
                    }
                    else
                    {
                        float   midpoint = (gridPoints[i].y + gridPoints[i + 1].y) * 0.5f;
                        Vector2 start_1  = gridPoints[i];
                        Vector2 end_1    = gridPoints[i + 1];
                        start_1.x += 25 / zoom;
                        end_1.x   -= 25 / zoom;
                        Vector2 start_2 = start_1;
                        Vector2 end_2   = end_1;
                        start_2.y = midpoint;
                        end_2.y   = midpoint;
                        if (i == length - 2)
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1, select);
                            Handles.color = gradient.Evaluate(0.25f);
                            DrawAAPolyLineNonAlloc(thickness, start_1, start_2, select);
                            Handles.color = gradient.Evaluate(0.5f);
                            DrawAAPolyLineNonAlloc(thickness, start_2, end_2, select);
                            Handles.color = gradient.Evaluate(0.75f);
                            DrawAAPolyLineNonAlloc(thickness, end_2, end_1, select);
                            Handles.color = gradient.Evaluate(1f);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1], select);
                        }
                        else
                        {
                            DrawAAPolyLineNonAlloc(thickness, gridPoints[i], start_1, select);
                            DrawAAPolyLineNonAlloc(thickness, start_1, start_2, select);
                            DrawAAPolyLineNonAlloc(thickness, start_2, end_2, select);
                            DrawAAPolyLineNonAlloc(thickness, end_2, end_1, select);
                            DrawAAPolyLineNonAlloc(thickness, end_1, gridPoints[i + 1], select);
                        }
                    }
                }
                break;
            }
        }
예제 #6
0
        /// <summary> Draw a bezier from output to input in grid coordinates </summary>
        public void DrawNoodle(Gradient gradient, NoodlePath path, NoodleStroke stroke, float thickness, List <Vector2> gridPoints)
        {
            Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray();
            Handles.color = gradient.Evaluate(0f);
            int length = gridPoints.Count;

            switch (path)
            {
            case NoodlePath.Curvy:
                Vector2 outputTangent = Vector2.right;
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 inputTangent = Vector2.left;
                    // Cached most variables that repeat themselves here to avoid so many indexer calls :p
                    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)
                    {
                        Vector2 point_c       = windowPoints[i + 2];
                        Vector2 ab            = (point_b - point_a).normalized;
                        Vector2 cb            = (point_b - point_c).normalized;
                        Vector2 ac            = (point_c - point_a).normalized;
                        Vector2 p             = (ab + cb) * 0.5f;
                        float   tangentLength = (dist_ab + Vector2.Distance(point_b, point_c)) * 0.005f * zoom;
                        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;
                        inputTangent = p;
                    }
                    else
                    {
                        inputTangent = Vector2.left * dist_ab * 0.01f * zoom;
                    }

                    // 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       division = Mathf.RoundToInt(.2f * dist_ab) + 3;
                    Vector3[] points   = Handles.MakeBezierPoints(point_a, point_b, tangent_a, tangent_b, division);
                    int       draw     = 0;
                    // Coloring and bezier drawing.
                    for (int j = 0; j < points.Length - 1; j++)
                    {
                        if (stroke == NoodleStroke.Dashed)
                        {
                            draw++;
                            if (draw >= 2)
                            {
                                draw = -2;
                            }
                            if (draw < 0)
                            {
                                continue;
                            }
                        }

                        if (i == gridPoints.Count - 2)
                        {
                            Handles.color = gradient.Evaluate((j + 1f) / points.Length);
                        }
                        Handles.DrawAAPolyLine(thickness, points[j], points[j + 1]);
                    }
                    outputTangent = -inputTangent;
                }
                break;

            case NoodlePath.Straight:
                for (int i = 0; i < length - 1; i++)
                {
                    Vector2 point_a = windowPoints[i];
                    Vector2 point_b = windowPoints[i + 1];
                    // Draws the line with the coloring.
                    Vector2 prev_point = point_a;
                    // Approximately one segment per 5 pixels
                    int segments = (int)Vector2.Distance(point_a, point_b) / 5;

                    int draw = 0;
                    for (int j = 0; j <= segments; j++)
                    {
                        draw++;
                        float   t    = j / (float)segments;
                        Vector2 lerp = Vector2.Lerp(point_a, point_b, t);
                        if (draw > 0)
                        {
                            if (i == gridPoints.Count - 2)
                            {
                                Handles.color = gradient.Evaluate(t);
                            }
                            Handles.DrawAAPolyLine(thickness, prev_point, lerp);
                        }
                        prev_point = lerp;
                        if (stroke == NoodleStroke.Dashed && draw >= 2)
                        {
                            draw = -2;
                        }
                    }
                }
                break;

            case NoodlePath.Angled:
                for (int i = 0; i < length - 1; i++)
                {
                    if (i == length - 1)
                    {
                        continue;                      // Skip last index
                    }
                    if (windowPoints[i].x <= windowPoints[i + 1].x - (50 / zoom))
                    {
                        float   midpoint = (windowPoints[i].x + windowPoints[i + 1].x) * 0.5f;
                        Vector2 start_1  = windowPoints[i];
                        Vector2 end_1    = windowPoints[i + 1];
                        start_1.x = midpoint;
                        end_1.x   = midpoint;
                        if (i == gridPoints.Count - 2)
                        {
                            Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
                            Handles.color = gradient.Evaluate(0.5f);
                            Handles.DrawAAPolyLine(thickness, start_1, end_1);
                            Handles.color = gradient.Evaluate(1f);
                            Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
                        }
                        else
                        {
                            Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
                            Handles.DrawAAPolyLine(thickness, start_1, end_1);
                            Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
                        }
                    }
                    else
                    {
                        float   midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f;
                        Vector2 start_1  = windowPoints[i];
                        Vector2 end_1    = windowPoints[i + 1];
                        start_1.x += 25 / zoom;
                        end_1.x   -= 25 / zoom;
                        Vector2 start_2 = start_1;
                        Vector2 end_2   = end_1;
                        start_2.y = midpoint;
                        end_2.y   = midpoint;
                        if (i == gridPoints.Count - 2)
                        {
                            Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
                            Handles.color = gradient.Evaluate(0.25f);
                            Handles.DrawAAPolyLine(thickness, start_1, start_2);
                            Handles.color = gradient.Evaluate(0.5f);
                            Handles.DrawAAPolyLine(thickness, start_2, end_2);
                            Handles.color = gradient.Evaluate(0.75f);
                            Handles.DrawAAPolyLine(thickness, end_2, end_1);
                            Handles.color = gradient.Evaluate(1f);
                            Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
                        }
                        else
                        {
                            Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
                            Handles.DrawAAPolyLine(thickness, start_1, start_2);
                            Handles.DrawAAPolyLine(thickness, start_2, end_2);
                            Handles.DrawAAPolyLine(thickness, end_2, end_1);
                            Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
                        }
                    }
                }
                break;
            }
        }
예제 #7
0
        private static void DrawNoodleLabesPositions(List <Vector2> gridPoints, Node node, NodePort port)
        {
            NoodlePath   path   = NodeEditorPreferences.GetSettings().noodlePath;
            NoodleStroke stroke = NodeEditorPreferences.GetSettings().noodleStroke;

            float zoom = NodeEditorWindow.current.zoom;

            // convert grid points to window points
            for (int i = 0; i < gridPoints.Count; ++i)
            {
                gridPoints[i] = NodeEditorWindow.current.GridToWindowPosition(gridPoints[i]);
            }

            int length = gridPoints.Count;

            Vector2 point_a       = Vector2.zero;
            Vector2 point_b       = Vector2.zero;
            Vector2 labelPosition = Vector2.zero;

            switch (path)
            {
            case NoodlePath.Curvy:

                if (length > 2)
                {
                    labelPosition = gridPoints[length / 2];
                }
                else
                {
                    point_a       = gridPoints[0];
                    point_b       = gridPoints[1];
                    labelPosition = (point_a + point_b) / 2;
                }

                break;

            case NoodlePath.Straight:
            case NoodlePath.Angled:
            case NoodlePath.ShaderLab:

                if (length > 2)
                {
                    if (length % 2 == 0)
                    {
                        point_a       = gridPoints[length / 2];
                        point_b       = gridPoints[(length / 2) - 1];
                        labelPosition = (point_a + point_b) / 2;
                    }
                    else
                    {
                        labelPosition = gridPoints[length / 2];
                    }
                }
                else
                {
                    point_a       = gridPoints[0];
                    point_b       = gridPoints[1];
                    labelPosition = (point_a + point_b) / 2;
                }

                break;
            }

            GUIContent content = new GUIContent(((INodeNoodleLabel)node).GetNoodleLabel(port));
            Vector2    size    = EditorStyles.helpBox.CalcSize(content);

            labelPosition.y -= size.y / 2;
            labelPosition.x -= (size.x / 2);

            TextAnchor textAnchor = EditorStyles.helpBox.alignment;
            FontStyle  fontStype  = EditorStyles.helpBox.fontStyle;

            GUI.backgroundColor = new Color(0, 0, 0, 255);
            GUI.color           = new Color(255, 255, 255, 255);

            EditorStyles.helpBox.alignment = TextAnchor.MiddleCenter;
            EditorStyles.helpBox.fontStyle = FontStyle.BoldAndItalic;


            Handles.Label(labelPosition, content, EditorStyles.helpBox);

            EditorStyles.helpBox.fontStyle = fontStype;
            EditorStyles.helpBox.alignment = textAnchor;

            GUI.color           = Color.white;
            GUI.backgroundColor = Color.white;
        }