public VoronoiNode GetClosestNode(Vector3 position) { VoronoiNode ClosestNode = openHeap.GetNode(0); openHeap.ResetHeap(); openHeap.Push(0); int numFurther = 0; float closestDist = 10000; int MaxNumLoops = 100000; while (!openHeap.IsEmpty() && MaxNumLoops > 0) { MaxNumLoops--; VoronoiNode least = openHeap.Pop(); float distToPos = Vector3.SqrMagnitude(least.Position - position); if (distToPos < closestDist) { ClosestNode = least; closestDist = distToPos; numFurther = 0; } else { numFurther++; if (numFurther > 10) { return(ClosestNode); } } int[] neighbors = least.GetNeighbors(); for (int i = 0; i < 3; i++) { VoronoiNode nbr = openHeap.GetNode(neighbors[i]); if (!nbr.Closed && !nbr.Open) { openHeap.SetHeuristic(nbr.Id, distToPos); openHeap.SetCost(nbr.Id); openHeap.Push(nbr.Id); } } } if (MaxNumLoops == 0) { Debug.Log("error: exited due to too many iterations in pathfinding loop"); } else { Debug.Log("error: no path found"); } return(ClosestNode); }
public VoronoiNode GetFurthestNode(Vector3 position, float distToFlee) { VoronoiNode FurthestNode = openHeap.GetNode(Random.Range(0, navMesh.nodes.Length - 1)); openHeap.ResetHeap(); openHeap.Push(0); int MaxNumLoops = 100000; while (!openHeap.IsEmpty() && MaxNumLoops > 0) { MaxNumLoops--; VoronoiNode least = openHeap.Pop(); float distToPos = Vector3.SqrMagnitude(least.Position - position); if (distToPos > distToFlee) { return(FurthestNode); } int[] neighbors = least.GetNeighbors(); for (int i = 0; i < 3; i++) { VoronoiNode nbr = openHeap.GetNode(neighbors[i]); if (!nbr.Closed && !nbr.Open) { openHeap.SetHeuristic(nbr.Id, 1 / distToPos); openHeap.SetCost(nbr.Id); openHeap.Push(nbr.Id); } } } if (MaxNumLoops == 0) { Debug.Log("error: exited due to too many iterations in pathfinding loop"); } else { Debug.Log("error: no path found"); } return(FurthestNode); }
public List <Vector3> GetSafeRandomPath(VoronoiNode start, float SafetyThreshold, out VoronoiNode safeSpot) { List <Vector3> path = new List <Vector3>(); openHeap.ResetHeap(); openHeap.Push(start.Id); int MaxNumLoops = 5; while (!openHeap.IsEmpty()) { MaxNumLoops--; VoronoiNode least = openHeap.Pop(); if (MaxNumLoops < 0) { safeSpot = least; int numStops = 1; List <VoronoiNode> nodeList = new List <VoronoiNode>(); while (least.Id != start.Id) { numStops++; path.Add(least.Position); nodeList.Add(least); least = openHeap.GetNode(least.Parent); } nodeList.Add(start); path.Add(start.Position); roughMoves = path; VoronoiNode[] nodeArr = new VoronoiNode[numStops]; int i = 0; foreach (VoronoiNode n in nodeList) { nodeArr[i] = n; i++; } path = GetFunnelPath(nodeArr); smoothMoves = path; return(path); } int[] neighbors = least.GetNeighbors(); for (int i = 0; i < 3; i++) { VoronoiNode nbr = openHeap.GetNode(neighbors[i]); if (!nbr.Open && !nbr.Closed) { float nbrSafety = 1 - (navMesh.distanceFromPlayer[nbr.Id] / navMesh.maxDistanceFromPlayer); openHeap.SetGiven(nbr.Id, least.Id, nbrSafety); openHeap.SetCost(nbr.Id); openHeap.Push(nbr.Id); } } } safeSpot = start; return(path); }
public List <Vector3> GetPath(VoronoiNode start, VoronoiNode end) { List <Vector3> path = new List <Vector3>(); if (start.Id == end.Id) { return(path); } openHeap.ResetHeap(); openHeap.Push(start.Id); int MaxNumLoops = 100000; while (!openHeap.IsEmpty() && MaxNumLoops > 0) { MaxNumLoops--; VoronoiNode least = openHeap.Pop(); if (least.Id == end.Id) { int numStops = 1; List <VoronoiNode> nodeList = new List <VoronoiNode>(); while (least.Id != start.Id) { numStops++; path.Add(least.Position); nodeList.Add(least); least = openHeap.GetNode(least.Parent); } nodeList.Add(start); path.Add(start.Position); roughMoves = path; VoronoiNode[] nodeArr = new VoronoiNode[numStops]; int i = 0; foreach (VoronoiNode n in nodeList) { nodeArr[i] = n; i++; } path = GetFunnelPath(nodeArr); smoothMoves = path; //funnel path!! return(path); } int[] neighbors = least.GetNeighbors(); for (int i = 0; i < 3; i++) { VoronoiNode nbr = openHeap.GetNode(neighbors[i]); if (nbr.Open) { float DistToNbr = Vector3.Distance(nbr.Position, least.Position); if (nbr.Given > least.Given + DistToNbr) { openHeap.SetGiven(nbr.Id, least.Id, least.Given + DistToNbr); openHeap.SetCost(nbr.Id); openHeap.UpdateNode(nbr.Id); } } else if (!nbr.Closed) { openHeap.SetHeuristic(nbr.Id, Vector3.Distance(nbr.Position, end.Position)); openHeap.SetGiven(nbr.Id, least.Id, least.Given + Vector3.Distance(nbr.Position, least.Position)); openHeap.SetCost(nbr.Id); openHeap.Push(nbr.Id); } } } if (MaxNumLoops == 0) { Debug.Log("error: exited due to too many iterations in pathfinding loop"); } else { Debug.Log("error: no path found"); } return(path); }
public List <Vector3> GetPathToSafeSpot(VoronoiNode start, float SafetyThreshold, out VoronoiNode safeSpot) { List <Vector3> path = new List <Vector3>(); safeSpot = start; if (navMesh.nodeVisability[start.Id] < SafetyThreshold) { VoronoiNode ss; path = GetSafeRandomPath(start, SafetyThreshold, out ss); safeSpot = ss; return(path); } openHeap.ResetHeap(); openHeap.Push(start.Id); int MaxNumLoops = 100000; while (!openHeap.IsEmpty() && MaxNumLoops > 0) { MaxNumLoops--; VoronoiNode least = openHeap.Pop(); if (navMesh.nodeVisability[least.Id] < SafetyThreshold) { safeSpot = least; int numStops = 1; List <VoronoiNode> nodeList = new List <VoronoiNode>(); while (least.Id != start.Id) { numStops++; path.Add(least.Position); nodeList.Add(least); least = openHeap.GetNode(least.Parent); } nodeList.Add(start); path.Add(start.Position); roughMoves = path; VoronoiNode[] nodeArr = new VoronoiNode[numStops]; int i = 0; foreach (VoronoiNode n in nodeList) { nodeArr[i] = n; i++; } path = GetFunnelPath(nodeArr); smoothMoves = path; return(path); } int[] neighbors = least.GetNeighbors(); for (int i = 0; i < 3; i++) { VoronoiNode nbr = openHeap.GetNode(neighbors[i]); if (!nbr.Open && !nbr.Closed) { float nbrVisibility = navMesh.nodeVisability[nbr.Id]; openHeap.SetGiven(nbr.Id, least.Id, least.Given + nbrVisibility * Vector3.Distance(nbr.Position, least.Position)); openHeap.SetCost(nbr.Id); openHeap.Push(nbr.Id); } } } if (MaxNumLoops == 0) { Debug.Log("error: exited due to too many iterations in pathfinding loop"); } else { Debug.Log("error: no path found"); } return(path); }