/** Opens the nodes connected to this node. This is a base call and can be called by node classes overriding the Open function to open all connections in the #connections array. * \see #connections * \see Open */ public void BaseOpen(NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { if (connections == null) { return; } for (int i = 0; i < connections.Length; i++) { Node node = connections[i]; if (!path.CanTraverse(node)) { continue; } NodeRun nodeR2 = node.GetNodeRun(nodeRunData); if (nodeR2.pathID != nodeRunData.pathID) { nodeR2.parent = nodeR; nodeR2.pathID = nodeRunData.pathID; nodeR2.cost = (uint)connectionCosts[i]; node.UpdateH(targetPosition, path.heuristic, path.heuristicScale, nodeR2); node.UpdateG(nodeR2, nodeRunData); nodeRunData.open.Add(nodeR2); //Debug.DrawLine (position,node.position,Color.cyan); //Debug.Log ("Opening Node "+node.position.ToString ()+" "+g+" "+node.cost+" "+node.g+" "+node.f); } else { //If not we can test if the path from the current node to this one is a better one then the one already used uint tmpCost = (uint)connectionCosts[i]; if (nodeR.g + tmpCost + node.penalty #if !NoTagPenalty + path.GetTagPenalty(node.tags) #endif < nodeR2.g) { nodeR2.cost = tmpCost; nodeR2.parent = nodeR; //TODO!!!!! ?? node.UpdateAllG(nodeR2, nodeRunData); nodeRunData.open.Add(nodeR2); } else if (nodeR2.g + tmpCost + penalty #if !NoTagPenalty + path.GetTagPenalty(tags) #endif < nodeR.g) //Or if the path from this node ("node") to the current ("current") is better { bool contains = node.ContainsConnection(this); //Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be moved to from the other Node. /*if (node.connections != null) { * for (int y=0;y<node.connections.Length;y++) { * if (node.connections[y] == this) { * contains = true; * break; * } * } * }*/ if (!contains) { continue; } nodeR.parent = nodeR2; nodeR.cost = tmpCost; //TODO!!!!!!! ?? UpdateAllG(nodeR, nodeRunData); nodeRunData.open.Add(nodeR); } } } }
/** Updates an area in the list graph. * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated * \astarpro */ public void UpdateArea(GraphUpdateObject guo) { if (nodes == null) { return; } for (int i = 0; i < nodes.Length; i++) { if (guo.bounds.Contains((Vector3)nodes[i].position)) { guo.WillUpdateNode(nodes[i]); guo.Apply(nodes[i]); } } if (guo.updatePhysics) { //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates Bounds bounds = guo.bounds; if (thickRaycast) { //Expand the bounding box to account for the thick raycast bounds.Expand(thickRaycastRadius * 2); } //Create two temporary arrays used for holding new connections and costs List <Node> tmp_arr = Pathfinding.Util.ListPool <Node> .Claim(); List <int> tmp_arr2 = Pathfinding.Util.ListPool <int> .Claim(); for (int i = 0; i < nodes.Length; i++) { Node node = nodes[i]; Vector3 a = (Vector3)node.position; List <Node> conn = null; List <int> costs = null; for (int j = 0; j < nodes.Length; j++) { if (j == i) { continue; } Vector3 b = (Vector3)nodes[j].position; if (Polygon.LineIntersectsBounds(bounds, a, b)) { float dist; Node other = nodes[j]; bool contains = node.ContainsConnection(other); //Note, the IsValidConnection test will actually only be done once //no matter what,so there is no performance penalty there if (!contains && IsValidConnection(node, other, out dist)) { //Debug.DrawLine (a+Vector3.up*0.1F,b+Vector3.up*0.1F,Color.green); if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } int cost = Mathf.RoundToInt(dist * Int3.FloatPrecision); conn.Add(other); costs.Add(cost); } else if (contains && !IsValidConnection(node, other, out dist)) { //Debug.DrawLine (a+Vector3.up*0.5F*Random.value,b+Vector3.up*0.5F*Random.value,Color.red); if (conn == null) { tmp_arr.Clear(); tmp_arr2.Clear(); conn = tmp_arr; costs = tmp_arr2; conn.AddRange(node.connections); costs.AddRange(node.connectionCosts); } int p = conn.IndexOf(other); //Shouldn't have to check for it, but who knows what might go wrong if (p != -1) { conn.RemoveAt(p); costs.RemoveAt(p); } } } } if (conn != null) { node.connections = conn.ToArray(); node.connectionCosts = costs.ToArray(); } } Pathfinding.Util.ListPool <Node> .Release(tmp_arr); Pathfinding.Util.ListPool <int> .Release(tmp_arr2); } }