Esempio n. 1
0
 public override void GetConnections(GraphNodeDelegate del)
 {
     if (this.connections == null)
     {
         return;
     }
     for (int i = 0; i < this.connections.Length; i++)
     {
         del(this.connections[i]);
     }
 }
Esempio n. 2
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. 3
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. 4
0
        public override void GetConnections(GraphNodeDelegate del)
        {
            GridGraph gg = GetGridGraph(GraphIndex);

            int[]      neighbourOffsets = gg.neighbourOffsets;
            GridNode[] nodes            = gg.nodes;

            for (int i = 0; i < 8; i++)
            {
                if (GetConnectionInternal(i))
                {
                    GridNode other = nodes[nodeInGridIndex + neighbourOffsets[i]];
                    if (other != null)
                    {
                        del(other);
                    }
                }
            }

#if !ASTAR_GRID_NO_CUSTOM_CONNECTIONS
            base.GetConnections(del);
#endif
        }
Esempio n. 5
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);
            });
        }
Esempio n. 6
0
 public override void GetConnections(GraphNodeDelegate del)
 {
     GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
     int[] neighbourOffsets = gridGraph.neighbourOffsets;
     GridNode[] nodes = gridGraph.nodes;
     for (int i = 0; i < 8; i++)
     {
         if (this.GetConnectionInternal(i))
         {
             GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
             if (gridNode != null)
             {
                 del(gridNode);
             }
         }
     }
     if (this.connections != null)
     {
         for (int j = 0; j < this.connections.Length; j++)
         {
             del(this.connections[j]);
         }
     }
 }
		public override void GetConnections (GraphNodeDelegate del)
		{
			int index = NodeInGridIndex;

			LayerGridGraph graph = GetGridGraph (GraphIndex);
			int[] neighbourOffsets = graph.neighbourOffsets;
			LevelGridNode[] nodes = graph.nodes;

			for (int i=0;i<4;i++) {
				int conn = GetConnectionValue(i);//(gridConnections >> i*4) & 0xF;
				if (conn != LevelGridNode.NoConnection) {
					LevelGridNode other = nodes[index+neighbourOffsets[i] + graph.lastScannedWidth*graph.lastScannedDepth*conn];
					if (other != null) del (other);
				}
			}
		}
Esempio n. 8
0
 /** Calls the delegate with all connections from this node */
 public abstract void GetConnections(GraphNodeDelegate del);
Esempio n. 9
0
		public override void GetConnections (GraphNodeDelegate del) {
			GridGraph gg = GetGridGraph(GraphIndex);

			int[] neighbourOffsets = gg.neighbourOffsets;
			GridNode[] nodes = gg.nodes;

			for (int i = 0; i < 8; i++) {
				if (GetConnectionInternal(i)) {
					GridNode other = nodes[nodeInGridIndex + neighbourOffsets[i]];
					if (other != null) del(other);
				}
			}

#if !ASTAR_GRID_NO_CUSTOM_CONNECTIONS
			if (connections != null) for (int i = 0; i < connections.Length; i++) del(connections[i]);
#endif
		}
Esempio n. 10
0
		public override void GetConnections (GraphNodeDelegate del) {
			throw new System.NotImplementedException();
		}
Esempio n. 11
0
        // Token: 0x06000041 RID: 65 RVA: 0x00004F38 File Offset: 0x00003338
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            Int3 @int = (Int3)position;

            if (this.nodes[this.currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }
            if (this.nodes[this.currentNode].ContainsPoint(@int))
            {
                if (this.tmpCounter >= 10)
                {
                    this.tmpCounter = 0;
                    int i     = 0;
                    int count = this.nodes.Count;
                    while (i < count)
                    {
                        if (this.nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                        i++;
                    }
                }
                else
                {
                    this.tmpCounter++;
                }
            }
            else
            {
                bool flag = false;
                int  num  = this.currentNode + 1;
                int  num2 = Math.Min(this.currentNode + 3, this.nodes.Count);
                while (num < num2 && !flag)
                {
                    if (this.nodes[num].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num].ContainsPoint(@int))
                    {
                        this.currentNode = num;
                        flag             = true;
                    }
                    num++;
                }
                int num3 = this.currentNode - 1;
                int num4 = Math.Max(this.currentNode - 3, 0);
                while (num3 > num4 && !flag)
                {
                    if (this.nodes[num3].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num3].ContainsPoint(@int))
                    {
                        this.currentNode = num3;
                        flag             = true;
                    }
                    num3--;
                }
                int     num5   = 0;
                float   num6   = float.PositiveInfinity;
                Vector3 vector = Vector3.zero;
                int     num7   = 0;
                int     count2 = this.nodes.Count;
                while (num7 < count2 && !flag)
                {
                    if (this.nodes[num7].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num7].ContainsPoint(@int))
                    {
                        this.currentNode = num7;
                        flag             = true;
                        vector           = position;
                    }
                    else
                    {
                        Vector3 vector2      = this.nodes[num7].ClosestPointOnNodeXZ(position);
                        float   sqrMagnitude = (vector2 - position).sqrMagnitude;
                        if (sqrMagnitude < num6)
                        {
                            num6   = sqrMagnitude;
                            num5   = num7;
                            vector = vector2;
                        }
                    }
                    num7++;
                }
                this.tmpCounter = 0;
                int j      = 0;
                int count3 = this.nodes.Count;
                while (j < count3)
                {
                    if (this.nodes[j].Destroyed)
                    {
                        requiresRepath = true;
                        break;
                    }
                    j++;
                }
                if (!flag)
                {
                    vector.y = position.y;
                    MeshNode          containingPoint = null;
                    int               containingIndex = this.nodes.Count - 1;
                    Int3              i3Copy          = @int;
                    GraphNodeDelegate del             = delegate(GraphNode node)
                    {
                        if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                        {
                            MeshNode meshNode2 = node as MeshNode;
                            if (meshNode2 != null && meshNode2.ContainsPoint(i3Copy))
                            {
                                containingPoint = meshNode2;
                            }
                        }
                    };
                    while (containingIndex >= 0 && containingPoint == null)
                    {
                        MeshNode meshNode = this.nodes[containingIndex];
                        meshNode.GetConnections(del);
                        containingIndex--;
                    }
                    if (containingPoint != null)
                    {
                        containingIndex++;
                        this.exactStart = position;
                        this.UpdateFunnelCorridor(containingIndex, containingPoint as TriangleMeshNode);
                        this.currentNode = 0;
                    }
                    else
                    {
                        position         = vector;
                        this.currentNode = num5;
                    }
                }
            }
            this.currentPosition = position;
            if (!this.FindNextCorners(position, this.currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }
            return(position);
        }
Esempio n. 12
0
 public override void GetConnections(GraphNodeDelegate del)
 {
     throw new System.NotImplementedException();
 }
Esempio n. 13
0
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            Int3 i3Pos = (Int3)position;

            if (nodes[currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }

            if (nodes[currentNode].ContainsPoint(i3Pos))
            {
                // Only check for destroyed nodes every 10 frames
                if (tmpCounter >= 10)
                {
                    tmpCounter = 0;
                    for (int i = 0, t = nodes.Count; i < t; i++)
                    {
                        if (nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                    }
                }
                else
                {
                    tmpCounter++;
                }
            }
            else
            {
                bool found = false;
                for (int i = currentNode + 1, t = System.Math.Min(currentNode + 3, nodes.Count); i < t && !found; i++)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }
                for (int i = currentNode - 1, t = System.Math.Max(currentNode - 3, 0); i > t && !found; i--)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }

                int     closest      = 0;
                float   closestDist  = float.PositiveInfinity;
                Vector3 closestPoint = Vector3.zero;

                for (int i = 0, t = nodes.Count; i < t && !found; i++)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode  = i;
                        found        = true;
                        closestPoint = position;
                    }
                    else
                    {
                        Vector3 close = nodes[i].ClosestPointOnNodeXZ(position);
                        float   d     = (close - position).sqrMagnitude;
                        if (d < closestDist)
                        {
                            closestDist  = d;
                            closest      = i;
                            closestPoint = close;
                        }
                    }
                }

                tmpCounter = 0;
                for (int i = 0, t = nodes.Count; i < t; i++)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        break;
                    }
                }

                if (!found)
                {
                    //Debug.DrawLine (position,closestPoint,Color.cyan);
                    //Debug.DrawRay (closestPoint,Vector3.up,Color.cyan);
                    //Debug.Break();
                    closestPoint.y = position.y;

                    MeshNode nd;
                    MeshNode containingPoint = null;
                    int      containingIndex = nodes.Count - 1;

                    // Need to make a copy here, the JIT will move this variable to the heap
                    // because it is used inside a delegate, if we didn't make a copy here
                    // we would /always/ allocate 24 bytes (sizeof(i3Pos)) on the heap every time
                    // this method was called
                    // now we only do it when this IF statement is executed
                    Int3 i3Copy           = i3Pos;
                    GraphNodeDelegate del = delegate(GraphNode node) {
                        if (!(containingIndex > 0 && node == nodes[containingIndex - 1]) && !(containingIndex < nodes.Count - 1 && node == nodes[containingIndex + 1]))
                        {
                            MeshNode mn = node as MeshNode;
                            if (mn != null && mn.ContainsPoint(i3Copy))
                            {
                                containingPoint = mn;
                            }
                        }
                    };

                    for (; containingIndex >= 0 && containingPoint == null; containingIndex--)
                    {
                        nd = nodes[containingIndex];
                        nd.GetConnections(del);
                    }

                    if (containingPoint != null)
                    {
                        // It will have been decremented once after containingPoint was null, revert that
                        containingIndex++;

                        // We have found a node containing the position, but it is outside the funnel
                        // Recalculate the funnel to include this node
                        exactStart = position;
                        UpdateFunnelCorridor(containingIndex, containingPoint as TriangleMeshNode);
                        currentNode = 0;
                        found       = true;
                    }
                    else
                    {
                        position = closestPoint;

                        found       = true;
                        currentNode = closest;
                    }
                }
            }

            currentPosition = position;

            //Debug.DrawLine ((Vector3)graph.vertices[nodes[currentNode].v1] + Vector3.up*0.1f,(Vector3)graph.vertices[nodes[currentNode].v2] + Vector3.up*0.1f,Color.red);
            //Debug.DrawLine ((Vector3)graph.vertices[nodes[currentNode].v2] + Vector3.up*0.1f,(Vector3)graph.vertices[nodes[currentNode].v3] + Vector3.up*0.1f,Color.red);
            //Debug.DrawLine ((Vector3)graph.vertices[nodes[currentNode].v3] + Vector3.up*0.1f,(Vector3)graph.vertices[nodes[currentNode].v1] + Vector3.up*0.1f,Color.red);


            if (!FindNextCorners(position, currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }

            return(position);
            //Debug.Log("Nearest " + w1.Elapsed.TotalMilliseconds*1000);
            //Debug.Log("Funnel " + w2.Elapsed.TotalMilliseconds*1000);
        }
Esempio n. 14
0
		Vector3 Snap (ABPath path, Exactness mode, bool start, out bool forceAddPoint) {
			var index = start ? 0 : path.path.Count - 1;
			var node = path.path[index];
			var nodePos = (Vector3)node.position;

			forceAddPoint = false;

			switch (mode) {
			case Exactness.ClosestOnNode:
				return GetClampedPoint(nodePos, start ? path.startPoint : path.endPoint, node);
			case Exactness.SnapToNode:
				return nodePos;
			case Exactness.Original:
			case Exactness.Interpolate:
			case Exactness.NodeConnection:
				Vector3 relevantPoint;
				if (start) {
					relevantPoint = adjustStartPoint != null ? adjustStartPoint() : path.originalStartPoint;
				} else {
					relevantPoint = path.originalEndPoint;
				}

				switch (mode) {
				case Exactness.Original:
					return GetClampedPoint(nodePos, relevantPoint, node);
				case Exactness.Interpolate:
					var clamped = GetClampedPoint(nodePos, relevantPoint, node);
					// Adjacent node to either the start node or the end node in the path
					var adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count-1)];
					return VectorMath.ClosestPointOnSegment(nodePos, (Vector3)adjacentNode.position, clamped);
				case Exactness.NodeConnection:
					// This code uses some tricks to avoid allocations
					// even though it uses delegates heavily
					// The connectionBufferAddDelegate delegate simply adds whatever node
					// it is called with to the connectionBuffer
					connectionBuffer = connectionBuffer ?? new List<GraphNode>();
					connectionBufferAddDelegate = connectionBufferAddDelegate ?? (GraphNodeDelegate)connectionBuffer.Add;

					// Adjacent node to either the start node or the end node in the path
					adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count-1)];

					// Add all neighbours of #node to the connectionBuffer
					node.GetConnections(connectionBufferAddDelegate);
					var bestPos = nodePos;
					var bestDist = float.PositiveInfinity;

					// Loop through all neighbours
					// Do it in reverse order because the length of the connectionBuffer
					// will change during iteration
					for (int i = connectionBuffer.Count - 1; i >= 0; i--) {
						var neighbour = connectionBuffer[i];

						// Find the closest point on the connection between the nodes
						// and check if the distance to that point is lower than the previous best
						var closest = VectorMath.ClosestPointOnSegment(nodePos, (Vector3)neighbour.position, relevantPoint);

						var dist = (closest - relevantPoint).sqrMagnitude;
						if (dist < bestDist) {
							bestPos = closest;
							bestDist = dist;

							// If this node is not the adjacent node
							// then the path should go through the start node as well
							forceAddPoint = neighbour != adjacentNode;
						}
					}

					connectionBuffer.Clear();
					return bestPos;
				default:
					throw new System.ArgumentException("Cannot reach this point, but the compiler is not smart enough to realize that.");
				}
			default:
				throw new System.ArgumentException("Invalid mode");
			}
		}
Esempio n. 15
0
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            Int3 p = (Int3)position;

            if (this.nodes[this.currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }
            if (this.nodes[this.currentNode].ContainsPoint(p))
            {
                if (this.checkForDestroyedNodesCounter >= 10)
                {
                    this.checkForDestroyedNodesCounter = 0;
                    int i     = 0;
                    int count = this.nodes.Count;
                    while (i < count)
                    {
                        if (this.nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                        i++;
                    }
                }
                else
                {
                    this.checkForDestroyedNodesCounter++;
                }
            }
            else
            {
                bool flag = false;
                int  num  = this.currentNode + 1;
                int  num2 = Math.Min(this.currentNode + 3, this.nodes.Count);
                while (num < num2 && !flag)
                {
                    if (this.nodes[num].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num].ContainsPoint(p))
                    {
                        this.currentNode = num;
                        flag             = true;
                    }
                    num++;
                }
                int num3 = this.currentNode - 1;
                int num4 = Math.Max(this.currentNode - 3, 0);
                while (num3 > num4 && !flag)
                {
                    if (this.nodes[num3].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num3].ContainsPoint(p))
                    {
                        this.currentNode = num3;
                        flag             = true;
                    }
                    num3--;
                }
                if (!flag)
                {
                    int              index = 0;
                    int              closestIsNeighbourOf = 0;
                    float            closestDist          = float.PositiveInfinity;
                    bool             closestIsInPath      = false;
                    TriangleMeshNode closestNode          = null;
                    int              containingIndex      = this.nodes.Count - 1;
                    this.checkForDestroyedNodesCounter = 0;
                    int j      = 0;
                    int count2 = this.nodes.Count;
                    while (j < count2)
                    {
                        if (this.nodes[j].Destroyed)
                        {
                            requiresRepath = true;
                            lastCorner     = false;
                            buffer.Add(position);
                            return(position);
                        }
                        Vector3 a            = this.nodes[j].ClosestPointOnNode(position);
                        float   sqrMagnitude = (a - position).sqrMagnitude;
                        if (sqrMagnitude < closestDist)
                        {
                            closestDist     = sqrMagnitude;
                            index           = j;
                            closestNode     = this.nodes[j];
                            closestIsInPath = true;
                        }
                        j++;
                    }
                    Vector3           posCopy = position;
                    GraphNodeDelegate del     = delegate(GraphNode node)
                    {
                        if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                        {
                            TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                            if (triangleMeshNode != null)
                            {
                                Vector3 a2            = triangleMeshNode.ClosestPointOnNode(posCopy);
                                float   sqrMagnitude2 = (a2 - posCopy).sqrMagnitude;
                                if (sqrMagnitude2 < closestDist)
                                {
                                    closestDist          = sqrMagnitude2;
                                    closestIsNeighbourOf = containingIndex;
                                    closestNode          = triangleMeshNode;
                                    closestIsInPath      = false;
                                }
                            }
                        }
                    };
                    while (containingIndex >= 0)
                    {
                        this.nodes[containingIndex].GetConnections(del);
                        containingIndex--;
                    }
                    if (closestIsInPath)
                    {
                        this.currentNode = index;
                        position         = this.nodes[index].ClosestPointOnNodeXZ(position);
                    }
                    else
                    {
                        position        = closestNode.ClosestPointOnNodeXZ(position);
                        this.exactStart = position;
                        this.UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);
                        this.currentNode = 0;
                    }
                }
            }
            this.currentPosition = position;
            if (!this.FindNextCorners(position, this.currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }
            return(position);
        }
Esempio n. 16
0
 public override void GetConnections(GraphNodeDelegate del)
 {
     int nodeInGridIndex = base.NodeInGridIndex;
     LayerGridGraph gridGraph = LevelGridNode.GetGridGraph(base.GraphIndex);
     int[] neighbourOffsets = gridGraph.neighbourOffsets;
     LevelGridNode[] nodes = gridGraph.nodes;
     for (int i = 0; i < 4; i++)
     {
         int connectionValue = this.GetConnectionValue(i);
         if (connectionValue != 255)
         {
             LevelGridNode levelGridNode = nodes[nodeInGridIndex + neighbourOffsets[i] + gridGraph.lastScannedWidth * gridGraph.lastScannedDepth * connectionValue];
             if (levelGridNode != null)
             {
                 del(levelGridNode);
             }
         }
     }
 }
Esempio n. 17
0
        private Vector3 Snap(ABPath path, StartEndModifier.Exactness mode, bool start, out bool forceAddPoint)
        {
            int       num       = (!start) ? (path.path.Count - 1) : 0;
            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) ? path.originalStartPoint : this.adjustStartPoint());
                }
                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>());
                    GraphNodeDelegate arg_162_1;
                    if ((arg_162_1 = this.connectionBufferAddDelegate) == null)
                    {
                        arg_162_1 = new GraphNodeDelegate(this.connectionBuffer.Add);
                    }
                    this.connectionBufferAddDelegate = arg_162_1;
                    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.endPoint : path.startPoint, graphNode));

            default:
                throw new ArgumentException("Invalid mode");
            }
        }
Esempio n. 18
0
        private bool ClampToNavmeshInternal(ref Vector3 position)
        {
            if (this.nodes[this.currentNode].Destroyed)
            {
                return(true);
            }
            Int3 p = (Int3)position;

            if (this.nodes[this.currentNode].ContainsPoint(p))
            {
                return(false);
            }
            int i   = this.currentNode + 1;
            int num = Math.Min(this.currentNode + 3, this.nodes.Count);

            while (i < num)
            {
                if (this.nodes[i].Destroyed)
                {
                    return(true);
                }
                if (this.nodes[i].ContainsPoint(p))
                {
                    this.currentNode = i;
                    return(false);
                }
                i++;
            }
            int j    = this.currentNode - 1;
            int num2 = Math.Max(this.currentNode - 3, 0);

            while (j > num2)
            {
                if (this.nodes[j].Destroyed)
                {
                    return(true);
                }
                if (this.nodes[j].ContainsPoint(p))
                {
                    this.currentNode = j;
                    return(false);
                }
                j--;
            }
            int              index = 0;
            int              closestIsNeighbourOf = 0;
            float            closestDist          = float.PositiveInfinity;
            bool             closestIsInPath      = false;
            TriangleMeshNode closestNode          = null;
            int              containingIndex      = this.nodes.Count - 1;

            this.checkForDestroyedNodesCounter = 0;
            int k     = 0;
            int count = this.nodes.Count;

            while (k < count)
            {
                if (this.nodes[k].Destroyed)
                {
                    return(true);
                }
                Vector3 a            = this.nodes[k].ClosestPointOnNode(position);
                float   sqrMagnitude = (a - position).sqrMagnitude;
                if (sqrMagnitude < closestDist)
                {
                    closestDist     = sqrMagnitude;
                    index           = k;
                    closestNode     = this.nodes[k];
                    closestIsInPath = true;
                }
                k++;
            }
            Vector3           posCopy = position;
            GraphNodeDelegate del     = delegate(GraphNode node)
            {
                if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                {
                    TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        Vector3 a2            = triangleMeshNode.ClosestPointOnNode(posCopy);
                        float   sqrMagnitude2 = (a2 - posCopy).sqrMagnitude;
                        if (sqrMagnitude2 < closestDist)
                        {
                            closestDist          = sqrMagnitude2;
                            closestIsNeighbourOf = containingIndex;
                            closestNode          = triangleMeshNode;
                            closestIsInPath      = false;
                        }
                    }
                }
            };

            while (containingIndex >= 0)
            {
                this.nodes[containingIndex].GetConnections(del);
                containingIndex--;
            }
            if (closestIsInPath)
            {
                this.currentNode = index;
                position         = this.nodes[index].ClosestPointOnNodeXZ(position);
            }
            else
            {
                position        = closestNode.ClosestPointOnNodeXZ(position);
                this.exactStart = position;
                this.UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);
                this.currentNode = 0;
            }
            return(false);
        }
Esempio n. 19
0
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            var i3Pos = (Int3)position;

            if (nodes[currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }

            // Check if we are in the same node as we were in during the last frame
            if (nodes[currentNode].ContainsPoint(i3Pos))
            {
                // Only check for destroyed nodes every 10 frames
                if (checkForDestroyedNodesCounter >= 10)
                {
                    checkForDestroyedNodesCounter = 0;

                    // Loop through all nodes and check if they are destroyed
                    // If so, we really need a recalculation of our path quickly
                    // since there might be an obstacle blocking our path after
                    // a graph update or something similar
                    for (int i = 0, t = nodes.Count; i < t; i++)
                    {
                        if (nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                    }
                }
                else
                {
                    checkForDestroyedNodesCounter++;
                }
            }
            else
            {
                // This part of the code is relatively seldom called
                // Most of the time we are still on the same node as during the previous frame

                // Otherwise check the 2 nodes ahead and 2 nodes back
                // If they contain the node in XZ space, then we probably moved into those nodes
                bool found = false;

                // 2 nodes ahead
                for (int i = currentNode + 1, t = System.Math.Min(currentNode + 3, nodes.Count); i < t && !found; i++)
                {
                    // If the node is destroyed, make sure we recalculate a new path quickly
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    // We found a node which contains our current position in XZ space
                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }

                // 2 nodes behind
                for (int i = currentNode - 1, t = System.Math.Max(currentNode - 3, 0); i > t && !found; i--)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }

                if (!found)
                {
                    int              closestNodeInPath    = 0;
                    int              closestIsNeighbourOf = 0;
                    float            closestDist          = float.PositiveInfinity;
                    bool             closestIsInPath      = false;
                    TriangleMeshNode closestNode          = null;

                    int containingIndex = nodes.Count - 1;

                    // If we still couldn't find a good node
                    // Check all nodes in the whole path

                    // We are checking for if any node is destroyed in the loop
                    // So we can reset this counter
                    checkForDestroyedNodesCounter = 0;

                    for (int i = 0, t = nodes.Count; i < t; i++)
                    {
                        if (nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            lastCorner     = false;
                            buffer.Add(position);
                            return(position);
                        }

                        Vector3 close = nodes[i].ClosestPointOnNode(position);
                        float   d     = (close - position).sqrMagnitude;
                        if (d < closestDist)
                        {
                            closestDist       = d;
                            closestNodeInPath = i;
                            closestNode       = nodes[i];
                            closestIsInPath   = true;
                        }
                    }

                    // Loop through all neighbours of all nodes in the path
                    // and find the closet point on them
                    // We cannot just look on the ones in the path since it is impossible
                    // to know if we are outside the navmesh completely or if we have just
                    // stepped in to an adjacent node

                    // Need to make a copy here, the JIT will move this variable to the heap
                    // because it is used inside a delegate, if we didn't make a copy here
                    // we would *always* allocate 24 bytes (sizeof(position)) on the heap every time
                    // this method was called
                    // now we only do it when this IF statement is executed
                    var posCopy = position;

                    GraphNodeDelegate del = node => {
                        // Check so that this neighbour we are processing is neither the node after the current node or the node before the current node in the path
                        // This is done for optimization, we have already checked those nodes earlier
                        if (!(containingIndex > 0 && node == nodes[containingIndex - 1]) && !(containingIndex < nodes.Count - 1 && node == nodes[containingIndex + 1]))
                        {
                            // Check if the neighbour was a mesh node
                            var mn = node as TriangleMeshNode;
                            if (mn != null)
                            {
                                // Find the distance to the closest point on it from our current position
                                var   close = mn.ClosestPointOnNode(posCopy);
                                float d     = (close - posCopy).sqrMagnitude;

                                // Is that distance better than the best distance seen so far
                                if (d < closestDist)
                                {
                                    closestDist          = d;
                                    closestIsNeighbourOf = containingIndex;
                                    closestNode          = mn;
                                    closestIsInPath      = false;
                                }
                            }
                        }
                    };

                    // Loop through all the nodes in the path in reverse order
                    // The callback needs to know about the index, so we store it
                    // in a local variable which it can read
                    for (; containingIndex >= 0; containingIndex--)
                    {
                        // Loop through all neighbours of the node
                        nodes[containingIndex].GetConnections(del);
                    }

                    // Check if the closest node
                    // was on the path already or if we need to adjust it
                    if (closestIsInPath)
                    {
                        // If we have found a node
                        // Snap to the closest point in XZ space (keep the Y coordinate)
                        // If we would have snapped to the closest point in 3D space, the agent
                        // might slow down when traversing slopes
                        currentNode = closestNodeInPath;
                        position    = nodes[closestNodeInPath].ClosestPointOnNodeXZ(position);
                    }
                    else
                    {
                        // Snap to the closest point in XZ space on the node
                        position = closestNode.ClosestPointOnNodeXZ(position);

                        // We have found a node containing the position, but it is outside the funnel
                        // Recalculate the funnel to include this node
                        exactStart = position;
                        UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);

                        // Restart from the first node in the updated path
                        currentNode = 0;
                    }
                }
            }

            currentPosition = position;


            if (!FindNextCorners(position, currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }

            return(position);
        }
Esempio n. 20
0
        Vector3 Snap(ABPath path, Exactness mode, bool start, out bool forceAddPoint)
        {
            var index   = start ? 0 : path.path.Count - 1;
            var node    = path.path[index];
            var nodePos = (Vector3)node.position;

            forceAddPoint = false;

            switch (mode)
            {
            case Exactness.ClosestOnNode:
                return(GetClampedPoint(nodePos, start ? path.startPoint : path.endPoint, node));

            case Exactness.SnapToNode:
                return(nodePos);

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

                switch (mode)
                {
                case Exactness.Original:
                    return(GetClampedPoint(nodePos, relevantPoint, node));

                case Exactness.Interpolate:
                    var clamped = GetClampedPoint(nodePos, relevantPoint, node);
                    // Adjacent node to either the start node or the end node in the path
                    var adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count - 1)];
                    return(VectorMath.ClosestPointOnSegment(nodePos, (Vector3)adjacentNode.position, clamped));

                case Exactness.NodeConnection:
                    // This code uses some tricks to avoid allocations
                    // even though it uses delegates heavily
                    // The connectionBufferAddDelegate delegate simply adds whatever node
                    // it is called with to the connectionBuffer
                    connectionBuffer            = connectionBuffer ?? new List <GraphNode>();
                    connectionBufferAddDelegate = connectionBufferAddDelegate ?? (GraphNodeDelegate)connectionBuffer.Add;

                    // Adjacent node to either the start node or the end node in the path
                    adjacentNode = path.path[Mathf.Clamp(index + (start ? 1 : -1), 0, path.path.Count - 1)];

                    // Add all neighbours of #node to the connectionBuffer
                    node.GetConnections(connectionBufferAddDelegate);
                    var bestPos  = nodePos;
                    var bestDist = float.PositiveInfinity;

                    // Loop through all neighbours
                    // Do it in reverse order because the length of the connectionBuffer
                    // will change during iteration
                    for (int i = connectionBuffer.Count - 1; i >= 0; i--)
                    {
                        var neighbour = connectionBuffer[i];

                        // Find the closest point on the connection between the nodes
                        // and check if the distance to that point is lower than the previous best
                        var closest = VectorMath.ClosestPointOnSegment(nodePos, (Vector3)neighbour.position, relevantPoint);

                        var dist = (closest - relevantPoint).sqrMagnitude;
                        if (dist < bestDist)
                        {
                            bestPos  = closest;
                            bestDist = dist;

                            // If this node is not the adjacent node
                            // then the path should go through the start node as well
                            forceAddPoint = neighbour != adjacentNode;
                        }
                    }

                    connectionBuffer.Clear();
                    return(bestPos);

                default:
                    throw new System.ArgumentException("Cannot reach this point, but the compiler is not smart enough to realize that.");
                }

            default:
                throw new System.ArgumentException("Invalid mode");
            }
        }
Esempio n. 21
0
 public abstract void GetConnections(GraphNodeDelegate del);
Esempio n. 22
0
		public override void GetConnections (GraphNodeDelegate del)
		{
			
			GridGraph gg = GetGridGraph (GraphIndex);
			int[] neighbourOffsets = gg.neighbourOffsets;
			GridNode[] nodes = gg.nodes;
			
			for (int i=0;i<8;i++) {
				if (GetConnectionInternal(i)) {
					GridNode other = nodes[nodeInGridIndex + neighbourOffsets[i]];
					if (other != null) del (other);
				}
			}
			
		}
Esempio n. 23
0
		public override void GetConnections (GraphNodeDelegate del) {
			if (connections == null) return;
			for (int i=0;i<connections.Length;i++) del (connections[i]);
		}
Esempio n. 24
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.");
        }