/** Calculates the grid connections for a single node */ public virtual void CalculateConnections (GridNode[] graphNodes, int x, int z, GridNode node) { //Reset all connections node.flags = node.flags & -256; //All connections are disabled if the node is not walkable if (!node.walkable) { return; } int index = node.GetIndex (); if (corners == null) { corners = new int[4]; } else { for (int i = 0;i<4;i++) { corners[i] = 0; } } for (int i=0, j = 3; i<4; j = i, i++) { int nx = x + neighbourXOffsets[i]; int nz = z + neighbourZOffsets[i]; if (nx < 0 || nz < 0 || nx >= width || nz >= depth) { continue; } GridNode other = graphNodes[index+neighbourOffsets[i]]; if (IsValidConnection (node, other)) { node.SetConnectionRaw (i,1); corners[i]++; corners[j]++; } } if (neighbours == NumNeighbours.Eight) { if (cutCorners) { for (int i=0; i<4; i++) { if (corners[i] >= 1) { int nx = x + neighbourXOffsets[i+4]; int nz = z + neighbourZOffsets[i+4]; if (nx < 0 || nz < 0 || nx >= width || nz >= depth) { continue; } GridNode other = graphNodes[index+neighbourOffsets[i+4]]; if (IsValidConnection (node,other)) { node.SetConnectionRaw (i+4,1); } } } } else { for (int i=0; i<4; i++) { //We don't need to check if it is out of bounds because if both of the other neighbours are inside the bounds this one must be too if (corners[i] == 2) { GridNode other = graphNodes[index+neighbourOffsets[i+4]]; if (IsValidConnection (node,other)) { node.SetConnectionRaw (i+4,1); } } } } } }
//END IFunnelGraph Implementation public bool CheckConnection (GridNode node, int dir) { if (neighbours == NumNeighbours.Eight) { return node.GetConnection (dir); } else { int dir1 = (dir-4-1) & 0x3; int dir2 = (dir-4+1) & 0x3; if (!node.GetConnection (dir1) || !node.GetConnection (dir2)) { return false; } else { GridNode n1 = nodes[node.GetIndex ()+neighbourOffsets[dir1]] as GridNode; GridNode n2 = nodes[node.GetIndex ()+neighbourOffsets[dir2]] as GridNode; if (!n1.walkable || !n2.walkable) { return false; } if (!n2.GetConnection (dir1) || !n1.GetConnection (dir2)) { return false; } } return true; } }
/** Calculates the grid connections for a single node. Convenience function, it's faster to use CalculateConnections(GridNode[],int,int,node) but that will only show when calculating for a large number of nodes * \todo Test this function, should work ok, but you never know */ public static void CalculateConnections (GridNode node) { GridGraph gg = AstarData.GetGraph (node) as GridGraph; if (gg != null) { int index = node.GetIndex (); int x = index % gg.width; int z = index / gg.width; gg.CalculateConnections (gg.graphNodes,x,z,node); } }
public void AddPortal (GridNode n1, GridNode n2, List<Vector3> left, List<Vector3> right) { if (n1 == n2) { return; } int i1 = n1.GetIndex (); int i2 = n2.GetIndex (); int x1 = i1 % width; int x2 = i2 % width; int z1 = i1 / width; int z2 = i2 / width; Vector3 n1p = n1.position; Vector3 n2p = n2.position; int diffx = Mathf.Abs (x1-x2); int diffz = Mathf.Abs (z1-z2); if (diffx > 1 || diffz > 1) { //If the nodes are not adjacent to each other left.Add (n1p); right.Add (n1p); left.Add (n2p); right.Add (n2p); } else if ((diffx+diffz) <= 1){ //If it is not a diagonal move Vector3 dir = n2p - n1p; dir = dir.normalized * nodeSize * 0.5F; Vector3 tangent = Vector3.Cross (dir, Vector3.up); tangent = tangent.normalized * nodeSize * 0.5F; left.Add (n1p + dir - tangent); right.Add (n1p + dir + tangent); } else { //Diagonal move Node t1 = nodes[z1 * width + x2]; Node t2 = nodes[z2 * width + x1]; Node target = null; if (t1.walkable) { target = t1; } else if (t2.walkable) { target = t2; } if (target == null) { Vector3 avg = (n1p + n2p) * 0.5F; left.Add (avg); right.Add (avg); } else { AddPortal (n1,(GridNode)target,left,right); AddPortal ((GridNode)target,n2,left,right); } } }