Pathfinding.TriangleMeshNode.GetPortal C# (CSharp) Method

GetPortal() public method

public GetPortal ( GraphNode _other, System left, System right, bool backwards, int &aIndex, int &bIndex ) : bool
_other GraphNode
left System
right System
backwards bool
aIndex int
bIndex int
return bool
		public bool GetPortal (GraphNode _other, System.Collections.Generic.List<Vector3> left, System.Collections.Generic.List<Vector3> right, bool backwards, out int aIndex, out int bIndex)
		{
			aIndex = -1;
			bIndex = -1;
			
			//If the nodes are in different graphs, this function has no idea on how to find a shared edge.
			if (_other.GraphIndex != GraphIndex) return false;
			
			TriangleMeshNode other = _other as TriangleMeshNode;
			
			//Get tile indices
			int tileIndex = (GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;
			int tileIndex2 = (other.GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;
			
			//When the nodes are in different tiles, the edges might not be completely identical
			//so another technique is needed
			//Only do this on recast graphs
			if (tileIndex != tileIndex2 && ( GetNavmeshHolder(GraphIndex) is RecastGraph)) {

				for ( int i=0;i<connections.Length;i++) {
					
					if ( connections[i].GraphIndex != GraphIndex ) {
						NodeLink3Node mid = connections[i] as NodeLink3Node;
						if ( mid != null && mid.GetOther (this) == other ) {
							// We have found a node which is connected through a NodeLink3Node
							
							if ( left != null ) {
								mid.GetPortal ( other, left, right, false );
								return true;
							}
						}
					}
				}

				//Get the tile coordinates, from them we can figure out which edge is going to be shared
				int x1, x2, z1, z2;
				int coord;
				INavmeshHolder nm = GetNavmeshHolder (GraphIndex);
				nm.GetTileCoordinates(tileIndex, out x1, out z1);
				nm.GetTileCoordinates(tileIndex2, out x2, out z2);
				
				if (System.Math.Abs(x1-x2) == 1) coord = 0;
				else if (System.Math.Abs(z1-z2) == 1) coord = 2;
				else throw new System.Exception ("Tiles not adjacent (" + x1+", " + z1 +") (" + x2 + ", " + z2+")");
				
				int av = GetVertexCount ();
				int bv = other.GetVertexCount ();
				
				//Try the X and Z coordinate. For one of them the coordinates should be equal for one of the two nodes' edges
				//The midpoint between the tiles is the only place where they will be equal
				
				int first = -1, second = -1;
				
				//Find the shared edge
				for (int a=0;a<av;a++) {
					int va = GetVertex(a)[coord];
					for (int b=0;b<bv;b++) {
						if (va == other.GetVertex((b+1)%bv)[coord] && GetVertex((a+1) % av)[coord] == other.GetVertex(b)[coord]) {
							first = a;
							second = b;
							a = av;
							break;
						}
					}
				}
				
				aIndex = first;
				bIndex = second;
				
				if (first != -1) {
					
					Int3 a = GetVertex(first);
					Int3 b = GetVertex((first+1)%av);
					
					//The coordinate which is not the same for the vertices
					int ocoord = coord == 2 ? 0 : 2;
					
					//When the nodes are in different tiles, they might not share exactly the same edge
					//so we clamp the portal to the segment of the edges which they both have.
					int mincoord = System.Math.Min(a[ocoord], b[ocoord]);
					int maxcoord = System.Math.Max(a[ocoord], b[ocoord]);
					
					mincoord = System.Math.Max (mincoord, System.Math.Min(other.GetVertex(second)[ocoord], other.GetVertex((second+1)%bv)[ocoord]));
					maxcoord = System.Math.Min (maxcoord, System.Math.Max(other.GetVertex(second)[ocoord], other.GetVertex((second+1)%bv)[ocoord]));
					
					if (a[ocoord] < b[ocoord]) {
						a[ocoord] = mincoord;
						b[ocoord] = maxcoord;
					} else {
						a[ocoord] = maxcoord;
						b[ocoord] = mincoord;
					}
					
					if (left != null) {
						//All triangles should be clockwise so second is the rightmost vertex (seen from this node)
						left.Add ((Vector3)a);
						right.Add ((Vector3)b);
					}
					return true;
				}
			} else
			if (!backwards) {
				
				int first = -1;
				int second = -1;
				
				int av = GetVertexCount ();
				int bv = other.GetVertexCount ();
				
				/** \todo Maybe optimize with pa=av-1 instead of modulus... */
				for (int a=0;a<av;a++) {
					int va = GetVertexIndex(a);
					for (int b=0;b<bv;b++) {
						if (va == other.GetVertexIndex((b+1)%bv) && GetVertexIndex((a+1) % av) == other.GetVertexIndex(b)) {
							first = a;
							second = b;
							a = av;
							break;
						}
						
					}
				}
				
				aIndex = first;
				bIndex = second;
				
				if (first != -1) {
					
					if (left != null) {
						//All triangles should be clockwise so second is the rightmost vertex (seen from this node)
						left.Add ((Vector3)GetVertex(first));
						right.Add ((Vector3)GetVertex((first+1)%av));
					}
				} else {
					for ( int i=0;i<connections.Length;i++) {
						
						if ( connections[i].GraphIndex != GraphIndex ) {
							NodeLink3Node mid = connections[i] as NodeLink3Node;
							if ( mid != null && mid.GetOther (this) == other ) {
								// We have found a node which is connected through a NodeLink3Node
								
								if ( left != null ) {
									mid.GetPortal ( other, left, right, false );
									return true;
								}
							}
						}
					}
					return false;
				}
			}
			
			return true;
		}
		

Same methods

TriangleMeshNode::GetPortal ( GraphNode _other, System left, System right, bool backwards ) : bool

Usage Example

Ejemplo n.º 1
0
        public static bool Linecast(INavmesh graph, Vector3 tmp_origin, Vector3 tmp_end, GraphNode hint, out GraphHitInfo hit, List <GraphNode> trace)
        {
            Int3 @int = (Int3)tmp_end;
            Int3 int2 = (Int3)tmp_origin;

            hit = default(GraphHitInfo);
            if (float.IsNaN(tmp_origin.x + tmp_origin.y + tmp_origin.z))
            {
                throw new ArgumentException("origin is NaN");
            }
            if (float.IsNaN(tmp_end.x + tmp_end.y + tmp_end.z))
            {
                throw new ArgumentException("end is NaN");
            }
            TriangleMeshNode triangleMeshNode = hint as TriangleMeshNode;

            if (triangleMeshNode == null)
            {
                triangleMeshNode = ((graph as NavGraph).GetNearest(tmp_origin, NNConstraint.None).node as TriangleMeshNode);
                if (triangleMeshNode == null)
                {
                    Debug.LogError("Could not find a valid node to start from");
                    hit.point = tmp_origin;
                    return(true);
                }
            }
            if (int2 == @int)
            {
                hit.node = triangleMeshNode;
                return(false);
            }
            int2       = (Int3)triangleMeshNode.ClosestPointOnNode((Vector3)int2);
            hit.origin = (Vector3)int2;
            if (!triangleMeshNode.Walkable)
            {
                hit.point         = (Vector3)int2;
                hit.tangentOrigin = (Vector3)int2;
                return(true);
            }
            List <Vector3> list = ListPool <Vector3> .Claim();

            List <Vector3> list2 = ListPool <Vector3> .Claim();

            int num = 0;

            while (true)
            {
                num++;
                if (num > 2000)
                {
                    break;
                }
                TriangleMeshNode triangleMeshNode2 = null;
                if (trace != null)
                {
                    trace.Add(triangleMeshNode);
                }
                if (triangleMeshNode.ContainsPoint(@int))
                {
                    goto Block_9;
                }
                for (int i = 0; i < triangleMeshNode.connections.Length; i++)
                {
                    if (triangleMeshNode.connections[i].GraphIndex == triangleMeshNode.GraphIndex)
                    {
                        list.Clear();
                        list2.Clear();
                        if (triangleMeshNode.GetPortal(triangleMeshNode.connections[i], list, list2, false))
                        {
                            Vector3 vector  = list[0];
                            Vector3 vector2 = list2[0];
                            if (Polygon.LeftNotColinear(vector, vector2, hit.origin) || !Polygon.LeftNotColinear(vector, vector2, tmp_end))
                            {
                                float num2;
                                float num3;
                                if (Polygon.IntersectionFactor(vector, vector2, hit.origin, tmp_end, out num2, out num3))
                                {
                                    if (num3 >= 0f)
                                    {
                                        if (num2 >= 0f && num2 <= 1f)
                                        {
                                            triangleMeshNode2 = (triangleMeshNode.connections[i] as TriangleMeshNode);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (triangleMeshNode2 == null)
                {
                    goto Block_18;
                }
                triangleMeshNode = triangleMeshNode2;
            }
            Debug.LogError("Linecast was stuck in infinite loop. Breaking.");
            ListPool <Vector3> .Release(list);

            ListPool <Vector3> .Release(list2);

            return(true);

Block_9:
            ListPool <Vector3> .Release(list);

            ListPool <Vector3> .Release(list2);

            return(false);

Block_18:
            int vertexCount = triangleMeshNode.GetVertexCount();

            for (int j = 0; j < vertexCount; j++)
            {
                Vector3 vector3 = (Vector3)triangleMeshNode.GetVertex(j);
                Vector3 vector4 = (Vector3)triangleMeshNode.GetVertex((j + 1) % vertexCount);
                if (Polygon.LeftNotColinear(vector3, vector4, hit.origin) || !Polygon.LeftNotColinear(vector3, vector4, tmp_end))
                {
                    float num4;
                    float num5;
                    if (Polygon.IntersectionFactor(vector3, vector4, hit.origin, tmp_end, out num4, out num5))
                    {
                        if (num5 >= 0f)
                        {
                            if (num4 >= 0f && num4 <= 1f)
                            {
                                Vector3 point = vector3 + (vector4 - vector3) * num4;
                                hit.point         = point;
                                hit.node          = triangleMeshNode;
                                hit.tangent       = vector4 - vector3;
                                hit.tangentOrigin = vector3;
                                ListPool <Vector3> .Release(list);

                                ListPool <Vector3> .Release(list2);

                                return(true);
                            }
                        }
                    }
                }
            }
            Debug.LogWarning("Linecast failing because point not inside node, and line does not hit any edges of it");
            ListPool <Vector3> .Release(list);

            ListPool <Vector3> .Release(list2);

            return(false);
        }
All Usage Examples Of Pathfinding.TriangleMeshNode::GetPortal