Esempio n. 1
0
        /** Draw gizmos for the graph */
        public virtual void OnDrawGizmos(bool drawNodes)
        {
            if (!drawNodes)
            {
                return;
            }

            // This is the relatively slow default implementation
            // subclasses of the base graph class may override
            // this method to draw gizmos in a more optimized way

            PathHandler data = AstarPath.active.debugPathData;
            GraphNode   node = null;

            // Use this delegate to draw connections
            // from the #node variable to #otherNode
            GraphNodeDelegate drawConnection = otherNode => Gizmos.DrawLine((Vector3)node.position, (Vector3)otherNode.position);

            GetNodes(_node => {
                // Set the #node variable so that #drawConnection can use it
                node = _node;

                Gizmos.color = NodeColor(node, AstarPath.active.debugPathData);
                if (AstarPath.active.showSearchTree && !InSearchTree(node, AstarPath.active.debugPath))
                {
                    return(true);
                }

                PathNode nodeR = data != null ? data.GetPathNode(node) : null;
                if (AstarPath.active.showSearchTree && nodeR != null && nodeR.parent != null)
                {
                    Gizmos.DrawLine((Vector3)node.position, (Vector3)nodeR.parent.node.position);
                }
                else
                {
                    node.GetConnections(drawConnection);
                }
                return(true);
            });
        }
Esempio n. 2
0
        /** Draw gizmos for the graph */
        public virtual void OnDrawGizmos(bool drawNodes)
        {
            if (!drawNodes)
            {
                return;
            }

            PathHandler data = AstarPath.active.debugPathData;

            GraphNode node = null;

            // Use this delegate to draw connections
            // from the #node variable to #otherNode
            GraphNodeDelegate drawConnection = otherNode => Gizmos.DrawLine((Vector3)node.position, (Vector3)otherNode.position);

            GetNodes(_node => {
                // Set the #node variable so that #drawConnection can use it
                node = _node;

                Gizmos.color = NodeColor(node, AstarPath.active.debugPathData);
                if (AstarPath.active.showSearchTree && !InSearchTree(node, AstarPath.active.debugPath))
                {
                    return(true);
                }


                PathNode nodeR = data != null ? data.GetPathNode(node) : null;
                if (AstarPath.active.showSearchTree && nodeR != null && nodeR.parent != null)
                {
                    Gizmos.DrawLine((Vector3)node.position, (Vector3)nodeR.parent.node.position);
                }
                else
                {
                    node.GetConnections(drawConnection);
                }
                return(true);
            });
        }
Esempio n. 3
0
        public virtual void OnDrawGizmos(bool drawNodes)
        {
            if (!drawNodes)
            {
                return;
            }

            var data = AstarPath.active.debugPathData;

            GraphNode node = null;

            GraphNodeDelegate del = delegate(GraphNode o) {
                Gizmos.DrawLine((Vector3)node.position, (Vector3)o.position);
            };

            GetNodes(delegate(GraphNode _node) {
                node = _node;

                Gizmos.color = NodeColor(node, AstarPath.active.debugPathData);
                if (AstarPath.active.showSearchTree && !InSearchTree(node, AstarPath.active.debugPath))
                {
                    return(true);
                }


                var nodeR = data != null ? data.GetPathNode(node) : null;
                if (AstarPath.active.showSearchTree && nodeR != null && nodeR.parent != null)
                {
                    Gizmos.DrawLine((Vector3)node.position, (Vector3)nodeR.parent.node.position);
                }
                else
                {
                    node.GetConnections(del);
                }
                return(true);
            });
        }
        // Token: 0x060027A0 RID: 10144 RVA: 0x001B3164 File Offset: 0x001B1364
        public static List <GraphNode> BFS(GraphNode seed, int depth, int tagMask = -1, Func <GraphNode, bool> filter = null)
        {
            PathUtilities.BFSQueue = (PathUtilities.BFSQueue ?? new Queue <GraphNode>());
            Queue <GraphNode> que = PathUtilities.BFSQueue;

            PathUtilities.BFSMap = (PathUtilities.BFSMap ?? new Dictionary <GraphNode, int>());
            Dictionary <GraphNode, int> map = PathUtilities.BFSMap;

            que.Clear();
            map.Clear();
            List <GraphNode> result = ListPool <GraphNode> .Claim();

            int currentDist = -1;
            Action <GraphNode> action;

            if (tagMask == -1)
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && !map.ContainsKey(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }
            else
            {
                action = delegate(GraphNode node)
                {
                    if (node.Walkable && (tagMask >> (int)node.Tag & 1) != 0 && !map.ContainsKey(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }
            action(seed);
            while (que.Count > 0)
            {
                GraphNode graphNode = que.Dequeue();
                currentDist = map[graphNode];
                if (currentDist >= depth)
                {
                    break;
                }
                graphNode.GetConnections(action);
            }
            que.Clear();
            map.Clear();
            return(result);
        }
Esempio n. 5
0
        /** Returns all nodes up to a given node-distance from the seed node.
         * This function performs a BFS (breadth-first-search) or flood fill of the graph and returns all nodes within a specified node distance which can be reached from
         * the seed node. In almost all cases when \a depth is large enough 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 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 depth The maximum node-distance from the seed node.
         * \param tagMask Optional mask for tags. This is a bitmask.
         *
         * \returns A List<Node> containing all nodes reachable up to a specified node distance from the seed node.
         * For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
         *
         * \warning This method is not thread safe. Only use it from the Unity thread (i.e normal game code).
         */
        public static List <GraphNode> BFS(GraphNode seed, int depth, int tagMask = -1)
        {
                        #if ASTAR_PROFILE
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
                        #endif

            BFSQueue = BFSQueue ?? new Queue <GraphNode>();
            var que = BFSQueue;

            BFSMap = BFSMap ?? new Dictionary <GraphNode, int>();
            var map = BFSMap;

            // Even though we clear at the end of this function, it is good to
            // do it here as well in case the previous invocation of the method
            // threw an exception for some reason
            // and didn't clear the que and map
            que.Clear();
            map.Clear();

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

            int currentDist = -1;
            GraphNodeDelegate callback;
            if (tagMask == -1)
            {
                callback = node => {
                    if (node.Walkable && !map.ContainsKey(node))
                    {
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }
            else
            {
                callback = node => {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && !map.ContainsKey(node))
                    {
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }

            callback(seed);

            while (que.Count > 0)
            {
                GraphNode n = que.Dequeue();
                currentDist = map[n];

                if (currentDist >= depth)
                {
                    break;
                }

                n.GetConnections(callback);
            }

            que.Clear();
            map.Clear();

                        #if ASTAR_PROFILE
            watch.Stop();
            Debug.Log((1000 * watch.Elapsed.TotalSeconds).ToString("0.0 ms"));
                        #endif
            return(result);
        }
        /** Returns all nodes up to a given node-distance from the seed node.
         * This function performs a BFS (breadth-first-search) or flood fill of the graph and returns all nodes within a specified node distance which can be reached from
         * the seed node. In almost all cases when \a depth is large enough 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 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 depth The maximum node-distance from the seed node.
         * \param tagMask Optional mask for tags. This is a bitmask.
         *
         * \returns A List<Node> containing all nodes reachable up to a specified node distance from the seed node.
         * For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
         *
         * \warning This method is not thread safe. Only use it from the Unity thread (i.e normal game code).
         */
        public static List <GraphNode> BFS(GraphNode seed, int depth, int tagMask = -1)
        {
            BFSQueue = BFSQueue ?? new Queue <GraphNode>();
            var que = BFSQueue;

            BFSMap = BFSMap ?? new Dictionary <GraphNode, int>();
            var map = BFSMap;

            // Even though we clear at the end of this function, it is good to
            // do it here as well in case the previous invocation of the method
            // threw an exception for some reason
            // and didn't clear the que and map
            que.Clear();
            map.Clear();

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

            int currentDist = -1;
            GraphNodeDelegate callback;

            if (tagMask == -1)
            {
                callback = node => {
                    if (node.Walkable && !map.ContainsKey(node))
                    {
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }
            else
            {
                callback = node => {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && !map.ContainsKey(node))
                    {
                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }

            callback(seed);

            while (que.Count > 0)
            {
                GraphNode n = que.Dequeue();
                currentDist = map[n];

                if (currentDist >= depth)
                {
                    break;
                }

                n.GetConnections(callback);
            }

            que.Clear();
            map.Clear();

            return(result);
        }
Esempio n. 7
0
        private Vector3 Snap(ABPath path, StartEndModifier.Exactness mode, bool start, out bool forceAddPoint)
        {
            int       num       = start ? 0 : (path.path.Count - 1);
            GraphNode graphNode = path.path[num];
            Vector3   vector    = (Vector3)graphNode.position;

            forceAddPoint = false;
            switch (mode)
            {
            case StartEndModifier.Exactness.SnapToNode:
                return(vector);

            case StartEndModifier.Exactness.Original:
            case StartEndModifier.Exactness.Interpolate:
            case StartEndModifier.Exactness.NodeConnection:
            {
                Vector3 vector2;
                if (start)
                {
                    vector2 = ((this.adjustStartPoint != null) ? this.adjustStartPoint() : path.originalStartPoint);
                }
                else
                {
                    vector2 = path.originalEndPoint;
                }
                switch (mode)
                {
                case StartEndModifier.Exactness.Original:
                    return(this.GetClampedPoint(vector, vector2, graphNode));

                case StartEndModifier.Exactness.Interpolate:
                {
                    Vector3   clampedPoint = this.GetClampedPoint(vector, vector2, graphNode);
                    GraphNode graphNode2   = path.path[Mathf.Clamp(num + (start ? 1 : -1), 0, path.path.Count - 1)];
                    return(VectorMath.ClosestPointOnSegment(vector, (Vector3)graphNode2.position, clampedPoint));
                }

                case StartEndModifier.Exactness.NodeConnection:
                {
                    this.connectionBuffer = (this.connectionBuffer ?? new List <GraphNode>());
                    Action <GraphNode> action;
                    if ((action = this.connectionBufferAddDelegate) == null)
                    {
                        action = new Action <GraphNode>(this.connectionBuffer.Add);
                    }
                    this.connectionBufferAddDelegate = action;
                    GraphNode graphNode2 = path.path[Mathf.Clamp(num + (start ? 1 : -1), 0, path.path.Count - 1)];
                    graphNode.GetConnections(this.connectionBufferAddDelegate);
                    Vector3 result = vector;
                    float   num2   = float.PositiveInfinity;
                    for (int i = this.connectionBuffer.Count - 1; i >= 0; i--)
                    {
                        GraphNode graphNode3   = this.connectionBuffer[i];
                        Vector3   vector3      = VectorMath.ClosestPointOnSegment(vector, (Vector3)graphNode3.position, vector2);
                        float     sqrMagnitude = (vector3 - vector2).sqrMagnitude;
                        if (sqrMagnitude < num2)
                        {
                            result        = vector3;
                            num2          = sqrMagnitude;
                            forceAddPoint = (graphNode3 != graphNode2);
                        }
                    }
                    this.connectionBuffer.Clear();
                    return(result);
                }
                }
                throw new ArgumentException("Cannot reach this point, but the compiler is not smart enough to realize that.");
            }

            case StartEndModifier.Exactness.ClosestOnNode:
                return(this.GetClampedPoint(vector, start ? path.startPoint : path.endPoint, graphNode));

            default:
                throw new ArgumentException("Invalid mode");
            }
        }
Esempio n. 8
0
        private Vector3 Snap(ABPath path, Exactness mode, bool start, out bool forceAddPoint)
        {
            Vector3   originalEndPoint;
            GraphNode node2;
            int       num      = !start ? (path.path.Count - 1) : 0;
            GraphNode hint     = path.path[num];
            Vector3   position = (Vector3)hint.position;

            forceAddPoint = false;
            switch (mode)
            {
            case Exactness.SnapToNode:
                return(position);

            case Exactness.Original:
            case Exactness.Interpolate:
            case Exactness.NodeConnection:
                if (!start)
                {
                    originalEndPoint = path.originalEndPoint;
                    break;
                }
                originalEndPoint = (this.adjustStartPoint == null) ? path.originalStartPoint : this.adjustStartPoint();
                break;

            case Exactness.ClosestOnNode:
                return(this.GetClampedPoint(position, !start ? path.endPoint : path.startPoint, hint));

            default:
                throw new ArgumentException("Invalid mode");
            }
            switch (mode)
            {
            case Exactness.Original:
                return(this.GetClampedPoint(position, originalEndPoint, hint));

            case Exactness.Interpolate:
            {
                Vector3 point = this.GetClampedPoint(position, originalEndPoint, hint);
                node2 = path.path[Mathf.Clamp(num + (!start ? -1 : 1), 0, path.path.Count - 1)];
                return(VectorMath.ClosestPointOnSegment(position, (Vector3)node2.position, point));
            }

            case Exactness.NodeConnection:
            {
                if (this.connectionBuffer == null)
                {
                }
                this.connectionBuffer = new List <GraphNode>();
                if (this.connectionBufferAddDelegate == null)
                {
                }
                this.connectionBufferAddDelegate = new GraphNodeDelegate(this.connectionBuffer.Add);
                node2 = path.path[Mathf.Clamp(num + (!start ? -1 : 1), 0, path.path.Count - 1)];
                hint.GetConnections(this.connectionBufferAddDelegate);
                Vector3 vector4          = position;
                float   positiveInfinity = float.PositiveInfinity;
                for (int i = this.connectionBuffer.Count - 1; i >= 0; i--)
                {
                    GraphNode node3        = this.connectionBuffer[i];
                    Vector3   vector5      = VectorMath.ClosestPointOnSegment(position, (Vector3)node3.position, originalEndPoint);
                    Vector3   vector6      = vector5 - originalEndPoint;
                    float     sqrMagnitude = vector6.sqrMagnitude;
                    if (sqrMagnitude < positiveInfinity)
                    {
                        vector4          = vector5;
                        positiveInfinity = sqrMagnitude;
                        forceAddPoint    = node3 != node2;
                    }
                }
                this.connectionBuffer.Clear();
                return(vector4);
            }
            }
            throw new ArgumentException("Cannot reach this point, but the compiler is not smart enough to realize that.");
        }