/// <summary> /// Gets the state object for a given graph node. Creates the object if it does not yet exist. /// </summary> public ConnectionPointInfo GetNodeStateInfo(GraphNode node) { ConnectionPointInfo info; if (!_nodeStateDict.TryGetValue(node, out info)) { info = new ConnectionPointInfo(); _nodeStateDict.Add(node, info); } return(info); }
public void Draw(Rect r, ConnectionPointInfo info, int i = -1) { //figure out width and height Vector2 size = new Vector2(r.width * info.Width, r.height * info.Height); //figure out offset Vector2 offset = new Vector2(r.width, r.height); offset.Scale(new Vector2(info.UVx, info.UVy)); offset -= size * .5f; Rect rP = new Rect(offset, size); rP.position += r.position; string s = i != -1 ? $"{i}":""; GUI.Box(rP, s, info.Style); }
/// <summary> /// Gets the state object for a given graph node. Creates the object if it does not yet exist. /// </summary> public ConnectionPointInfo GetNodeStateInfo(GraphNode node) { ConnectionPointInfo info; if(!_nodeStateDict.TryGetValue(node, out info)) { info = new ConnectionPointInfo(); _nodeStateDict.Add(node, info); } return info; }
private void PaintBackConnection(Pen pen, Point srcPos, Point tgtPos, ConnectionPointInfo srcInfo, ConnectionPointInfo tgtInfo, PaintState state) { const float SlopeInit = 0.25f; const float SlopeIncr = 0.23f; // This is the maximum slope value we get before exceeding the slope threshold of 1. float slopeMax = SlopeInit + (SlopeIncr * (float)Math.Floor((1f-SlopeInit) / SlopeIncr)); // Back connection is described by the line ABCDEF. A = srcPos and F = tgtPos. int srcConIdx, tgtConIdx; int srcSide, tgtSide; // If the source and target nodes are close on the X-axis then connect to the same side on both // nodes. Otherwise connect nodes on their facing sides. if(Math.Abs(tgtPos.X - srcPos.X) <= NodeDiameterModel) { srcConIdx = srcInfo._lowerLeft++; tgtConIdx = tgtInfo._upperLeft++; srcSide = -1; tgtSide = -1; } else if(tgtPos.X > srcPos.X) { srcConIdx = srcInfo._lowerRight++; tgtConIdx = tgtInfo._upperLeft++; srcSide = 1; tgtSide = -1; } else { srcConIdx = srcInfo._lowerLeft++; tgtConIdx = tgtInfo._upperRight++; srcSide = -1; tgtSide = 1; } //--- Point B. // The line AB is a connection leg emerging from the base of a node. To visually seperate multiple legs // the first leg has a gentle gradient (almost horizontal) and each successive leg has a steeper gradient. // Once a vertical gradient has been reached each sucessive leg is made longer. // Calculate leg slope: 0=horizontal, 1=vertical. Hence this is value is not a gradient. // Slope pre-trimming back to maximum of 1.0. float slopePre = SlopeInit + (SlopeIncr * srcConIdx); // Leg length. float lenAB = state._backConnectionLegLength; float slope = slopePre; if(slope > slopeMax) { // Increase length in fractions of _backConnectionLegLength. lenAB += (slopePre-slopeMax) * state._backConnectionLegLength; slope = 1f; } // Calculate position of B as relative to A. // Note. Length is taken to be L1 length (Manhatten distance). This means that the successive B positions // describe a straight line (rather than the circle you get with L2/Euclidean distance) which in turn // ensures that the BC segments of successive connections are evenly spaced out. int xDelta = (int)(lenAB * (1f - slope)) * srcSide; int yDelta = (int)(lenAB * slope); Point b = new Point(srcPos.X + xDelta, srcPos.Y + yDelta); //--- Point C. // Line BC is a horizontal line from the end of the leg AB. int lenBC = (int)(2f * slopePre * state._backConnectionLegLength); xDelta = lenBC * srcSide; Point c = new Point(b.X + xDelta, b.Y); //--- Point E. Equivalent to point B but emerging from the target node. slopePre = SlopeInit + (SlopeIncr * tgtConIdx); // Leg length. float lenEF = state._backConnectionLegLength; slope = slopePre; if(slope > slopeMax) { // Increase length in fractions of _backConnectionLegLength. lenEF += (slopePre-slopeMax) * state._backConnectionLegLength; slope = 1f; } xDelta = (int)(lenEF * (1f - slope)) * tgtSide; yDelta = -(int)(lenEF * slope); Point e = new Point(tgtPos.X + xDelta, tgtPos.Y + yDelta); //--- Point D. Equivalent to point C but on the target end of the connection. int lenDE = (int)(2f * slopePre * state._backConnectionLegLength); xDelta = lenDE * tgtSide; Point d = new Point(e.X + xDelta, e.Y); state._g.DrawLines(pen, new Point[]{srcPos,b,c,d,e,tgtPos}); }
private void PaintBackConnection(Pen pen, Point srcPos, Point tgtPos, ConnectionPointInfo srcInfo, ConnectionPointInfo tgtInfo, PaintState state) { const float SlopeInit = 0.25f; const float SlopeIncr = 0.23f; // This is the maximum slope value we get before exceeding the slope threshold of 1. float slopeMax = SlopeInit + (SlopeIncr * (float)Math.Floor((1f - SlopeInit) / SlopeIncr)); // Back connection is described by the line ABCDEF. A = srcPos and F = tgtPos. int srcConIdx, tgtConIdx; int srcSide, tgtSide; // If the source and target nodes are close on the X-axis then connect to the same side on both // nodes. Otherwise connect nodes on their facing sides. if (Math.Abs(tgtPos.X - srcPos.X) <= NodeDiameterModel) { srcConIdx = srcInfo._lowerLeft++; tgtConIdx = tgtInfo._upperLeft++; srcSide = -1; tgtSide = -1; } else if (tgtPos.X > srcPos.X) { srcConIdx = srcInfo._lowerRight++; tgtConIdx = tgtInfo._upperLeft++; srcSide = 1; tgtSide = -1; } else { srcConIdx = srcInfo._lowerLeft++; tgtConIdx = tgtInfo._upperRight++; srcSide = -1; tgtSide = 1; } //--- Point B. // The line AB is a connection leg emerging from the base of a node. To visually separate multiple legs // the first leg has a gentle gradient (almost horizontal) and each successive leg has a steeper gradient. // Once a vertical gradient has been reached each successive leg is made longer. // Calculate leg slope: 0=horizontal, 1=vertical. Hence this is value is not a gradient. // Slope pre-trimming back to maximum of 1.0. float slopePre = SlopeInit + (SlopeIncr * srcConIdx); // Leg length. float lenAB = state._backConnectionLegLength; float slope = slopePre; if (slope > slopeMax) { // Increase length in fractions of _backConnectionLegLength. lenAB += (slopePre - slopeMax) * state._backConnectionLegLength; slope = 1f; } // Calculate position of B as relative to A. // Note. Length is taken to be L1 length (Manhattan distance). This means that the successive B positions // describe a straight line (rather than the circle you get with L2/Euclidean distance) which in turn // ensures that the BC segments of successive connections are evenly spaced out. int xDelta = (int)(lenAB * (1f - slope)) * srcSide; int yDelta = (int)(lenAB * slope); Point b = new Point(srcPos.X + xDelta, srcPos.Y + yDelta); //--- Point C. // Line BC is a horizontal line from the end of the leg AB. int lenBC = (int)(2f * slopePre * state._backConnectionLegLength); xDelta = lenBC * srcSide; Point c = new Point(b.X + xDelta, b.Y); //--- Point E. Equivalent to point B but emerging from the target node. slopePre = SlopeInit + (SlopeIncr * tgtConIdx); // Leg length. float lenEF = state._backConnectionLegLength; slope = slopePre; if (slope > slopeMax) { // Increase length in fractions of _backConnectionLegLength. lenEF += (slopePre - slopeMax) * state._backConnectionLegLength; slope = 1f; } xDelta = (int)(lenEF * (1f - slope)) * tgtSide; yDelta = -(int)(lenEF * slope); Point e = new Point(tgtPos.X + xDelta, tgtPos.Y + yDelta); //--- Point D. Equivalent to point C but on the target end of the connection. int lenDE = (int)(2f * slopePre * state._backConnectionLegLength); xDelta = lenDE * tgtSide; Point d = new Point(e.X + xDelta, e.Y); state._g.DrawLines(pen, new Point[] { srcPos, b, c, d, e, tgtPos }); }