void ConnectEndPoints(List <Node> _nodes, List <Edge> _edges)
{
// Find endpoints
List <Node> endNodes = new List <Node>();
for (int i = 1; i < _nodes.Count; i++)
{
if (_nodes[i].adjacents.Count == 1)
{
endNodes.Add(_nodes[i]);
}
}
// Connect endpoints to edges or other nodes
for (int i = 0; i < endNodes.Count; i++)
{
// End node direction
Node adjacent = Node.GetNode(_nodes, endNodes[i].adjacents[0]);
Vector3 nodeDir = (endNodes[i].Position - adjacent.Position).normalized;
//Check if there is any nodes in the rough direction of the end node
float roughAngle = 30f;
List <Node> nodesInDir = new List <Node>();
for (int j = 0; j < _nodes.Count; j++)
{
if (_nodes[j] == endNodes[i])
{
continue;
}
Vector3 dirToNode = (_nodes[j].Position - endNodes[i].Position).normalized;
if (Vector3.Angle(nodeDir, dirToNode) < roughAngle && Vector3.Angle(nodeDir, dirToNode) > 30f)
{
nodesInDir.Add(_nodes[j]);
}
}
// The node with which this endpoint is connected to
Node connectTo = null;
// If there are some nodes in the rough direction, pick the one that is closest
if (nodesInDir.Count > 0)
{
float toClosest = Mathf.Infinity;
Node closest = null;
for (int j = 0; j < nodesInDir.Count; j++)
{
float toCurrent = Vector3.Distance(endNodes[i].Position, nodesInDir[j].Position);
if (toCurrent < toClosest)
{
toClosest = toCurrent;
closest = nodesInDir[j];
}
}
if (toClosest < subEdgeEndConnectionRange)
{
connectTo = closest;
}
}
// Else get intersection with closest edge in the direction of this endpoint
if (connectTo == null)
{
// Ending point for tested segment in the direction of this endpoint
Vector3 segmentEnd = endNodes[i].Position + nodeDir * 1000f;
// Get the intersection
Vector3 intersectPoint = Vector3.zero;
// Convert all used points to XZ space
Vector3 intersectPointXZ = Vector2.zero;
Vector2 endPointXZ = new Vector2(endNodes[i].Position.x, endNodes[i].Position.z);
Vector2 segmentEndXZ = new Vector2(segmentEnd.x, segmentEnd.z);
List <Edge> intersectedEdges = new List <Edge>();
List <Vector3> intersectPoints = new List <Vector3>();
// Ignore the edge that starts on this endpoint
Edge endEdge = _edges.Find(e => (e.Node1 == endNodes[i].ID || e.Node2 == endNodes[i].ID));
for (int j = 0; j < _edges.Count; j++)
{
if (_edges[j] == endEdge)
{
continue;
}
Node n1 = Node.GetNode(_nodes, _edges[j].Node1);
Node n2 = Node.GetNode(_nodes, _edges[j].Node2);
Vector2 node1XZ = new Vector2(n1.Position.x, n1.Position.z);
Vector2 node2XZ = new Vector2(n2.Position.x, n2.Position.z);
if (UtilityTools.MathHelper.AreIntersecting(out intersectPointXZ, endPointXZ, segmentEndXZ, node1XZ, node2XZ) == 1)
{
intersectPoints.Add(new Vector3(intersectPointXZ.x, n1.Position.y, intersectPointXZ.y));
intersectedEdges.Add(_edges[j]);
}
}
// Get closest intersect point
float toClosest = Mathf.Infinity;
Edge closestIntersectedEdge = null;
for (int j = 0; j < intersectPoints.Count; j++)
{
float toPoint = Vector3.Distance(endNodes[i].Position, intersectPoints[j]);
if (toPoint < toClosest)
{
toClosest = toPoint;
intersectPoint = intersectPoints[j];
closestIntersectedEdge = intersectedEdges[j];
}
}
// Split the intersected edge on the intersection
if (closestIntersectedEdge == null || intersectPoint == Vector3.zero)
{
Debug.Log("Primitive::ConnectEndPoints() - Intersect point not found.");
continue;
}
else
{
connectTo = Edge.SplitEdge(closestIntersectedEdge, intersectPoint, _nodes, _edges);
}
}
_edges.Add(new Edge(endNodes[i].ID, connectTo.ID, subEdgeWidth));
}
// Refresh adjacent nodes after all the endpoint connections
EdgeGraphUtility.CheckAdjacentNodes(ref _nodes, ref _edges);
}