Ejemplo n.º 1
0
		/** Returns all nodes reachable from the seed node.
		 * This function performs a BFS (breadth-first-search) or flood fill of the graph and returns all nodes which can be reached from
		 * the seed node. In almost all cases this will be identical to returning all nodes which have the same area as the seed node.
		 * In the editor areas are displayed as different colors of the nodes.
		 * The only case where it will not be so is when there is a one way path from some part of the area to the seed node
		 * but no path from the seed node to that part of the graph.
		 * 
		 * The returned list is sorted by node distance from the seed node
		 * i.e distance is measured in the number of nodes the shortest path from \a seed to that node would pass through.
		 * Note that the distance measurement does not take heuristics, penalties or tag penalties.
		 * 
		 * Depending on the number of reachable nodes, this function can take quite some time to calculate
		 * so don't use it too often or it might affect the framerate of your game.
		 * 
		 * \param seed The node to start the search from
		 * \param tagMask Optional mask for tags. This is a bitmask.
		 * 
		 * \returns A List<Node> containing all nodes reachable from the seed node.
		 * For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
		 */
		public static List<GraphNode> GetReachableNodes (GraphNode seed, int tagMask = -1) {
			var stack = StackPool<GraphNode>.Claim ();
			var list = ListPool<GraphNode>.Claim ();
			
			/** \todo Pool */
			var map = new HashSet<GraphNode>();
			
			GraphNodeDelegate callback;
			if (tagMask == -1) {
				callback = delegate (GraphNode node) {
					if (node.Walkable && map.Add (node)) {
						list.Add (node);
						stack.Push (node);
					}
				};
			} else {
				callback = delegate (GraphNode node) {
					if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && map.Add (node)) {
						list.Add (node);
						stack.Push (node);
					}
				};
			}
			
			callback (seed);
			
			while (stack.Count > 0) {
				stack.Pop ().GetConnections (callback);
			}
			
			StackPool<GraphNode>.Release (stack);
			
			return list;
		}
Ejemplo n.º 2
0
        /// <summary>
        /// Returns all nodes reachable from the seed node.
        /// This function performs a DFS (depth-first-search) or flood fill of the graph and returns all nodes which can be reached from
        /// the seed node. In almost all cases this will be identical to returning all nodes which have the same area as the seed node.
        /// In the editor areas are displayed as different colors of the nodes.
        /// The only case where it will not be so is when there is a one way path from some part of the area to the seed node
        /// but no path from the seed node to that part of the graph.
        ///
        /// The returned list is not sorted in any particular way.
        ///
        /// Depending on the number of reachable nodes, this function can take quite some time to calculate
        /// so don't use it too often or it might affect the framerate of your game.
        ///
        /// See: bitmasks (view in online documentation for working links).
        ///
        /// Returns: A List<Node> containing all nodes reachable from the seed node.
        /// For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool.
        /// </summary>
        /// <param name="seed">The node to start the search from.</param>
        /// <param name="tagMask">Optional mask for tags. This is a bitmask.</param>
        /// <param name="filter">Optional filter for which nodes to search. You can combine this with tagMask = -1 to make the filter determine everything.
        ///      Only walkable nodes are searched regardless of the filter. If the filter function returns false the node will be treated as unwalkable.</param>
        public static List <GraphNode> GetReachableNodes(GraphNode seed, int tagMask          = -1,
                                                         System.Func <GraphNode, bool> filter = null)
        {
            var dfsStack = StackPool <GraphNode> .Claim();

            var reachable = ListPool <GraphNode> .Claim();

            /// <summary>TODO: Pool</summary>
            var map = new HashSet <GraphNode>();

            System.Action <GraphNode> callback;
            // Check if we can use the fast path
            if (tagMask == -1 && filter == null)
            {
                callback = (GraphNode node) =>
                {
                    if (node.Walkable && map.Add(node))
                    {
                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                }
            }
            ;
            else
            {
                callback = (GraphNode node) =>
                {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && map.Add(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }

                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                }
            };

            callback(seed);

            while (dfsStack.Count > 0)
            {
                dfsStack.Pop().GetConnections(callback);
            }

            StackPool <GraphNode> .Release(dfsStack);

            return(reachable);
        }
Ejemplo n.º 3
0
        /** Returns all nodes reachable from the seed node.
         * This function performs a BFS (breadth-first-search) or flood fill of the graph and returns all nodes which can be reached from
         * the seed node. In almost all cases this will be identical to returning all nodes which have the same area as the seed node.
         * In the editor areas are displayed as different colors of the nodes.
         * The only case where it will not be so is when there is a one way path from some part of the area to the seed node
         * but no path from the seed node to that part of the graph.
         *
         * The returned list is sorted by node distance from the seed node
         * i.e distance is measured in the number of nodes the shortest path from \a seed to that node would pass through.
         * Note that the distance measurement does not take heuristics, penalties or tag penalties.
         *
         * Depending on the number of reachable nodes, this function can take quite some time to calculate
         * so don't use it too often or it might affect the framerate of your game.
         *
         * \param seed The node to start the search from
         * \param tagMask Optional mask for tags. This is a bitmask.
         *
         * \returns A List<Node> containing all nodes reachable from the seed node.
         * For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
         */
        public static List <GraphNode> GetReachableNodes(GraphNode seed, int tagMask = -1)
        {
#if ASTAR_PROFILE
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
#endif
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            List <GraphNode> list = ListPool <GraphNode> .Claim();

            /** \todo Pool */
            var map = new HashSet <GraphNode>();

            GraphNodeDelegate callback;
            if (tagMask == -1)
            {
                callback = delegate(GraphNode node) {
                    if (node.Walkable && map.Add(node))
                    {
                        list.Add(node);
                        stack.Push(node);
                    }
                };
            }
            else
            {
                callback = delegate(GraphNode node) {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && map.Add(node))
                    {
                        list.Add(node);
                        stack.Push(node);
                    }
                };
            }

            callback(seed);

            while (stack.Count > 0)
            {
                stack.Pop().GetConnections(callback);
            }

            StackPool <GraphNode> .Release(stack);

#if ASTAR_PROFILE
            watch.Stop();
            Debug.Log((1000 * watch.Elapsed.TotalSeconds).ToString("0.0 ms"));
#endif
            return(list);
        }
Ejemplo n.º 4
0
        // Token: 0x0600279F RID: 10143 RVA: 0x001B30BC File Offset: 0x001B12BC
        public static List <GraphNode> GetReachableNodes(GraphNode seed, int tagMask = -1, Func <GraphNode, bool> filter = null)
        {
            Stack <GraphNode> dfsStack = StackPool <GraphNode> .Claim();

            List <GraphNode> reachable = ListPool <GraphNode> .Claim();

            HashSet <GraphNode> map = new HashSet <GraphNode>();
            Action <GraphNode>  action;

            if (tagMask == -1 && filter == null)
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && map.Add(node))
                    {
                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                };
            }
            else
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && (tagMask >> (int)node.Tag & 1) != 0 && map.Add(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }
                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                };
            }
            action(seed);
            while (dfsStack.Count > 0)
            {
                dfsStack.Pop().GetConnections(action);
            }
            StackPool <GraphNode> .Release(dfsStack);

            return(reachable);
        }
Ejemplo n.º 5
0
        /** Returns all nodes reachable from the seed node.
         * This function performs a BFS (breadth-first-search) or flood fill of the graph and returns all nodes which can be reached from
         * the seed node. In almost all cases this will be identical to returning all nodes which have the same area as the seed node.
         * In the editor areas are displayed as different colors of the nodes.
         * The only case where it will not be so is when there is a one way path from some part of the area to the seed node
         * but no path from the seed node to that part of the graph.
         *
         * The returned list is sorted by node distance from the seed node
         * i.e distance is measured in the number of nodes the shortest path from \a seed to that node would pass through.
         * Note that the distance measurement does not take heuristics, penalties or tag penalties.
         *
         * Depending on the number of reachable nodes, this function can take quite some time to calculate
         * so don't use it too often or it might affect the framerate of your game.
         *
         * \param seed The node to start the search from
         * \param tagMask Optional mask for tags. This is a bitmask.
         *
         * \returns A List<Node> containing all nodes reachable from the seed node.
         * For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
         */
        public static List <GraphNode> GetReachableNodes(GraphNode seed, int tagMask = -1)
        {
            Stack <GraphNode> dfsStack = StackPool <GraphNode> .Claim();

            List <GraphNode> reachable = ListPool <GraphNode> .Claim();

            /** \todo Pool */
            var map = new HashSet <GraphNode>();

            System.Action <GraphNode> callback;
            if (tagMask == -1)
            {
                callback = (GraphNode node) => {
                    if (node.Walkable && map.Add(node))
                    {
                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                };
            }
            else
            {
                callback = (GraphNode node) => {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && map.Add(node))
                    {
                        reachable.Add(node);
                        dfsStack.Push(node);
                    }
                };
            }

            callback(seed);

            while (dfsStack.Count > 0)
            {
                dfsStack.Pop().GetConnections(callback);
            }

            StackPool <GraphNode> .Release(dfsStack);

            return(reachable);
        }
Ejemplo n.º 6
0
        public static List <GraphNode> GetReachableNodes(GraphNode seed, int tagMask = -1)
        {
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            List <GraphNode> list = ListPool <GraphNode> .Claim();

            HashSet <GraphNode> map = new HashSet <GraphNode>();
            Action <GraphNode>  action;

            if (tagMask == -1)
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && map.Add(node))
                    {
                        list.Add(node);
                        stack.Push(node);
                    }
                };
            }
            else
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && (tagMask >> (int)node.Tag & 1) != 0 && map.Add(node))
                    {
                        list.Add(node);
                        stack.Push(node);
                    }
                };
            }
            action(seed);
            while (stack.Count > 0)
            {
                stack.Pop().GetConnections(action);
            }
            StackPool <GraphNode> .Release(stack);

            return(list);
        }
        // Token: 0x060022EE RID: 8942 RVA: 0x00196858 File Offset: 0x00194A58
        public void FloodFill(GraphNode seed, uint area)
        {
            if (area > 131071U)
            {
                Debug.LogError("Too high area index - The maximum area index is " + 131071U);
                return;
            }
            if (area < 0U)
            {
                Debug.LogError("Too low area index - The minimum area index is 0");
                return;
            }
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            stack.Push(seed);
            seed.Area = area;
            while (stack.Count > 0)
            {
                stack.Pop().FloodFill(stack, area);
            }
            StackPool <GraphNode> .Release(stack);
        }
        // Token: 0x060022EF RID: 8943 RVA: 0x001968C8 File Offset: 0x00194AC8
        public void FloodFill()
        {
            NavGraph[] graphs = this.astar.graphs;
            if (graphs == null)
            {
                return;
            }
            foreach (NavGraph navGraph in graphs)
            {
                if (navGraph != null)
                {
                    navGraph.GetNodes(delegate(GraphNode node)
                    {
                        node.Area = 0U;
                    });
                }
            }
            this.lastUniqueAreaIndex = 0U;
            uint area               = 0U;
            int  forcedSmallAreas   = 0;
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            Action <GraphNode> < > 9__1;
            foreach (NavGraph navGraph2 in graphs)
            {
                if (navGraph2 != null)
                {
                    NavGraph           navGraph3 = navGraph2;
                    Action <GraphNode> action;
                    if ((action = < > 9__1) == null)
                    {
                        action = (< > 9__1 = delegate(GraphNode node)
                        {
                            if (node.Walkable && node.Area == 0U)
                            {
                                uint area = area;
                                area += 1U;
                                uint area2 = area;
                                if (area > 131071U)
                                {
                                    area = area;
                                    area -= 1U;
                                    area2 = area;
                                    int forcedSmallAreas;
                                    if (forcedSmallAreas == 0)
                                    {
                                        forcedSmallAreas = 1;
                                    }
                                    forcedSmallAreas = forcedSmallAreas;
                                    forcedSmallAreas++;
                                }
                                stack.Clear();
                                stack.Push(node);
                                int num = 1;
                                node.Area = area2;
                                while (stack.Count > 0)
                                {
                                    num++;
                                    stack.Pop().FloodFill(stack, area2);
                                }
                            }
                        });
                    }
                    navGraph3.GetNodes(action);
                }
            }
            this.lastUniqueAreaIndex = area;
            if (forcedSmallAreas > 0)
            {
                Debug.LogError(string.Concat(new object[]
                {
                    forcedSmallAreas,
                    " areas had to share IDs. This usually doesn't affect pathfinding in any significant way (you might get 'Searched whole area but could not find target' as a reason for path failure) however some path requests may take longer to calculate (specifically those that fail with the 'Searched whole area' error).The maximum number of areas is ",
                    131071U,
                    "."
                }));
            }
            StackPool <GraphNode> .Release(stack);
        }