private void Connect(Graph graph, Vector3 nearestPos, Vector3 connectToPos) { var nearest = graph.GetNearest(nearestPos, Constraint.Empty); var connectTo = graph.GetNearest(connectToPos, Constraint.Empty); nearest.node.AddConnection(connectTo.node); }
public override void ApplyAfterConnections(Graph graph) { var visited = PoolHashSet <Node> .Spawn(); foreach (var pos in this.bounds.allPositionsWithin) { var tile = this.tilemap.GetTile(pos); for (int i = 0; i < this.items.Length; ++i) { var item = this.items[i]; if (item.requiredTile == tile) { var worldPos = this.tilemap.CellToWorld(pos); var node = graph.GetNearest(this.GetPosition(worldPos)); if (visited.Contains(node) == false) { visited.Add(node); if (item.modifyWalkability == true) { node.walkable = item.walkable; } } } } } PoolHashSet <Node> .Recycle(ref visited); }
public Path Run <TMod>(Pathfinding pathfinding, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0) where TMod : IPathModifier { if (threadIndex < 0 || threadIndex > Pathfinding.THREADS_COUNT) { threadIndex = 0; } var constraintStart = constraint; constraintStart.checkWalkability = true; constraintStart.walkable = true; var startNode = graph.GetNearest(from, constraintStart); if (startNode == null) { return(new Path()); } var constraintEnd = constraintStart; constraintEnd.checkArea = true; constraintEnd.areaMask = (1 << startNode.area); var endNode = graph.GetNearest(to, constraintEnd); if (endNode == null) { return(new Path()); } var visited = PoolList <Node> .Spawn(10); System.Diagnostics.Stopwatch swPath = null; if (pathfinding.HasLogLevel(LogLevel.Path) == true) { swPath = System.Diagnostics.Stopwatch.StartNew(); } var nodesPath = this.AstarSearch(graph, visited, startNode, endNode, constraint, threadIndex); var statVisited = visited.Count; var statLength = 0; var path = new Path(); path.graph = graph; path.result = PathCompleteState.NotCalculated; if (nodesPath == null) { path.result = PathCompleteState.NotExist; } else { statLength = nodesPath.Count; path.result = PathCompleteState.Complete; path.nodes = nodesPath; } for (int i = 0; i < visited.Count; ++i) { visited[i].Reset(threadIndex); } PoolList <Node> .Recycle(ref visited); System.Diagnostics.Stopwatch swModifier = null; if (pathfinding.HasLogLevel(LogLevel.PathMods) == true) { swModifier = System.Diagnostics.Stopwatch.StartNew(); } if (path.result == PathCompleteState.Complete) { path = pathModifier.Run(path, constraint); } if (pathfinding.HasLogLevel(LogLevel.Path) == true) { Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: {2} (visited: {3})\nThread Index: {4}", path.result, swPath.ElapsedMilliseconds, statLength, statVisited, threadIndex)); } if (pathfinding.HasLogLevel(LogLevel.PathMods) == true) { Logger.Log(string.Format("Path Mods: {0}ms", swModifier.ElapsedMilliseconds)); } return(path); }
public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0, bool burstEnabled = true, bool cacheEnabled = false) where TMod : struct, IPathModifier { if (threadIndex < 0) { threadIndex = 0; } threadIndex = threadIndex % Pathfinding.THREADS_COUNT; var constraintStart = constraint; constraintStart.checkWalkability = true; constraintStart.walkable = true; var startNode = graph.GetNearest(from, constraintStart); if (startNode == null) { return(new Path()); } var constraintEnd = constraintStart; constraintEnd.checkArea = true; constraintEnd.areaMask = (1 << startNode.area); var endNode = graph.GetNearest(to, constraintEnd); if (endNode == null) { return(new Path()); } System.Diagnostics.Stopwatch swPath = null; if ((pathfindingLogLevel & LogLevel.Path) != 0) { swPath = System.Diagnostics.Stopwatch.StartNew(); } //UnityEngine.Debug.Log(endNode.worldPosition + " :: " + ((GridNode)endNode).erosion); //UnityEngine.Debug.DrawLine(endNode.worldPosition, endNode.worldPosition + Vector3.up * 10f, Color.red, 3f); var key = MathUtils.GetKey(constraint.GetKey(), endNode.index); //UnityEngine.Debug.Log("Build path cache: " + cacheEnabled + ", burst: " + burstEnabled); if (cacheEnabled == true) { if (PathfindingFlowFieldProcessor.pathCache.TryGetValue(key, out var buffer) == true) { var pathCache = new Path() { graph = graph, result = PathCompleteState.Complete, flowField = buffer, cacheEnabled = cacheEnabled, }; if ((pathfindingLogLevel & LogLevel.Path) != 0) { Logger.Log(string.Format("Path result {0}, cache in {1}ms. \nThread Index: {2}", pathCache.result, swPath.ElapsedMilliseconds, threadIndex)); } return(pathCache); } } var flowField = PoolArray <byte> .Spawn(graph.nodes.Count); int statVisited = 0; if (burstEnabled == true) // burst { this.FlowFieldBurst(ref statVisited, (GridGraph)graph, ref flowField, (GridNode)endNode, constraint, pathModifier); if (cacheEnabled == true) { if (PathfindingFlowFieldProcessor.pathCache.Count > PathfindingFlowFieldProcessor.CACHE_SIZE) { const int size = PathfindingFlowFieldProcessor.CACHE_SIZE / 10; for (int i = 0; i < size; ++i) { var idx = PathfindingFlowFieldProcessor.pathCacheQueue.Dequeue(); PathfindingFlowFieldProcessor.pathCache.Remove(idx); } PathfindingFlowFieldProcessor.pathCacheQueue.Clear(); } PathfindingFlowFieldProcessor.pathCache.Add(key, flowField); PathfindingFlowFieldProcessor.pathCacheQueue.Enqueue(key); } } else // no burst { var visited = PoolListCopyable <Node> .Spawn(10); for (int i = 0; i < graph.nodes.Count; ++i) { graph.nodes[i].Reset(threadIndex); } this.CreateIntegrationField(graph, visited, endNode, constraint, threadIndex); this.CreateFlowField(graph, ref flowField, endNode, constraint, threadIndex); statVisited = visited.Count; for (int i = 0; i < visited.Count; ++i) { visited[i].Reset(threadIndex); } PoolListCopyable <Node> .Recycle(ref visited); } var path = new Path(); path.graph = graph; path.result = PathCompleteState.Complete; path.flowField = flowField; path.cacheEnabled = cacheEnabled; if ((pathfindingLogLevel & LogLevel.Path) != 0) { Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: (visited: {2})\nThread Index: {3}", path.result, (swPath.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond).ToString("0.##"), statVisited, threadIndex)); } return(path); }
public Path Run <TMod>(LogLevel pathfindingLogLevel, Vector3 from, Vector3 to, Constraint constraint, Graph graph, TMod pathModifier, int threadIndex = 0, bool burstEnabled = true, bool cacheEnabled = false) where TMod : struct, IPathModifier { if (threadIndex < 0) { threadIndex = 0; } threadIndex = threadIndex % Pathfinding.THREADS_COUNT; var constraintStart = constraint; constraintStart.checkWalkability = true; constraintStart.walkable = true; var startNode = graph.GetNearest(from, constraintStart); if (startNode.node == null) { return(new Path()); } var constraintEnd = constraintStart; constraintEnd.checkArea = true; constraintEnd.areaMask = (1 << startNode.node.area); var endNode = graph.GetNearest(to, constraintEnd); if (endNode.node == null) { return(new Path()); } System.Diagnostics.Stopwatch swPath = null; if ((pathfindingLogLevel & LogLevel.Path) != 0) { swPath = System.Diagnostics.Stopwatch.StartNew(); } var statVisited = 0; var nodesPath = this.AstarSearch(ref statVisited, graph as GridGraph, startNode.node, endNode.node, constraint, threadIndex); var statLength = 0; var path = new Path(); path.graph = graph; path.result = PathCompleteState.NotCalculated; if (nodesPath.Length == 0) { path.result = PathCompleteState.NotExist; } else { statLength = nodesPath.Length; path.result = PathCompleteState.Complete; var list = PoolListCopyable <Node> .Spawn(nodesPath.Length); for (int i = 0; i < nodesPath.Length; ++i) { list.Add(graph.nodes[nodesPath[i].index]); } path.nodes = list; } nodesPath.Dispose(); System.Diagnostics.Stopwatch swModifier = null; if ((pathfindingLogLevel & LogLevel.PathMods) != 0) { swModifier = System.Diagnostics.Stopwatch.StartNew(); } if (path.result == PathCompleteState.Complete) { path = pathModifier.Run(path, constraint); } if ((pathfindingLogLevel & LogLevel.Path) != 0) { Logger.Log(string.Format("Path result {0}, built in {1}ms. Path length: {2} (visited: {3})\nThread Index: {4}", path.result, (swPath.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond).ToString("0.##"), statLength, statVisited, threadIndex)); } if ((pathfindingLogLevel & LogLevel.PathMods) != 0) { Logger.Log(string.Format("Path Mods: {0}ms", swModifier.ElapsedMilliseconds)); } return(path); }