GetVertex() public method

public GetVertex ( int i ) : Int3
i int
return Int3
Example #1
0
        /// <summary>
        /// ³õʼ»¯graphNodeÕ¤¸ñÆ÷
        /// </summary>
        public void InitRasterizer(int inCellSize = 4000)
        {
            if (this.graphs == null || this.graphs.Length == 0)
            {
                return;
            }
            rasterizer = new GraphNodeRasterizer();
            Int2 min = new Int2(2147483647, 2147483647);
            Int2 max = new Int2(-2147483648, -2147483648);

            for (int j = 0; j < this.graphs.Length; j++)
            {
                RecastGraph recastGraph2 = this.graphs[j] as RecastGraph;
                if (recastGraph2 == null)
                {
                    return;
                }
                recastGraph2.GetNodes(delegate(GraphNode node)
                {
                    TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        Int2 xz  = triangleMeshNode.GetVertex(0).xz;
                        Int2 xz2 = triangleMeshNode.GetVertex(1).xz;
                        Int2 xz3 = triangleMeshNode.GetVertex(2).xz;
                        min.Min(ref xz);
                        min.Min(ref xz2);
                        min.Min(ref xz3);
                        max.Max(ref xz);
                        max.Max(ref xz2);
                        max.Max(ref xz3);
                    }
                    return(true);
                });
            }
            rasterizer.Init(min, max.x - min.x, max.y - min.y, inCellSize);

            for (int k = 0; k < this.graphs.Length; k++)
            {
                RecastGraph recastGraph3 = this.graphs[k] as RecastGraph;
                if (recastGraph3 != null)
                {
                    recastGraph3.GetNodes(delegate(GraphNode node)
                    {
                        TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                        if (triangleMeshNode != null)
                        {
                            Int2 xz  = triangleMeshNode.GetVertex(0).xz;
                            Int2 xz2 = triangleMeshNode.GetVertex(1).xz;
                            Int2 xz3 = triangleMeshNode.GetVertex(2).xz;
                            rasterizer.AddTriangle(ref xz, ref xz2, ref xz3, triangleMeshNode);
                        }
                        return(true);
                    });
                }
            }
        }
        // Token: 0x0600229B RID: 8859 RVA: 0x00190E64 File Offset: 0x0018F064
        public static void GetContours(INavmesh navmesh, Action <List <Int3>, bool> results)
        {
            bool[] uses = new bool[3];
            Dictionary <int, int>  outline         = new Dictionary <int, int>();
            Dictionary <int, Int3> vertexPositions = new Dictionary <int, Int3>();
            HashSet <int>          hasInEdge       = new HashSet <int>();

            navmesh.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                uses[0] = (uses[1] = (uses[2] = false));
                if (triangleMeshNode != null)
                {
                    for (int i = 0; i < triangleMeshNode.connections.Length; i++)
                    {
                        TriangleMeshNode triangleMeshNode2 = triangleMeshNode.connections[i].node as TriangleMeshNode;
                        if (triangleMeshNode2 != null)
                        {
                            int num = triangleMeshNode.SharedEdge(triangleMeshNode2);
                            if (num != -1)
                            {
                                uses[num] = true;
                            }
                        }
                    }
                    for (int j = 0; j < 3; j++)
                    {
                        if (!uses[j])
                        {
                            int i2 = j;
                            int i3 = (j + 1) % triangleMeshNode.GetVertexCount();
                            outline[triangleMeshNode.GetVertexIndex(i2)] = triangleMeshNode.GetVertexIndex(i3);
                            hasInEdge.Add(triangleMeshNode.GetVertexIndex(i3));
                            vertexPositions[triangleMeshNode.GetVertexIndex(i2)] = triangleMeshNode.GetVertex(i2);
                            vertexPositions[triangleMeshNode.GetVertexIndex(i3)] = triangleMeshNode.GetVertex(i3);
                        }
                    }
                }
            });
            Polygon.TraceContours(outline, hasInEdge, delegate(List <int> chain, bool cycle)
            {
                List <Int3> list = ListPool <Int3> .Claim();
                for (int i = 0; i < chain.Count; i++)
                {
                    list.Add(vertexPositions[chain[i]]);
                }
                results(list, cycle);
            });
        }
Example #3
0
        public static void BuildFunnelCorridor(INavmesh graph, List <GraphNode> path, int startIndex, int endIndex, List <Vector3> left, List <Vector3> right)
        {
            if (graph == null)
            {
                Debug.LogError("Couldn't cast graph to the appropriate type (graph isn't a Navmesh type graph, it doesn't implement the INavmesh interface)");
                return;
            }

            for (int i = startIndex; i < endIndex; i++)
            {
                //Find the connection between the nodes

                TriangleMeshNode n1 = path[i] as TriangleMeshNode;
                TriangleMeshNode n2 = path[i + 1] as TriangleMeshNode;

                int  a;
                bool search = true;
                for (a = 0; a < 3; a++)
                {
                    for (int b = 0; b < 3; b++)
                    {
                        if (n1.GetVertexIndex(a) == n2.GetVertexIndex((b + 1) % 3) && n1.GetVertexIndex((a + 1) % 3) == n2.GetVertexIndex(b))
                        {
                            search = false;
                            break;
                        }
                    }
                    if (!search)
                    {
                        break;
                    }
                }

                if (a == 3)
                {
                    left.Add((Vector3)n1.position);
                    right.Add((Vector3)n1.position);
                    left.Add((Vector3)n2.position);
                    right.Add((Vector3)n2.position);
                }
                else
                {
                    left.Add((Vector3)n1.GetVertex(a));
                    right.Add((Vector3)n1.GetVertex((a + 1) % 3));
                }
            }
        }
Example #4
0
 public static void BuildFunnelCorridor(INavmesh graph, List <GraphNode> path, int startIndex, int endIndex, List <Vector3> left, List <Vector3> right)
 {
     if (graph == null)
     {
         Debug.LogError("Couldn't cast graph to the appropriate type (graph isn't a Navmesh type graph, it doesn't implement the INavmesh interface)");
         return;
     }
     for (int i = startIndex; i < endIndex; i++)
     {
         TriangleMeshNode triangleMeshNode  = path[i] as TriangleMeshNode;
         TriangleMeshNode triangleMeshNode2 = path[i + 1] as TriangleMeshNode;
         bool             flag = true;
         int j;
         for (j = 0; j < 3; j++)
         {
             for (int k = 0; k < 3; k++)
             {
                 if (triangleMeshNode.GetVertexIndex(j) == triangleMeshNode2.GetVertexIndex((k + 1) % 3) && triangleMeshNode.GetVertexIndex((j + 1) % 3) == triangleMeshNode2.GetVertexIndex(k))
                 {
                     flag = false;
                     break;
                 }
             }
             if (!flag)
             {
                 break;
             }
         }
         if (j == 3)
         {
             left.Add((Vector3)triangleMeshNode.position);
             right.Add((Vector3)triangleMeshNode.position);
             left.Add((Vector3)triangleMeshNode2.position);
             right.Add((Vector3)triangleMeshNode2.position);
         }
         else
         {
             left.Add((Vector3)triangleMeshNode.GetVertex(j));
             right.Add((Vector3)triangleMeshNode.GetVertex((j + 1) % 3));
         }
     }
 }
Example #5
0
 static void DrawDebugNode(TriangleMeshNode node, float yoffset, Color color)
 {
     Debug.DrawLine((Vector3)node.GetVertex(1) + Vector3.up * yoffset,
                    (Vector3)node.GetVertex(2) + Vector3.up * yoffset, color);
     Debug.DrawLine((Vector3)node.GetVertex(0) + Vector3.up * yoffset,
                    (Vector3)node.GetVertex(1) + Vector3.up * yoffset, color);
     Debug.DrawLine((Vector3)node.GetVertex(2) + Vector3.up * yoffset,
                    (Vector3)node.GetVertex(0) + Vector3.up * yoffset, color);
 }
Example #6
0
		/** Create a tile at tile index \a x , \a z from the mesh.
		 * \warning This implementation is not thread safe. It uses cached variables to improve performance
		 */
		NavmeshTile CreateTile (Voxelize vox, VoxelMesh mesh, int x, int z) {
			
			if (mesh.tris == null) throw new System.ArgumentNullException ("The mesh must be valid. tris is null.");
			if (mesh.verts == null) throw new System.ArgumentNullException ("The mesh must be valid. verts is null.");
			
			//Create a new navmesh tile and assign its settings
			NavmeshTile tile = new NavmeshTile();
			
			tile.x = x;
			tile.z = z;
			tile.w = 1;
			tile.d = 1;
			tile.tris = mesh.tris;
			tile.verts = mesh.verts;
			tile.bbTree = new BBTree(tile);
			
			if (tile.tris.Length % 3 != 0) throw new System.ArgumentException ("Indices array's length must be a multiple of 3 (mesh.tris)");
			
			if (tile.verts.Length >= VertexIndexMask) throw new System.ArgumentException ("Too many vertices per tile (more than "+VertexIndexMask+")." +
				"\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector");
			
			//Dictionary<Int3, int> firstVerts = new Dictionary<Int3, int> ();
			Dictionary<Int3, int> firstVerts = cachedInt3_int_dict;
			firstVerts.Clear();
			
			int[] compressedPointers = new int[tile.verts.Length];
			
			int count = 0;
			for (int i=0;i<tile.verts.Length;i++) {
				try {
					firstVerts.Add (tile.verts[i], count);
					compressedPointers[i] = count;
					tile.verts[count] = tile.verts[i];
					count++;
				} catch {
					//There are some cases, rare but still there, that vertices are identical
					compressedPointers[i] = firstVerts[tile.verts[i]];
				}
			}
			
			for (int i=0;i<tile.tris.Length;i++) {
				tile.tris[i] = compressedPointers[tile.tris[i]];
			}
			
			Int3[] compressed = new Int3[count];
			for (int i=0;i<count;i++) compressed[i] = tile.verts[i];
			
			tile.verts = compressed;
			
			TriangleMeshNode[] nodes = new TriangleMeshNode[tile.tris.Length/3];
			tile.nodes = nodes;
			
			//Here we are faking a new graph
			//The tile is not added to any graphs yet, but to get the position querys from the nodes
			//to work correctly (not throw exceptions because the tile is not calculated) we fake a new graph
			//and direct the position queries directly to the tile
			int graphIndex = AstarPath.active.astarData.graphs.Length;
			
			TriangleMeshNode.SetNavmeshHolder (graphIndex, tile);
			
			//This index will be ORed to the triangle indices
			int tileIndex = x + z*tileXCount;
			tileIndex <<= TileIndexOffset;
			
			//Create nodes and assign triangle indices
			for (int i=0;i<nodes.Length;i++) {
				TriangleMeshNode node = new TriangleMeshNode(active);
				nodes[i] = node;
				node.GraphIndex = (uint)graphIndex;
				node.v0 = tile.tris[i*3+0] | tileIndex;
				node.v1 = tile.tris[i*3+1] | tileIndex;
				node.v2 = tile.tris[i*3+2] | tileIndex;
				
				//Degenerate triangles might ocurr, but they will not cause any large troubles anymore
				//if (Polygon.IsColinear (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
				//	Debug.Log ("COLINEAR!!!!!!");
				//}
				
				//Make sure the triangle is clockwise
				if (!Polygon.IsClockwise (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
					int tmp = node.v0;
					node.v0 = node.v2;
					node.v2 = tmp;
				}
				
				node.Walkable = true;
				node.Penalty = initialPenalty;
				node.UpdatePositionFromVertices();
				tile.bbTree.Insert (node);
			}
			
			CreateNodeConnections (tile.nodes);
			
			//Remove the fake graph
			TriangleMeshNode.SetNavmeshHolder (graphIndex, null);
			
			return tile;
		}
Example #7
0
        public bool GetPortal(GraphNode _other, List <VInt3> left, List <VInt3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode node = _other as TriangleMeshNode;
            int tileIndex         = (this.GetVertexIndex(0) >> 12) & 0x7ffff;
            int num2 = (node.GetVertexIndex(0) >> 12) & 0x7ffff;

            if ((tileIndex != num2) && (GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex) is RecastGraph))
            {
                int            num3;
                int            num4;
                int            num5;
                int            num6;
                int            num7;
                INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);
                navmeshHolder.GetTileCoordinates(tileIndex, out num3, out num5);
                navmeshHolder.GetTileCoordinates(num2, out num4, out num6);
                if (Math.Abs((int)(num3 - num4)) == 1)
                {
                    num7 = 0;
                }
                else if (Math.Abs((int)(num5 - num6)) == 1)
                {
                    num7 = 2;
                }
                else
                {
                    object[] objArray1 = new object[] { "Tiles not adjacent (", num3, ", ", num5, ") (", num4, ", ", num6, ")" };
                    throw new Exception(string.Concat(objArray1));
                }
                int vertexCount = this.GetVertexCount();
                int num9        = node.GetVertexCount();
                int i           = -1;
                int num11       = -1;
                for (int j = 0; j < vertexCount; j++)
                {
                    int num13 = this.GetVertex(j)[num7];
                    for (int k = 0; k < num9; k++)
                    {
                        if ((num13 == node.GetVertex((k + 1) % num9)[num7]) && (this.GetVertex((j + 1) % vertexCount)[num7] == node.GetVertex(k)[num7]))
                        {
                            i     = j;
                            num11 = k;
                            j     = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = i;
                bIndex = num11;
                if (i != -1)
                {
                    VInt3 vertex = this.GetVertex(i);
                    VInt3 item   = this.GetVertex((i + 1) % vertexCount);
                    int   num17  = (num7 != 2) ? 2 : 0;
                    int   num18  = Math.Min(vertex[num17], item[num17]);
                    int   num19  = Math.Max(vertex[num17], item[num17]);
                    num18 = Math.Max(num18, Math.Min(node.GetVertex(num11)[num17], node.GetVertex((num11 + 1) % num9)[num17]));
                    num19 = Math.Min(num19, Math.Max(node.GetVertex(num11)[num17], node.GetVertex((num11 + 1) % num9)[num17]));
                    if (vertex[num17] < item[num17])
                    {
                        vertex[num17] = num18;
                        item[num17]   = num19;
                    }
                    else
                    {
                        vertex[num17] = num19;
                        item[num17]   = num18;
                    }
                    if (left != null)
                    {
                        left.Add(vertex);
                        right.Add(item);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num20 = -1;
                int num21 = -1;
                int num22 = this.GetVertexCount();
                int num23 = node.GetVertexCount();
                for (int m = 0; m < num22; m++)
                {
                    int vertexIndex = this.GetVertexIndex(m);
                    for (int n = 0; n < num23; n++)
                    {
                        if ((vertexIndex == node.GetVertexIndex((n + 1) % num23)) && (this.GetVertexIndex((m + 1) % num22) == node.GetVertexIndex(n)))
                        {
                            num20 = m;
                            num21 = n;
                            m     = num22;
                            break;
                        }
                    }
                }
                aIndex = num20;
                bIndex = num21;
                if (num20 == -1)
                {
                    return(false);
                }
                if (left != null)
                {
                    left.Add(this.GetVertex(num20));
                    right.Add(this.GetVertex((num20 + 1) % num22));
                }
            }
            return(true);
        }
Example #8
0
 public static bool Linecast(INavmesh graph, VInt3 tmp_origin, VInt3 tmp_end, GraphNode hint, out GraphHitInfo hit, List<GraphNode> trace)
 {
     VInt3 vInt = tmp_end;
     VInt3 vInt2 = tmp_origin;
     hit = default(GraphHitInfo);
     if (float.IsNaN((float)(tmp_origin.x + tmp_origin.y + tmp_origin.z)))
     {
         throw new ArgumentException("origin is NaN");
     }
     if (float.IsNaN((float)(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 (vInt2 == vInt)
     {
         hit.node = triangleMeshNode;
         return false;
     }
     vInt2 = (VInt3)triangleMeshNode.ClosestPointOnNode((Vector3)vInt2);
     hit.origin = vInt2;
     if (!triangleMeshNode.Walkable)
     {
         hit.point = vInt2;
         hit.tangentOrigin = vInt2;
         return true;
     }
     List<VInt3> list = ListPool<VInt3>.Claim();
     List<VInt3> list2 = ListPool<VInt3>.Claim();
     int num = 0;
     while (true)
     {
         num++;
         if (num > 2000)
         {
             break;
         }
         TriangleMeshNode triangleMeshNode2 = null;
         if (trace != null)
         {
             trace.Add(triangleMeshNode);
         }
         if (triangleMeshNode.ContainsPoint(vInt))
         {
             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))
                 {
                     VInt3 vInt3 = list.get_Item(0);
                     VInt3 vInt4 = list2.get_Item(0);
                     if (Polygon.LeftNotColinear(vInt3, vInt4, hit.origin) || !Polygon.LeftNotColinear(vInt3, vInt4, tmp_end))
                     {
                         float num2;
                         float num3;
                         if (Polygon.IntersectionFactor(vInt3, vInt4, 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<VInt3>.Release(list);
     ListPool<VInt3>.Release(list2);
     return true;
     Block_9:
     ListPool<VInt3>.Release(list);
     ListPool<VInt3>.Release(list2);
     return false;
     Block_18:
     int vertexCount = triangleMeshNode.GetVertexCount();
     for (int j = 0; j < vertexCount; j++)
     {
         VInt3 vertex = triangleMeshNode.GetVertex(j);
         VInt3 vertex2 = triangleMeshNode.GetVertex((j + 1) % vertexCount);
         if (Polygon.LeftNotColinear(vertex, vertex2, hit.origin) || !Polygon.LeftNotColinear(vertex, vertex2, tmp_end))
         {
             VFactor vFactor;
             VFactor vFactor2;
             if (Polygon.IntersectionFactor(vertex, vertex2, hit.origin, tmp_end, out vFactor, out vFactor2))
             {
                 if (!vFactor2.IsNegative)
                 {
                     if (!vFactor.IsNegative && vFactor.nom / vFactor.den <= 1L)
                     {
                         VInt3 vInt5 = (vertex2 - vertex) * (float)vFactor.nom;
                         vInt5 = IntMath.Divide(vInt5, vFactor.den);
                         vInt5 += vertex;
                         hit.point = vInt5;
                         hit.node = triangleMeshNode;
                         hit.tangent = vertex2 - vertex;
                         hit.tangentOrigin = vertex;
                         ListPool<VInt3>.Release(list);
                         ListPool<VInt3>.Release(list2);
                         return true;
                     }
                 }
             }
         }
     }
     Debug.LogWarning("Linecast failing because point not inside node, and line does not hit any edges of it");
     ListPool<VInt3>.Release(list);
     ListPool<VInt3>.Release(list2);
     return false;
 }
Example #9
0
        private void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
        {
            if (range <= 0f)
            {
                return;
            }
            bool flag  = false;
            bool flag2 = false;

            range     *= range;
            position.y = 0f;
            int num = 0;

            while (!flag || !flag2)
            {
                if (num >= 0 || !flag)
                {
                    if (num <= 0 || !flag2)
                    {
                        if (num < 0 && nodeIndex + num < 0)
                        {
                            flag = true;
                        }
                        else if (num > 0 && nodeIndex + num >= this.nodes.Count)
                        {
                            flag2 = true;
                        }
                        else
                        {
                            TriangleMeshNode triangleMeshNode  = (nodeIndex + num - 1 >= 0) ? this.nodes[nodeIndex + num - 1] : null;
                            TriangleMeshNode triangleMeshNode2 = this.nodes[nodeIndex + num];
                            TriangleMeshNode triangleMeshNode3 = (nodeIndex + num + 1 < this.nodes.Count) ? this.nodes[nodeIndex + num + 1] : null;
                            if (triangleMeshNode2.Destroyed)
                            {
                                break;
                            }
                            if ((triangleMeshNode2.ClosestPointOnNodeXZ(position) - position).sqrMagnitude > range)
                            {
                                if (num < 0)
                                {
                                    flag = true;
                                }
                                else
                                {
                                    flag2 = true;
                                }
                            }
                            else
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    this.triBuffer[i] = 0;
                                }
                                for (int j = 0; j < triangleMeshNode2.connections.Length; j++)
                                {
                                    TriangleMeshNode triangleMeshNode4 = triangleMeshNode2.connections[j].node as TriangleMeshNode;
                                    if (triangleMeshNode4 != null)
                                    {
                                        int num2 = -1;
                                        for (int k = 0; k < 3; k++)
                                        {
                                            for (int l = 0; l < 3; l++)
                                            {
                                                if (triangleMeshNode2.GetVertex(k) == triangleMeshNode4.GetVertex((l + 1) % 3) && triangleMeshNode2.GetVertex((k + 1) % 3) == triangleMeshNode4.GetVertex(l))
                                                {
                                                    num2 = k;
                                                    k    = 3;
                                                    break;
                                                }
                                            }
                                        }
                                        if (num2 != -1)
                                        {
                                            this.triBuffer[num2] = ((triangleMeshNode4 != triangleMeshNode && triangleMeshNode4 != triangleMeshNode3) ? 1 : 2);
                                        }
                                    }
                                }
                                for (int m = 0; m < 3; m++)
                                {
                                    if (this.triBuffer[m] == 0)
                                    {
                                        wallBuffer.Add((Vector3)triangleMeshNode2.GetVertex(m));
                                        wallBuffer.Add((Vector3)triangleMeshNode2.GetVertex((m + 1) % 3));
                                    }
                                }
                            }
                        }
                    }
                }
                num = ((num >= 0) ? (-num - 1) : (-num));
            }
            if (this.path.transform != null)
            {
                for (int n = 0; n < wallBuffer.Count; n++)
                {
                    wallBuffer[n] = this.path.transform.Transform(wallBuffer[n]);
                }
            }
        }
Example #10
0
 private void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
 {
     if (range > 0f)
     {
         bool flag  = false;
         bool flag2 = false;
         range     *= range;
         position.y = 0f;
         for (int i = 0; !flag || !flag2; i = (i >= 0) ? (-i - 1) : -i)
         {
             if (((i >= 0) || !flag) && ((i <= 0) || !flag2))
             {
                 if ((i < 0) && ((nodeIndex + i) < 0))
                 {
                     flag = true;
                 }
                 else if ((i > 0) && ((nodeIndex + i) >= this.nodes.Count))
                 {
                     flag2 = true;
                 }
                 else
                 {
                     TriangleMeshNode node  = (((nodeIndex + i) - 1) >= 0) ? this.nodes[(nodeIndex + i) - 1] : null;
                     TriangleMeshNode node2 = this.nodes[nodeIndex + i];
                     TriangleMeshNode node3 = (((nodeIndex + i) + 1) < this.nodes.Count) ? this.nodes[(nodeIndex + i) + 1] : null;
                     if (node2.Destroyed)
                     {
                         break;
                     }
                     Vector3 vector = node2.ClosestPointOnNodeXZ(position) - position;
                     if (vector.sqrMagnitude > range)
                     {
                         if (i < 0)
                         {
                             flag = true;
                         }
                         else
                         {
                             flag2 = true;
                         }
                     }
                     else
                     {
                         for (int j = 0; j < 3; j++)
                         {
                             this.triBuffer[j] = 0;
                         }
                         for (int k = 0; k < node2.connections.Length; k++)
                         {
                             TriangleMeshNode node4 = node2.connections[k] as TriangleMeshNode;
                             if (node4 != null)
                             {
                                 int index = -1;
                                 for (int n = 0; n < 3; n++)
                                 {
                                     for (int num6 = 0; num6 < 3; num6++)
                                     {
                                         if ((node2.GetVertex(n) == node4.GetVertex((num6 + 1) % 3)) && (node2.GetVertex((n + 1) % 3) == node4.GetVertex(num6)))
                                         {
                                             index = n;
                                             n     = 3;
                                             break;
                                         }
                                     }
                                 }
                                 if (index != -1)
                                 {
                                     this.triBuffer[index] = ((node4 != node) && (node4 != node3)) ? 1 : 2;
                                 }
                             }
                         }
                         for (int m = 0; m < 3; m++)
                         {
                             if (this.triBuffer[m] == 0)
                             {
                                 wallBuffer.Add((Vector3)node2.GetVertex(m));
                                 wallBuffer.Add((Vector3)node2.GetVertex((m + 1) % 3));
                             }
                         }
                     }
                 }
             }
         }
     }
 }
        public bool GetPortal(GraphNode _other, List <Vector3> left, List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode other = _other as TriangleMeshNode;
            int tileIndex          = (this.GetVertexIndex(0) >> 12) & 0x7ffff;
            int num2 = (other.GetVertexIndex(0) >> 12) & 0x7ffff;

            if ((tileIndex != num2) && (GetNavmeshHolder(base.GraphIndex) is RecastGraph))
            {
                int num4;
                int num5;
                int num6;
                int num7;
                int num8;
                for (int i = 0; i < base.connections.Length; i++)
                {
                    if (base.connections[i].GraphIndex != base.GraphIndex)
                    {
                        NodeLink3Node node2 = base.connections[i] as NodeLink3Node;
                        if (((node2 != null) && (node2.GetOther(this) == other)) && (left != null))
                        {
                            node2.GetPortal(other, left, right, false);
                            return(true);
                        }
                    }
                }
                INavmeshHolder navmeshHolder = GetNavmeshHolder(base.GraphIndex);
                navmeshHolder.GetTileCoordinates(tileIndex, out num4, out num6);
                navmeshHolder.GetTileCoordinates(num2, out num5, out num7);
                if (Math.Abs((int)(num4 - num5)) == 1)
                {
                    num8 = 0;
                }
                else if (Math.Abs((int)(num6 - num7)) == 1)
                {
                    num8 = 2;
                }
                else
                {
                    object[] objArray1 = new object[] { "Tiles not adjacent (", num4, ", ", num6, ") (", num5, ", ", num7, ")" };
                    throw new Exception(string.Concat(objArray1));
                }
                int vertexCount = this.GetVertexCount();
                int num10       = other.GetVertexCount();
                int num11       = -1;
                int num12       = -1;
                for (int j = 0; j < vertexCount; j++)
                {
                    int num14 = this.GetVertex(j)[num8];
                    for (int k = 0; k < num10; k++)
                    {
                        if ((num14 == other.GetVertex((k + 1) % num10)[num8]) && (this.GetVertex((j + 1) % vertexCount)[num8] == other.GetVertex(k)[num8]))
                        {
                            num11 = j;
                            num12 = k;
                            j     = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = num11;
                bIndex = num12;
                if (num11 != -1)
                {
                    Int3 vertex = this.GetVertex(num11);
                    Int3 num17  = this.GetVertex((num11 + 1) % vertexCount);
                    int  num18  = (num8 != 2) ? 2 : 0;
                    int  num19  = Math.Min(vertex[num18], num17[num18]);
                    int  num20  = Math.Max(vertex[num18], num17[num18]);
                    num19 = Math.Max(num19, Math.Min(other.GetVertex(num12)[num18], other.GetVertex((num12 + 1) % num10)[num18]));
                    num20 = Math.Min(num20, Math.Max(other.GetVertex(num12)[num18], other.GetVertex((num12 + 1) % num10)[num18]));
                    if (vertex[num18] < num17[num18])
                    {
                        vertex[num18] = num19;
                        num17[num18]  = num20;
                    }
                    else
                    {
                        vertex[num18] = num20;
                        num17[num18]  = num19;
                    }
                    if (left != null)
                    {
                        left.Add((Vector3)vertex);
                        right.Add((Vector3)num17);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num21 = -1;
                int num22 = -1;
                int num23 = this.GetVertexCount();
                int num24 = other.GetVertexCount();
                for (int m = 0; m < num23; m++)
                {
                    int vertexIndex = this.GetVertexIndex(m);
                    for (int n = 0; n < num24; n++)
                    {
                        if ((vertexIndex == other.GetVertexIndex((n + 1) % num24)) && (this.GetVertexIndex((m + 1) % num23) == other.GetVertexIndex(n)))
                        {
                            num21 = m;
                            num22 = n;
                            m     = num23;
                            break;
                        }
                    }
                }
                aIndex = num21;
                bIndex = num22;
                if (num21 == -1)
                {
                    for (int num28 = 0; num28 < base.connections.Length; num28++)
                    {
                        if (base.connections[num28].GraphIndex != base.GraphIndex)
                        {
                            NodeLink3Node node3 = base.connections[num28] as NodeLink3Node;
                            if (((node3 != null) && (node3.GetOther(this) == other)) && (left != null))
                            {
                                node3.GetPortal(other, left, right, false);
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                if (left != null)
                {
                    left.Add((Vector3)this.GetVertex(num21));
                    right.Add((Vector3)this.GetVertex((num21 + 1) % num23));
                }
            }
            return(true);
        }
Example #12
0
        public GraphNodeRasterizer InitRasterizer(int inCellSize, bool bUseForceBoundsSize = false)
        {
            if (this.graphs == null || this.graphs.Length == 0)
            {
                return(null);
            }
            GraphNodeRasterizer r = new GraphNodeRasterizer();
            VInt2 min             = new VInt2(2147483647, 2147483647);
            VInt2 max             = new VInt2(-2147483648, -2147483648);

            if (bUseForceBoundsSize)
            {
                for (int i = 0; i < this.graphs.Length; i++)
                {
                    RecastGraph recastGraph = this.graphs[i] as RecastGraph;
                    if (recastGraph == null)
                    {
                        return(null);
                    }
                    VInt2 vInt  = new VInt2((int)(recastGraph.forcedBounds.min.x * 1000f), (int)(recastGraph.forcedBounds.min.z * 1000f));
                    VInt2 vInt2 = new VInt2((int)(recastGraph.forcedBounds.max.x * 1000f), (int)(recastGraph.forcedBounds.max.z * 1000f));
                    min.Min(ref vInt);
                    max.Max(ref vInt2);
                }
                r.Init(min, max.x - min.x, max.y - min.y, inCellSize);
            }
            else
            {
                for (int j = 0; j < this.graphs.Length; j++)
                {
                    RecastGraph recastGraph2 = this.graphs[j] as RecastGraph;
                    if (recastGraph2 == null)
                    {
                        return(null);
                    }
                    recastGraph2.GetNodes(delegate(GraphNode node)
                    {
                        TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                        if (triangleMeshNode != null)
                        {
                            VInt2 xz  = triangleMeshNode.GetVertex(0).xz;
                            VInt2 xz2 = triangleMeshNode.GetVertex(1).xz;
                            VInt2 xz3 = triangleMeshNode.GetVertex(2).xz;
                            min.Min(ref xz);
                            min.Min(ref xz2);
                            min.Min(ref xz3);
                            max.Max(ref xz);
                            max.Max(ref xz2);
                            max.Max(ref xz3);
                        }
                        return(true);
                    });
                }
                r.Init(min, max.x - min.x, max.y - min.y, inCellSize);
            }
            for (int k = 0; k < this.graphs.Length; k++)
            {
                RecastGraph recastGraph3 = this.graphs[k] as RecastGraph;
                if (recastGraph3 != null)
                {
                    recastGraph3.GetNodes(delegate(GraphNode node)
                    {
                        TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                        if (triangleMeshNode != null)
                        {
                            VInt2 xz  = triangleMeshNode.GetVertex(0).xz;
                            VInt2 xz2 = triangleMeshNode.GetVertex(1).xz;
                            VInt2 xz3 = triangleMeshNode.GetVertex(2).xz;
                            r.AddTriangle(ref xz, ref xz2, ref xz3, triangleMeshNode);
                        }
                        return(true);
                    });
                }
            }
            return(r);
        }
Example #13
0
        // this function keeps the path generated away from the edge of the nav mesh, replacing funnel path points which are on a triangle vertex
        // with new points which are offset into the triangle away from the vertex
        private void PadFunnelPath(ref List <Vector3> funnelPath, ref List <GraphNode> path, Path _p)
        {
            ABPath      abPath          = _p as ABPath;
            const float SamePositionSqr = 0.001f * 0.001f;

            bool skipFirstPoint = false;
            bool skipLastPoint  = false;

            if (null != abPath && funnelPath.Count > 0)
            {   // don't want to mess with the start point
                if (VectorMath.SqrDistanceXZ(funnelPath[0], abPath.originalStartPoint) < SamePositionSqr)
                {
                    skipFirstPoint = true;
                }
                // don't want to mess with the end point
                if (VectorMath.SqrDistanceXZ(funnelPath[funnelPath.Count - 1], abPath.originalEndPoint) < SamePositionSqr)
                {
                    skipLastPoint = true;
                }
            }

            int startNode = 0;

            for (int point = 0; point < funnelPath.Count; ++point)
            {
                Vector3 funnelPoint = funnelPath[point];

                if (0 == point && skipFirstPoint)
                {
                    continue;
                }

                if (funnelPath.Count - 1 == point && skipLastPoint)
                {
                    continue;
                }

                bool hasPointBeenRemoved = false; // we will remove the funnel path point if it is found to be on a triangle vertex (it'll be replaced with offset points)

                ++startNode;
                // go over all points apart from the end node, as we don't want to add new path points in the end node as that node contains the target position
                for (int node = startNode; node < path.Count - 1; ++node)
                {
                    if (node < 0 || node >= path.Count)
                    {
                        continue;
                    }
                    TriangleMeshNode theNode = path[node] as TriangleMeshNode;

                    Vector3[] vertices = new Vector3[3] {
                        (Vector3)theNode.GetVertex(0), (Vector3)theNode.GetVertex(1), (Vector3)theNode.GetVertex(2)
                    };

                    for (int vert = 0; vert < 3; ++vert)
                    {
                        if (VectorMath.SqrDistanceXZ(funnelPoint, vertices[vert]) < SamePositionSqr) // the triangle has a vertex on the funnel path
                        {
                            bool isNodeOnTheLine = false;
                            // in this section we test if the triangle has an edge on the funnel path
                            if (point < funnelPath.Count - 1) // we need another point after point
                            {
                                Vector3 nextFunnelPoint  = funnelPath[point + 1];
                                Vector3 vertNotOnTheLine = new Vector3(); // if two of our triangle verts are on the funnel path, this is the other vert
                                if (VectorMath.SqrDistanceXZ(vertices[(vert + 2) % 3], nextFunnelPoint) < SamePositionSqr)
                                {
                                    isNodeOnTheLine  = true;
                                    vertNotOnTheLine = vertices[(vert + 1) % 3]; // other point is next
                                }
                                else if (VectorMath.SqrDistanceXZ(vertices[(vert + 1) % 3], nextFunnelPoint) < SamePositionSqr)
                                {
                                    isNodeOnTheLine  = true;
                                    vertNotOnTheLine = vertices[(vert + 2) % 3]; // other point is prev
                                }

                                if (isNodeOnTheLine)
                                {
                                    Vector3 pushAwayDirNorm = vertNotOnTheLine - VectorMath.ClosestPointOnLine(funnelPoint, nextFunnelPoint, vertNotOnTheLine);
                                    pushAwayDirNorm.y = 0f;
                                    pushAwayDirNorm.Normalize();

                                    // add a new point to the funnel path which is offset at a right angle from triangle line which is coincident with the funnel path
                                    Vector3 lineStart       = funnelPoint + ((nextFunnelPoint - funnelPoint) * 0.25f);
                                    Vector3 firstPointToAdd = lineStart + pushAwayDirNorm * obstaclePadding;
                                    float   maxLineLen      = CalculateMaxLineLengthXZ(lineStart, firstPointToAdd, nextFunnelPoint, vertNotOnTheLine, vertices[vert]);
                                    firstPointToAdd = lineStart + pushAwayDirNorm * maxLineLen;
                                    AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, firstPointToAdd);

                                    // add another point to the funnel path which is offset at a right angle from triangle line which is coincident with the funnel path
                                    lineStart = funnelPoint + ((nextFunnelPoint - funnelPoint) * 0.75f);
                                    Vector3 secondPointToAdd = lineStart + pushAwayDirNorm * obstaclePadding;
                                    maxLineLen       = CalculateMaxLineLengthXZ(lineStart, secondPointToAdd, nextFunnelPoint, vertNotOnTheLine, vertices[vert]);
                                    secondPointToAdd = lineStart + pushAwayDirNorm * maxLineLen;
                                    AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, secondPointToAdd);
                                }
                            }

                            // if the node did not have an edge on the funnel path, let's just offset from the single triangle vertex on the funnel path
                            if (!isNodeOnTheLine)
                            {
                                Vector3 toPrevVert = (vertices[(vert + 2) % 3] - vertices[vert]);
                                Vector3 toNextVert = (vertices[(vert + 1) % 3] - vertices[vert]);

                                // calculate a line between the two triangle edges and offset a point on that line
                                Vector3 newNavPoint = Vector3.Lerp(vertices[vert] + toPrevVert.normalized, vertices[vert] + toNextVert.normalized, 0.5f);
                                float   maxLength   = CalculateMaxLineLengthXZ(vertices[vert], newNavPoint, vertices[(vert + 1) % 3], vertices[(vert + 2) % 3]);
                                Vector3 dirNorm     = (newNavPoint - vertices[vert]);
                                dirNorm.y   = 0f;
                                newNavPoint = vertices[vert] + dirNorm.normalized * Mathf.Min(obstaclePadding, maxLength);
                                AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, newNavPoint);
                            }
                            startNode = node;
                            break;
                        }
                    }
                }
            }
        }
Example #14
0
 private RecastGraph.NavmeshTile CreateTile(Voxelize vox, VoxelMesh mesh, int x, int z)
 {
     if (mesh.tris == null)
     {
         throw new ArgumentNullException("mesh.tris");
     }
     if (mesh.verts == null)
     {
         throw new ArgumentNullException("mesh.verts");
     }
     RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile();
     navmeshTile.x = x;
     navmeshTile.z = z;
     navmeshTile.w = 1;
     navmeshTile.d = 1;
     navmeshTile.tris = mesh.tris;
     navmeshTile.verts = mesh.verts;
     navmeshTile.bbTree = new BBTree();
     if (navmeshTile.tris.Length % 3 != 0)
     {
         throw new ArgumentException("Indices array's length must be a multiple of 3 (mesh.tris)");
     }
     if (navmeshTile.verts.Length >= 4095)
     {
         throw new ArgumentException("Too many vertices per tile (more than " + 4095 + ").\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector");
     }
     Dictionary<Int3, int> dictionary = this.cachedInt3_int_dict;
     dictionary.Clear();
     int[] array = new int[navmeshTile.verts.Length];
     int num = 0;
     for (int i = 0; i < navmeshTile.verts.Length; i++)
     {
         if (!dictionary.ContainsKey(navmeshTile.verts[i]))
         {
             dictionary.Add(navmeshTile.verts[i], num);
             array[i] = num;
             navmeshTile.verts[num] = navmeshTile.verts[i];
             num++;
         }
         else
         {
             array[i] = dictionary[navmeshTile.verts[i]];
         }
     }
     for (int j = 0; j < navmeshTile.tris.Length; j++)
     {
         navmeshTile.tris[j] = array[navmeshTile.tris[j]];
     }
     Int3[] array2 = new Int3[num];
     for (int k = 0; k < num; k++)
     {
         array2[k] = navmeshTile.verts[k];
     }
     navmeshTile.verts = array2;
     TriangleMeshNode[] array3 = new TriangleMeshNode[navmeshTile.tris.Length / 3];
     navmeshTile.nodes = array3;
     int graphIndex = AstarPath.active.astarData.graphs.Length;
     TriangleMeshNode.SetNavmeshHolder(graphIndex, navmeshTile);
     int num2 = x + z * this.tileXCount;
     num2 <<= 12;
     for (int l = 0; l < array3.Length; l++)
     {
         TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active);
         array3[l] = triangleMeshNode;
         triangleMeshNode.GraphIndex = (uint)graphIndex;
         triangleMeshNode.v0 = (navmeshTile.tris[l * 3] | num2);
         triangleMeshNode.v1 = (navmeshTile.tris[l * 3 + 1] | num2);
         triangleMeshNode.v2 = (navmeshTile.tris[l * 3 + 2] | num2);
         if (!Polygon.IsClockwise(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)))
         {
             int v = triangleMeshNode.v0;
             triangleMeshNode.v0 = triangleMeshNode.v2;
             triangleMeshNode.v2 = v;
         }
         triangleMeshNode.Walkable = true;
         triangleMeshNode.Penalty = this.initialPenalty;
         triangleMeshNode.UpdatePositionFromVertices();
     }
     navmeshTile.bbTree.RebuildFrom(array3);
     this.CreateNodeConnections(navmeshTile.nodes);
     TriangleMeshNode.SetNavmeshHolder(graphIndex, null);
     return navmeshTile;
 }
Example #15
0
        /** Generate connections between the two tiles.
         * The tiles must be adjacent.
         */
        protected void ConnectTiles(NavmeshTile tile1, NavmeshTile tile2)
        {
            if (tile1 == null)
            {
                return;                           //throw new System.ArgumentNullException ("tile1");
            }
            if (tile2 == null)
            {
                return;                           //throw new System.ArgumentNullException ("tile2");
            }
            if (tile1.nodes == null)
            {
                throw new System.ArgumentException("tile1 does not contain any nodes");
            }
            if (tile2.nodes == null)
            {
                throw new System.ArgumentException("tile2 does not contain any nodes");
            }

            int t1x = Mathf.Clamp(tile2.x, tile1.x, tile1.x + tile1.w - 1);
            int t2x = Mathf.Clamp(tile1.x, tile2.x, tile2.x + tile2.w - 1);
            int t1z = Mathf.Clamp(tile2.z, tile1.z, tile1.z + tile1.d - 1);
            int t2z = Mathf.Clamp(tile1.z, tile2.z, tile2.z + tile2.d - 1);

            int coord, altcoord;
            int t1coord, t2coord;

            float tcs;

            if (t1x == t2x)
            {
                coord    = 2;
                altcoord = 0;
                t1coord  = t1z;
                t2coord  = t2z;
                tcs      = tileSizeZ * cellSize;
            }
            else if (t1z == t2z)
            {
                coord    = 0;
                altcoord = 2;
                t1coord  = t1x;
                t2coord  = t2x;
                tcs      = tileSizeX * cellSize;
            }
            else
            {
                throw new System.ArgumentException("Tiles are not adjacent (neither x or z coordinates match)");
            }

            if (Math.Abs(t1coord - t2coord) != 1)
            {
                EB.Debug.Log("{0} {1} {2} {3}\n{5} {6} {7} {8}\n{9} {10} {11} {12}", tile1.x, tile1.z, tile1.w, tile1.d,
                             tile2.x, tile2.z, tile2.w, tile2.d, t1x, t1z, t2x, t2z);
                throw new System.ArgumentException("Tiles are not adjacent (tile coordinates must differ by exactly 1. Got '" + t1coord + "' and '" + t2coord + "')");
            }

            //Midpoint between the two tiles
            int midpoint = (int)Math.Round((Math.Max(t1coord, t2coord) * tcs + forcedBounds.min[coord]) * Int3.Precision);

#if ASTARDEBUG
            Vector3 v1 = new Vector3(-100, 0, -100);
            Vector3 v2 = new Vector3(100, 0, 100);
            v1[coord] = midpoint * Int3.PrecisionFactor;
            v2[coord] = midpoint * Int3.PrecisionFactor;

            Debug.DrawLine(v1, v2, Color.magenta);
#endif

#if BNICKSON_UPDATED
            // different triangle link height tolerance based on whether we're linking tiles generated for random levels or not
            float heightToleranceSquared = generateFromInputMesh ? GameUtils.Square(heightZoneLinkTolerance) : GameUtils.Square(walkableClimb);
#endif
            TriangleMeshNode[] nodes1 = tile1.nodes;
            TriangleMeshNode[] nodes2 = tile2.nodes;

            //Find adjacent nodes on the border between the tiles
            for (int i = 0; i < nodes1.Length; i++)
            {
                TriangleMeshNode node = nodes1[i];
                int av = node.GetVertexCount();

                for (int a = 0; a < av; a++)
                {
                    Int3 ap1 = node.GetVertex(a);
                    Int3 ap2 = node.GetVertex((a + 1) % av);
#if BNICKSON_UPDATED
                    if (ap1[coord] == midpoint && ap2[coord] == midpoint)                     // this could be given a little bit of tolerance
#else
                    if (Math.Abs(ap1[coord] - midpoint) < 2 && Math.Abs(ap2[coord] - midpoint) < 2)
#endif
                    {
#if ASTARDEBUG
                        Debug.DrawLine((Vector3)ap1, (Vector3)ap2, Color.red);
#endif

                        int minalt = Math.Min(ap1[altcoord], ap2[altcoord]);
                        int maxalt = Math.Max(ap1[altcoord], ap2[altcoord]);

                        //Degenerate edge
                        if (minalt == maxalt)
                        {
                            continue;
                        }

                        for (int j = 0; j < nodes2.Length; j++)
                        {
                            TriangleMeshNode other = nodes2[j];
                            int bv = other.GetVertexCount();
                            for (int b = 0; b < bv; b++)
                            {
                                Int3 bp1 = other.GetVertex(b);
                                Int3 bp2 = other.GetVertex((b + 1) % av);
#if BNICKSON_UPDATED
                                if (bp1[coord] == midpoint && bp2[coord] == midpoint)                                 // this could be given a little bit of tolerance
#else
                                if (Math.Abs(bp1[coord] - midpoint) < 2 && Math.Abs(bp2[coord] - midpoint) < 2)
#endif
                                {
                                    int minalt2 = Math.Min(bp1[altcoord], bp2[altcoord]);
                                    int maxalt2 = Math.Max(bp1[altcoord], bp2[altcoord]);

                                    //Degenerate edge
                                    if (minalt2 == maxalt2)
                                    {
                                        continue;
                                    }

                                    if (maxalt > minalt2 && minalt < maxalt2)
                                    {
                                        //Adjacent

                                        //Test shortest distance between the segments (first test if they are equal since that is much faster)
                                        if ((ap1 == bp1 && ap2 == bp2) || (ap1 == bp2 && ap2 == bp1) ||
#if BNICKSON_UPDATED
                                            VectorMath.SqrDistanceSegmentSegment((Vector3)ap1, (Vector3)ap2, (Vector3)bp1, (Vector3)bp2) < heightToleranceSquared)                                             // different height tolerances based on generating from input mesh or not
#else
                                            VectorMath.SqrDistanceSegmentSegment((Vector3)ap1, (Vector3)ap2, (Vector3)bp1, (Vector3)bp2) < walkableClimb * walkableClimb)
#endif
                                        {
                                            uint cost = (uint)(node.position - other.position).costMagnitude;

                                            node.AddConnection(other, cost);
                                            other.AddConnection(node, cost);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #16
0
        protected NavmeshTile CreateTile(int[] tris, Int3[] verts, int x, int z)
        {
#if BNICKSON_UPDATED
            if (tris == null)
            {
                throw new System.ArgumentNullException("The mesh must be valid. tris is null.");
            }
            if (verts == null)
            {
                throw new System.ArgumentNullException("The mesh must be valid. verts is null.");
            }

            //Create a new navmesh tile and assign its settings
            var tile = new NavmeshTile();

            tile.x      = x;
            tile.z      = z;
            tile.w      = 1;
            tile.d      = 1;
            tile.tris   = tris;
            tile.verts  = verts;
            tile.bbTree = new BBTree();
#endif

            if (tile.tris.Length % 3 != 0)
            {
                throw new System.ArgumentException("Indices array's length must be a multiple of 3 (mesh.tris)");
            }

            if (tile.verts.Length >= VertexIndexMask)
            {
                throw new System.ArgumentException("Too many vertices per tile (more than " + VertexIndexMask + ")." +
                                                   "\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector");
            }

            //Dictionary<Int3, int> firstVerts = new Dictionary<Int3, int> ();
            Dictionary <Int3, int> firstVerts = cachedInt3_int_dict;
            firstVerts.Clear();

            var compressedPointers = new int[tile.verts.Length];

            int count = 0;
            for (int i = 0; i < tile.verts.Length; i++)
            {
                try
                {
                    firstVerts.Add(tile.verts[i], count);
                    compressedPointers[i] = count;
                    tile.verts[count]     = tile.verts[i];
                    count++;
                }
                catch
                {
                    //There are some cases, rare but still there, that vertices are identical
                    compressedPointers[i] = firstVerts[tile.verts[i]];
                }
            }

            for (int i = 0; i < tile.tris.Length; i++)
            {
                tile.tris[i] = compressedPointers[tile.tris[i]];
            }

            var compressed = new Int3[count];
            for (int i = 0; i < count; i++)
            {
                compressed[i] = tile.verts[i];
            }

            tile.verts = compressed;

            var nodes = new TriangleMeshNode[tile.tris.Length / 3];
            tile.nodes = nodes;

            //Here we are faking a new graph
            //The tile is not added to any graphs yet, but to get the position querys from the nodes
            //to work correctly (not throw exceptions because the tile is not calculated) we fake a new graph
            //and direct the position queries directly to the tile
            int graphIndex = AstarPath.active.astarData.graphs.Length;

            TriangleMeshNode.SetNavmeshHolder(graphIndex, tile);

            //This index will be ORed to the triangle indices
            int tileIndex = x + z * tileXCount;
            tileIndex <<= TileIndexOffset;

            //Create nodes and assign triangle indices
            for (int i = 0; i < nodes.Length; i++)
            {
                var node = new TriangleMeshNode(active);
                nodes[i]        = node;
                node.GraphIndex = (uint)graphIndex;
                node.v0         = tile.tris[i * 3 + 0] | tileIndex;
                node.v1         = tile.tris[i * 3 + 1] | tileIndex;
                node.v2         = tile.tris[i * 3 + 2] | tileIndex;

                //Degenerate triangles might occur, but they will not cause any large troubles anymore
                //if (Polygon.IsColinear (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
                //	Debug.Log ("COLINEAR!!!!!!");
                //}

                //Make sure the triangle is clockwise
                if (!VectorMath.IsClockwiseXZ(node.GetVertex(0), node.GetVertex(1), node.GetVertex(2)))
                {
                    int tmp = node.v0;
                    node.v0 = node.v2;
                    node.v2 = tmp;
                }

                node.Walkable = true;
                node.Penalty  = initialPenalty;
                node.UpdatePositionFromVertices();
                tile.bbTree.Insert(node);
            }

            CreateNodeConnections(tile.nodes);

            //Remove the fake graph
            TriangleMeshNode.SetNavmeshHolder(graphIndex, null);

            return(tile);
        }
Example #17
0
        // Token: 0x060025FE RID: 9726 RVA: 0x001A6C10 File Offset: 0x001A4E10
        public bool GetPortal(GraphNode toNode, List <Vector3> left, List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (backwards || toNode.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode triangleMeshNode = toNode as TriangleMeshNode;
            int num = this.SharedEdge(triangleMeshNode);

            if (num == 255)
            {
                return(false);
            }
            if (num == -1)
            {
                for (int i = 0; i < this.connections.Length; i++)
                {
                    if (this.connections[i].node.GraphIndex != base.GraphIndex)
                    {
                        NodeLink3Node nodeLink3Node = this.connections[i].node as NodeLink3Node;
                        if (nodeLink3Node != null && nodeLink3Node.GetOther(this) == triangleMeshNode)
                        {
                            nodeLink3Node.GetPortal(triangleMeshNode, left, right, false);
                            return(true);
                        }
                    }
                }
                return(false);
            }
            aIndex = num;
            bIndex = (num + 1) % this.GetVertexCount();
            Int3 vertex  = this.GetVertex(num);
            Int3 vertex2 = this.GetVertex((num + 1) % this.GetVertexCount());
            int  num2    = this.GetVertexIndex(0) >> 12 & 524287;
            int  num3    = triangleMeshNode.GetVertexIndex(0) >> 12 & 524287;

            if (num2 != num3)
            {
                INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);
                int            num4;
                int            num5;
                navmeshHolder.GetTileCoordinates(num2, out num4, out num5);
                int num6;
                int num7;
                navmeshHolder.GetTileCoordinates(num3, out num6, out num7);
                int i2;
                if (Math.Abs(num4 - num6) == 1)
                {
                    i2 = 2;
                }
                else
                {
                    if (Math.Abs(num5 - num7) != 1)
                    {
                        return(false);
                    }
                    i2 = 0;
                }
                int num8 = triangleMeshNode.SharedEdge(this);
                if (num8 == 255)
                {
                    throw new Exception("Connection used edge in one direction, but not in the other direction. Has the wrong overload of AddConnection been used?");
                }
                if (num8 != -1)
                {
                    int  num9    = Math.Min(vertex[i2], vertex2[i2]);
                    int  num10   = Math.Max(vertex[i2], vertex2[i2]);
                    Int3 vertex3 = triangleMeshNode.GetVertex(num8);
                    Int3 vertex4 = triangleMeshNode.GetVertex((num8 + 1) % triangleMeshNode.GetVertexCount());
                    num9  = Math.Max(num9, Math.Min(vertex3[i2], vertex4[i2]));
                    num10 = Math.Min(num10, Math.Max(vertex3[i2], vertex4[i2]));
                    if (vertex[i2] < vertex2[i2])
                    {
                        vertex[i2]  = num9;
                        vertex2[i2] = num10;
                    }
                    else
                    {
                        vertex[i2]  = num10;
                        vertex2[i2] = num9;
                    }
                }
            }
            if (left != null)
            {
                left.Add((Vector3)vertex);
                right.Add((Vector3)vertex2);
            }
            return(true);
        }
Example #18
0
		public void ReplaceTile (int x, int z, int w, int d, Int3[] verts, int[] tris, bool worldSpace) {
			
			if(x + w > tileXCount || z+d > tileZCount || x < 0 || z < 0) {
				throw new System.ArgumentException ("Tile is placed at an out of bounds position or extends out of the graph bounds ("+x+", " + z + " [" + w + ", " + d+ "] " + tileXCount + " " + tileZCount + ")");
			}
			
			if (w < 1 || d < 1) throw new System.ArgumentException ("width and depth must be greater or equal to 1");
			
			//Remove previous tiles
			for (int cz=z; cz < z+d;cz++) {
				for (int cx=x; cx < x+w;cx++) {
					
					NavmeshTile otile = tiles[cx + cz*tileXCount];
					if (otile == null) continue;
					
					//Remove old tile connections
					RemoveConnectionsFromTile (otile);
					
					for (int i=0;i<otile.nodes.Length;i++) {
						otile.nodes[i].Destroy();
					}
					
					for (int qz=otile.z; qz < otile.z+otile.d;qz++) {
						for (int qx=otile.x; qx < otile.x+otile.w;qx++) {
							NavmeshTile qtile = tiles[qx + qz*tileXCount];
							if (qtile == null || qtile != otile) throw new System.Exception("This should not happen");
							
							if (qz < z || qz >= z+d || qx < x || qx >= x+w) {
								//if out of this tile's bounds, replace with empty tile
								tiles[qx + qz*tileXCount] = NewEmptyTile(qx,qz);
								
								if (batchTileUpdate) {
									batchUpdatedTiles.Add (qx + qz*tileXCount);
								}
							} else {
								//Will be replaced by the new tile
								tiles[qx + qz*tileXCount] = null;
							}
						}
					}
				}
			}
			
			//Create a new navmesh tile and assign its settings
			NavmeshTile tile = new NavmeshTile();
			
			tile.x = x;
			tile.z = z;
			tile.w = w;
			tile.d = d;
			tile.tris = tris;
			tile.verts = verts;
			tile.bbTree = new BBTree(tile);
			
			if (tile.tris.Length % 3 != 0) throw new System.ArgumentException ("Triangle array's length must be a multiple of 3 (tris)");
			
			if (tile.verts.Length > 0xFFFF) throw new System.ArgumentException ("Too many vertices per tile (more than 65535)");
			
			if (!worldSpace) {
				if (!Mathf.Approximately (x*tileSizeX*cellSize*Int3.FloatPrecision, (float)System.Math.Round(x*tileSizeX*cellSize*Int3.FloatPrecision))) Debug.LogWarning ("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize");
				if (!Mathf.Approximately (z*tileSizeZ*cellSize*Int3.FloatPrecision, (float)System.Math.Round(z*tileSizeZ*cellSize*Int3.FloatPrecision))) Debug.LogWarning ("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize");
			
				Int3 offset = (Int3)(new Vector3((x * tileSizeX * cellSize),0,(z * tileSizeZ * cellSize)) + forcedBounds.min);
				
				for (int i=0;i<verts.Length;i++) {
					verts[i] += offset;
				}
				
			}
			
			TriangleMeshNode[] nodes = new TriangleMeshNode[tile.tris.Length/3];
			tile.nodes = nodes;
			
			//Here we are faking a new graph
			//The tile is not added to any graphs yet, but to get the position querys from the nodes
			//to work correctly (not throw exceptions because the tile is not calculated) we fake a new graph
			//and direct the position queries directly to the tile
			int graphIndex = AstarPath.active.astarData.graphs.Length;
			
			TriangleMeshNode.SetNavmeshHolder (graphIndex, tile);
			
			//This index will be ORed to the triangle indices
			int tileIndex = x + z*tileXCount;
			tileIndex <<= TileIndexOffset;
			
			//Create nodes and assign triangle indices
			for (int i=0;i<nodes.Length;i++) {
				TriangleMeshNode node = new TriangleMeshNode(active);
				nodes[i] = node;
				node.GraphIndex = (uint)graphIndex;
				node.v0 = tile.tris[i*3+0] | tileIndex;
				node.v1 = tile.tris[i*3+1] | tileIndex;
				node.v2 = tile.tris[i*3+2] | tileIndex;
				
				//Degenerate triangles might ocurr, but they will not cause any large troubles anymore
				//if (Polygon.IsColinear (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
				//	Debug.Log ("COLINEAR!!!!!!");
				//}
				
				//Make sure the triangle is clockwise
				if (!Polygon.IsClockwise (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
					int tmp = node.v0;
					node.v0 = node.v2;
					node.v2 = tmp;
				}
				
				node.Walkable = true;
				node.Penalty = initialPenalty;
				node.UpdatePositionFromVertices();
				
				tile.bbTree.Insert (node);
			}
			
			CreateNodeConnections (tile.nodes);
			
			//Set tile
			for (int cz=z; cz < z+d;cz++) {
				for (int cx=x; cx < x+w;cx++) {
					tiles[cx + cz*tileXCount] = tile;
				}
			}
			
			if (batchTileUpdate) {
				batchUpdatedTiles.Add (x + z*tileXCount);
			} else {
				ConnectTileWithNeighbours(tile);
				/*if (x > 0) ConnectTiles (tiles[(x-1) + z*tileXCount], tile);
				if (z > 0) ConnectTiles (tiles[x + (z-1)*tileXCount], tile);
				if (x < tileXCount-1) ConnectTiles (tiles[(x+1) + z*tileXCount], tile);
				if (z < tileZCount-1) ConnectTiles (tiles[x + (z+1)*tileXCount], tile);*/
			}
			
			//Remove the fake graph
			TriangleMeshNode.SetNavmeshHolder (graphIndex, null);
			
			//Real graph index
			//TODO, could this step be changed for this function, is a fake index required?
			graphIndex = AstarPath.active.astarData.GetGraphIndex (this);
			
			for (int i=0;i<nodes.Length;i++) nodes[i].GraphIndex = (uint)graphIndex;			
			
		}
Example #19
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            Bounds  bounds = o.bounds;
            Rect    r      = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);
            IntRect r2     = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f));
            Int3    a      = new Int3(r2.xmin, 0, r2.ymin);
            Int3    b      = new Int3(r2.xmin, 0, r2.ymax);
            Int3    c      = new Int3(r2.xmax, 0, r2.ymin);
            Int3    d      = new Int3(r2.xmax, 0, r2.ymax);

            graph.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                bool flag = false;
                int num   = 0;
                int num2  = 0;
                int num3  = 0;
                int num4  = 0;
                for (int i = 0; i < 3; i++)
                {
                    Int3 vertex    = triangleMeshNode.GetVertex(i);
                    Vector3 vector = (Vector3)vertex;
                    if (r2.Contains(vertex.x, vertex.z))
                    {
                        flag = true;
                        break;
                    }
                    if (vector.x < r.xMin)
                    {
                        num++;
                    }
                    if (vector.x > r.xMax)
                    {
                        num2++;
                    }
                    if (vector.z < r.yMin)
                    {
                        num3++;
                    }
                    if (vector.z > r.yMax)
                    {
                        num4++;
                    }
                }
                if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3))
                {
                    return(true);
                }
                for (int j = 0; j < 3; j++)
                {
                    int i2       = (j <= 1) ? (j + 1) : 0;
                    Int3 vertex2 = triangleMeshNode.GetVertex(j);
                    Int3 vertex3 = triangleMeshNode.GetVertex(i2);
                    if (Polygon.Intersects(a, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(a, c, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(c, d, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(d, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                }
                if (triangleMeshNode.ContainsPoint(a) || triangleMeshNode.ContainsPoint(b) || triangleMeshNode.ContainsPoint(c) || triangleMeshNode.ContainsPoint(d))
                {
                    flag = true;
                }
                if (!flag)
                {
                    return(true);
                }
                o.WillUpdateNode(triangleMeshNode);
                o.Apply(triangleMeshNode);
                return(true);
            });
        }
        /** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
         * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
         * For other node types, only the positions of the nodes will be used.
         *
         * clearanceRadius will be reduced if no valid points can be found.
         */
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0)
        {
            if (nodes == null)
            {
                throw new System.ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("no nodes passed");
            }

            System.Random rnd = new System.Random();

            List <Vector3> pts = Pathfinding.Util.ListPool <Vector3> .Claim(count);

            // Square
            clearanceRadius *= clearanceRadius;

            if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode)
            {
                //Assume all nodes are triangle nodes or grid nodes

                List <float> accs = Pathfinding.Util.ListPool <float> .Claim(nodes.Count);

                float tot = 0;

                for (int i = 0; i < nodes.Count; i++)
                {
                    TriangleMeshNode tnode = nodes[i] as TriangleMeshNode;
                    if (tnode != null)
                    {
                        float a = System.Math.Abs(Polygon.TriangleArea(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
                        tot += a;
                        accs.Add(tot);
                    }
                    else
                    {
                        GridNode gnode = nodes[i] as GridNode;

                        if (gnode != null)
                        {
                            GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);
                            float     a  = gg.nodeSize * gg.nodeSize;
                            tot += a;
                            accs.Add(tot);
                        }
                        else
                        {
                            accs.Add(tot);
                        }
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    //Pick point
                    int  testCount = 0;
                    int  testLimit = 10;
                    bool worked    = false;

                    while (!worked)
                    {
                        worked = true;

                        //If no valid points can be found, progressively lower the clearance radius until such a point is found
                        if (testCount >= testLimit)
                        {
                            clearanceRadius *= 0.8f;
                            testLimit       += 10;
                            if (testLimit > 100)
                            {
                                clearanceRadius = 0;
                            }
                        }

                        float tg = (float)rnd.NextDouble() * tot;
                        int   v  = accs.BinarySearch(tg);
                        if (v < 0)
                        {
                            v = ~v;
                        }

                        if (v >= nodes.Count)
                        {
                            // This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
                            worked = false;
                            continue;
                        }

                        TriangleMeshNode node = nodes[v] as TriangleMeshNode;

                        Vector3 p;

                        if (node != null)
                        {
                            // Find a random point inside the triangle
                            float v1;
                            float v2;
                            do
                            {
                                v1 = (float)rnd.NextDouble();
                                v2 = (float)rnd.NextDouble();
                            } while (v1 + v2 > 1);

                            p = ((Vector3)(node.GetVertex(1) - node.GetVertex(0))) * v1 + ((Vector3)(node.GetVertex(2) - node.GetVertex(0))) * v2 + (Vector3)node.GetVertex(0);
                        }
                        else
                        {
                            GridNode gnode = nodes[v] as GridNode;

                            if (gnode != null)
                            {
                                GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);

                                float v1 = (float)rnd.NextDouble();
                                float v2 = (float)rnd.NextDouble();
                                p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
                            }
                            else
                            {
                                //Point nodes have no area, so we break directly instead
                                pts.Add((Vector3)nodes[v].position);
                                break;
                            }
                        }

                        // Test if it is some distance away from the other points
                        if (clearanceRadius > 0)
                        {
                            for (int j = 0; j < pts.Count; j++)
                            {
                                if ((pts[j] - p).sqrMagnitude < clearanceRadius)
                                {
                                    worked = false;
                                    break;
                                }
                            }
                        }

                        if (worked)
                        {
                            pts.Add(p);
                            break;
                        }
                        else
                        {
                            testCount++;
                        }
                    }
                }

                Pathfinding.Util.ListPool <float> .Release(accs);
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    pts.Add((Vector3)nodes[rnd.Next(nodes.Count)].position);
                }
            }

            return(pts);
        }
Example #21
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            //System.DateTime startTime = System.DateTime.UtcNow;

            Bounds bounds = o.bounds;

            Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            IntRect r2 = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.FloorToInt(bounds.max.x * Int3.Precision),
                Mathf.FloorToInt(bounds.max.z * Int3.Precision)
                );

            Int3 a = new Int3(r2.xmin, 0, r2.ymin);
            Int3 b = new Int3(r2.xmin, 0, r2.ymax);
            Int3 c = new Int3(r2.xmax, 0, r2.ymin);
            Int3 d = new Int3(r2.xmax, 0, r2.ymax);

            Int3 ia = (Int3)a;
            Int3 ib = (Int3)b;
            Int3 ic = (Int3)c;
            Int3 id = (Int3)d;


            //for (int i=0;i<nodes.Length;i++) {
            graph.GetNodes(delegate(GraphNode _node) {
                TriangleMeshNode node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                for (int v = 0; v < 3; v++)
                {
                    Int3 p       = node.GetVertex(v);
                    Vector3 vert = (Vector3)p;
                    //Vector2 vert2D = new Vector2 (vert.x,vert.z);

                    if (r2.Contains(p.x, p.z))
                    {
                        //Debug.DrawRay (vert,Vector3.up*10,Color.yellow);
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }
                }
                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        return(true);
                    }
                }

                //Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow);
                //Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow);
                //Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow);

                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertex(v);
                    Int3 vert2 = node.GetVertex(v2);

                    if (Polygon.Intersects(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }



                if (node.ContainsPoint(ia) || node.ContainsPoint(ib) || node.ContainsPoint(ic) || node.ContainsPoint(id))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return(true);
                }

                o.WillUpdateNode(node);
                o.Apply(node);

                /*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue);
                 * Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue);
                 * Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue);
                 * Debug.Break ();*/
                return(true);
            });

            //System.DateTime endTime = System.DateTime.UtcNow;
            //float theTime = (endTime-startTime).Ticks*0.0001F;
            //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms");
        }
        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)
                    {
#if !ASTAR_NO_POINT_GRAPH
                        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);
                            }
                        }
#endif
                    }
                }

                //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)
                        {
#if !ASTAR_NO_POINT_GRAPH
                            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);
                                }
                            }
#endif
                        }
                    }
                    return(false);
                }
            }

            return(true);
        }
Example #23
0
 public void ReplaceTile(int x, int z, int w, int d, Int3[] verts, int[] tris, bool worldSpace)
 {
     if (x + w > this.tileXCount || z + d > this.tileZCount || x < 0 || z < 0)
     {
         throw new ArgumentException(string.Concat(new object[]
         {
             "Tile is placed at an out of bounds position or extends out of the graph bounds (",
             x,
             ", ",
             z,
             " [",
             w,
             ", ",
             d,
             "] ",
             this.tileXCount,
             " ",
             this.tileZCount,
             ")"
         }));
     }
     if (w < 1 || d < 1)
     {
         throw new ArgumentException(string.Concat(new object[]
         {
             "width and depth must be greater or equal to 1. Was ",
             w,
             ", ",
             d
         }));
     }
     for (int i = z; i < z + d; i++)
     {
         for (int j = x; j < x + w; j++)
         {
             RecastGraph.NavmeshTile navmeshTile = this.tiles[j + i * this.tileXCount];
             if (navmeshTile != null)
             {
                 this.RemoveConnectionsFromTile(navmeshTile);
                 for (int k = 0; k < navmeshTile.nodes.Length; k++)
                 {
                     navmeshTile.nodes[k].Destroy();
                 }
                 for (int l = navmeshTile.z; l < navmeshTile.z + navmeshTile.d; l++)
                 {
                     for (int m = navmeshTile.x; m < navmeshTile.x + navmeshTile.w; m++)
                     {
                         RecastGraph.NavmeshTile navmeshTile2 = this.tiles[m + l * this.tileXCount];
                         if (navmeshTile2 == null || navmeshTile2 != navmeshTile)
                         {
                             throw new Exception("This should not happen");
                         }
                         if (l < z || l >= z + d || m < x || m >= x + w)
                         {
                             this.tiles[m + l * this.tileXCount] = RecastGraph.NewEmptyTile(m, l);
                             if (this.batchTileUpdate)
                             {
                                 this.batchUpdatedTiles.Add(m + l * this.tileXCount);
                             }
                         }
                         else
                         {
                             this.tiles[m + l * this.tileXCount] = null;
                         }
                     }
                 }
             }
         }
     }
     RecastGraph.NavmeshTile navmeshTile3 = new RecastGraph.NavmeshTile();
     navmeshTile3.x = x;
     navmeshTile3.z = z;
     navmeshTile3.w = w;
     navmeshTile3.d = d;
     navmeshTile3.tris = tris;
     navmeshTile3.verts = verts;
     navmeshTile3.bbTree = new BBTree();
     if (navmeshTile3.tris.Length % 3 != 0)
     {
         throw new ArgumentException("Triangle array's length must be a multiple of 3 (tris)");
     }
     if (navmeshTile3.verts.Length > 65535)
     {
         throw new ArgumentException("Too many vertices per tile (more than 65535)");
     }
     if (!worldSpace)
     {
         if (!Mathf.Approximately((float)(x * this.tileSizeX) * this.cellSize * 1000f, (float)Math.Round((double)((float)(x * this.tileSizeX) * this.cellSize * 1000f))))
         {
             UnityEngine.Debug.LogWarning("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize");
         }
         if (!Mathf.Approximately((float)(z * this.tileSizeZ) * this.cellSize * 1000f, (float)Math.Round((double)((float)(z * this.tileSizeZ) * this.cellSize * 1000f))))
         {
             UnityEngine.Debug.LogWarning("Possible numerical imprecision. Consider adjusting tileSize and/or cellSize");
         }
         Int3 rhs = (Int3)(new Vector3((float)(x * this.tileSizeX) * this.cellSize, 0f, (float)(z * this.tileSizeZ) * this.cellSize) + this.forcedBounds.min);
         for (int n = 0; n < verts.Length; n++)
         {
             verts[n] += rhs;
         }
     }
     TriangleMeshNode[] array = new TriangleMeshNode[navmeshTile3.tris.Length / 3];
     navmeshTile3.nodes = array;
     int graphIndex = AstarPath.active.astarData.graphs.Length;
     TriangleMeshNode.SetNavmeshHolder(graphIndex, navmeshTile3);
     int num = x + z * this.tileXCount;
     num <<= 12;
     for (int num2 = 0; num2 < array.Length; num2++)
     {
         TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active);
         array[num2] = triangleMeshNode;
         triangleMeshNode.GraphIndex = (uint)graphIndex;
         triangleMeshNode.v0 = (navmeshTile3.tris[num2 * 3] | num);
         triangleMeshNode.v1 = (navmeshTile3.tris[num2 * 3 + 1] | num);
         triangleMeshNode.v2 = (navmeshTile3.tris[num2 * 3 + 2] | num);
         if (!Polygon.IsClockwise(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)))
         {
             int v = triangleMeshNode.v0;
             triangleMeshNode.v0 = triangleMeshNode.v2;
             triangleMeshNode.v2 = v;
         }
         triangleMeshNode.Walkable = true;
         triangleMeshNode.Penalty = this.initialPenalty;
         triangleMeshNode.UpdatePositionFromVertices();
     }
     navmeshTile3.bbTree.RebuildFrom(array);
     this.CreateNodeConnections(navmeshTile3.nodes);
     for (int num3 = z; num3 < z + d; num3++)
     {
         for (int num4 = x; num4 < x + w; num4++)
         {
             this.tiles[num4 + num3 * this.tileXCount] = navmeshTile3;
         }
     }
     if (this.batchTileUpdate)
     {
         this.batchUpdatedTiles.Add(x + z * this.tileXCount);
     }
     else
     {
         this.ConnectTileWithNeighbours(navmeshTile3);
     }
     TriangleMeshNode.SetNavmeshHolder(graphIndex, null);
     graphIndex = AstarPath.active.astarData.GetGraphIndex(this);
     for (int num5 = 0; num5 < array.Length; num5++)
     {
         array[num5].GraphIndex = (uint)graphIndex;
     }
 }
Example #24
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);
        }
Example #25
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            Bounds  bounds = o.bounds;
            Rect    rect   = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);
            IntRect irect  = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f));
            Int3    a      = new Int3(irect.xmin, 0, irect.ymin);
            Int3    b      = new Int3(irect.xmin, 0, irect.ymax);
            Int3    c      = new Int3(irect.xmax, 0, irect.ymin);
            Int3    d      = new Int3(irect.xmax, 0, irect.ymax);
            int     ymin   = ((Int3)bounds.min).y;
            int     ymax   = ((Int3)bounds.max).y;

            graph.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                bool flag = false;
                int num   = 0;
                int num2  = 0;
                int num3  = 0;
                int num4  = 0;
                for (int i = 0; i < 3; i++)
                {
                    Int3 vertex    = triangleMeshNode.GetVertex(i);
                    Vector3 vector = (Vector3)vertex;
                    if (irect.Contains(vertex.x, vertex.z))
                    {
                        flag = true;
                        break;
                    }
                    if (vector.x < rect.xMin)
                    {
                        num++;
                    }
                    if (vector.x > rect.xMax)
                    {
                        num2++;
                    }
                    if (vector.z < rect.yMin)
                    {
                        num3++;
                    }
                    if (vector.z > rect.yMax)
                    {
                        num4++;
                    }
                }
                if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3))
                {
                    return;
                }
                for (int j = 0; j < 3; j++)
                {
                    int i2       = (j > 1) ? 0 : (j + 1);
                    Int3 vertex2 = triangleMeshNode.GetVertex(j);
                    Int3 vertex3 = triangleMeshNode.GetVertex(i2);
                    if (VectorMath.SegmentsIntersectXZ(a, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(a, c, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(c, d, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(d, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag || triangleMeshNode.ContainsPoint(a) || triangleMeshNode.ContainsPoint(b) || triangleMeshNode.ContainsPoint(c) || triangleMeshNode.ContainsPoint(d))
                {
                    flag = true;
                }
                if (!flag)
                {
                    return;
                }
                int num5 = 0;
                int num6 = 0;
                for (int k = 0; k < 3; k++)
                {
                    Int3 vertex4 = triangleMeshNode.GetVertex(k);
                    if (vertex4.y < ymin)
                    {
                        num6++;
                    }
                    if (vertex4.y > ymax)
                    {
                        num5++;
                    }
                }
                if (num6 == 3 || num5 == 3)
                {
                    return;
                }
                o.WillUpdateNode(triangleMeshNode);
                o.Apply(triangleMeshNode);
            });
        }
Example #26
0
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0f)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new ArgumentException("no nodes passed");
            }
            Random         random = new Random();
            List <Vector3> list   = ListPool <Vector3> .Claim(count);

            clearanceRadius *= clearanceRadius;
            if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode)
            {
                List <float> list2 = ListPool <float> .Claim(nodes.Count);

                float num = 0f;
                for (int i = 0; i < nodes.Count; i++)
                {
                    TriangleMeshNode triangleMeshNode = nodes[i] as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        float num2 = (float)Math.Abs(Polygon.TriangleArea(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)));
                        num += num2;
                        list2.Add(num);
                    }
                    else
                    {
                        GridNode gridNode = nodes[i] as GridNode;
                        if (gridNode != null)
                        {
                            GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);
                            float     num3      = gridGraph.nodeSize * gridGraph.nodeSize;
                            num += num3;
                            list2.Add(num);
                        }
                        else
                        {
                            list2.Add(num);
                        }
                    }
                }
                for (int j = 0; j < count; j++)
                {
                    int  num4 = 0;
                    int  num5 = 10;
                    bool flag = false;
                    while (!flag)
                    {
                        flag = true;
                        if (num4 >= num5)
                        {
                            clearanceRadius *= 0.8f;
                            num5            += 10;
                            if (num5 > 100)
                            {
                                clearanceRadius = 0f;
                            }
                        }
                        float item = (float)random.NextDouble() * num;
                        int   num6 = list2.BinarySearch(item);
                        if (num6 < 0)
                        {
                            num6 = ~num6;
                        }
                        if (num6 >= nodes.Count)
                        {
                            flag = false;
                        }
                        else
                        {
                            TriangleMeshNode triangleMeshNode2 = nodes[num6] as TriangleMeshNode;
                            Vector3          vector;
                            if (triangleMeshNode2 != null)
                            {
                                float num7;
                                float num8;
                                do
                                {
                                    num7 = (float)random.NextDouble();
                                    num8 = (float)random.NextDouble();
                                }while (num7 + num8 > 1f);
                                vector = (Vector3)(triangleMeshNode2.GetVertex(1) - triangleMeshNode2.GetVertex(0)) * num7 + (Vector3)(triangleMeshNode2.GetVertex(2) - triangleMeshNode2.GetVertex(0)) * num8 + (Vector3)triangleMeshNode2.GetVertex(0);
                            }
                            else
                            {
                                GridNode gridNode2 = nodes[num6] as GridNode;
                                if (gridNode2 == null)
                                {
                                    list.Add((Vector3)nodes[num6].position);
                                    break;
                                }
                                GridGraph gridGraph2 = GridNode.GetGridGraph(gridNode2.GraphIndex);
                                float     num9       = (float)random.NextDouble();
                                float     num10      = (float)random.NextDouble();
                                vector = (Vector3)gridNode2.position + new Vector3(num9 - 0.5f, 0f, num10 - 0.5f) * gridGraph2.nodeSize;
                            }
                            if (clearanceRadius > 0f)
                            {
                                for (int k = 0; k < list.Count; k++)
                                {
                                    if ((list[k] - vector).sqrMagnitude < clearanceRadius)
                                    {
                                        flag = false;
                                        break;
                                    }
                                }
                            }
                            if (flag)
                            {
                                list.Add(vector);
                                break;
                            }
                            num4++;
                        }
                    }
                }
                ListPool <float> .Release(list2);
            }
            else
            {
                for (int l = 0; l < count; l++)
                {
                    list.Add((Vector3)nodes[random.Next(nodes.Count)].position);
                }
            }
            return(list);
        }
Example #27
0
        public bool GetPortal(GraphNode _other, List <Vector3> left, List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode triangleMeshNode = _other as TriangleMeshNode;
            int num  = this.GetVertexIndex(0) >> 12 & 524287;
            int num2 = triangleMeshNode.GetVertexIndex(0) >> 12 & 524287;

            if (num != num2 && TriangleMeshNode.GetNavmeshHolder(base.GraphIndex) is RecastGraph)
            {
                for (int i = 0; i < this.connections.Length; i++)
                {
                    if (this.connections[i].GraphIndex != base.GraphIndex)
                    {
                        NodeLink3Node nodeLink3Node = this.connections[i] as NodeLink3Node;
                        if (nodeLink3Node != null && nodeLink3Node.GetOther(this) == triangleMeshNode && left != null)
                        {
                            nodeLink3Node.GetPortal(triangleMeshNode, left, right, false);
                            return(true);
                        }
                    }
                }
                INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);
                int            num3;
                int            num4;
                navmeshHolder.GetTileCoordinates(num, out num3, out num4);
                int num5;
                int num6;
                navmeshHolder.GetTileCoordinates(num2, out num5, out num6);
                int num7;
                if (Math.Abs(num3 - num5) == 1)
                {
                    num7 = 0;
                }
                else
                {
                    if (Math.Abs(num4 - num6) != 1)
                    {
                        throw new Exception(string.Concat(new object[]
                        {
                            "Tiles not adjacent (",
                            num3,
                            ", ",
                            num4,
                            ") (",
                            num5,
                            ", ",
                            num6,
                            ")"
                        }));
                    }
                    num7 = 2;
                }
                int vertexCount  = this.GetVertexCount();
                int vertexCount2 = triangleMeshNode.GetVertexCount();
                int num8         = -1;
                int num9         = -1;
                for (int j = 0; j < vertexCount; j++)
                {
                    int num10 = this.GetVertex(j)[num7];
                    for (int k = 0; k < vertexCount2; k++)
                    {
                        if (num10 == triangleMeshNode.GetVertex((k + 1) % vertexCount2)[num7] && this.GetVertex((j + 1) % vertexCount)[num7] == triangleMeshNode.GetVertex(k)[num7])
                        {
                            num8 = j;
                            num9 = k;
                            j    = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = num8;
                bIndex = num9;
                if (num8 != -1)
                {
                    Int3 vertex  = this.GetVertex(num8);
                    Int3 vertex2 = this.GetVertex((num8 + 1) % vertexCount);
                    int  i2      = (num7 != 2) ? 2 : 0;
                    int  num11   = Math.Min(vertex[i2], vertex2[i2]);
                    int  num12   = Math.Max(vertex[i2], vertex2[i2]);
                    num11 = Math.Max(num11, Math.Min(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    num12 = Math.Min(num12, Math.Max(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    if (vertex[i2] < vertex2[i2])
                    {
                        vertex[i2]  = num11;
                        vertex2[i2] = num12;
                    }
                    else
                    {
                        vertex[i2]  = num12;
                        vertex2[i2] = num11;
                    }
                    if (left != null)
                    {
                        left.Add((Vector3)vertex);
                        right.Add((Vector3)vertex2);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num13        = -1;
                int num14        = -1;
                int vertexCount3 = this.GetVertexCount();
                int vertexCount4 = triangleMeshNode.GetVertexCount();
                for (int l = 0; l < vertexCount3; l++)
                {
                    int vertexIndex = this.GetVertexIndex(l);
                    for (int m = 0; m < vertexCount4; m++)
                    {
                        if (vertexIndex == triangleMeshNode.GetVertexIndex((m + 1) % vertexCount4) && this.GetVertexIndex((l + 1) % vertexCount3) == triangleMeshNode.GetVertexIndex(m))
                        {
                            num13 = l;
                            num14 = m;
                            l     = vertexCount3;
                            break;
                        }
                    }
                }
                aIndex = num13;
                bIndex = num14;
                if (num13 == -1)
                {
                    for (int n = 0; n < this.connections.Length; n++)
                    {
                        if (this.connections[n].GraphIndex != base.GraphIndex)
                        {
                            NodeLink3Node nodeLink3Node2 = this.connections[n] as NodeLink3Node;
                            if (nodeLink3Node2 != null && nodeLink3Node2.GetOther(this) == triangleMeshNode && left != null)
                            {
                                nodeLink3Node2.GetPortal(triangleMeshNode, left, right, false);
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                if (left != null)
                {
                    left.Add((Vector3)this.GetVertex(num13));
                    right.Add((Vector3)this.GetVertex((num13 + 1) % vertexCount3));
                }
            }
            return(true);
        }
Example #28
0
        void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
        {
            if (range <= 0)
            {
                return;
            }

            bool negAbort = false;
            bool posAbort = false;

            range *= range;

            position.y = 0;
            //Looping as 0,-1,1,-2,2,-3,3,-4,4 etc. Avoids code duplication by keeping it to one loop instead of two
            for (int i = 0; !negAbort || !posAbort; i = i < 0 ? -i : -i - 1)
            {
                if (i < 0 && negAbort)
                {
                    continue;
                }
                if (i > 0 && posAbort)
                {
                    continue;
                }

                if (i < 0 && nodeIndex + i < 0)
                {
                    negAbort = true;
                    continue;
                }

                if (i > 0 && nodeIndex + i >= nodes.Count)
                {
                    posAbort = true;
                    continue;
                }

                TriangleMeshNode prev = nodeIndex + i - 1 < 0 ? null : nodes[nodeIndex + i - 1];
                TriangleMeshNode node = nodes[nodeIndex + i];
                TriangleMeshNode next = nodeIndex + i + 1 >= nodes.Count ? null : nodes[nodeIndex + i + 1];

                if (node.Destroyed)
                {
                    break;
                }

                if ((node.ClosestPointOnNodeXZ(position) - position).sqrMagnitude > range)
                {
                    if (i < 0)
                    {
                        negAbort = true;
                    }
                    else
                    {
                        posAbort = true;
                    }
                    continue;
                }

                for (int j = 0; j < 3; j++)
                {
                    triBuffer[j] = 0;
                }

                for (int j = 0; j < node.connections.Length; j++)
                {
                    var other = node.connections[j] as TriangleMeshNode;
                    if (other == null)
                    {
                        continue;
                    }

                    int va = -1;
                    for (int a = 0; a < 3; a++)
                    {
                        for (int b = 0; b < 3; b++)
                        {
                            if (node.GetVertex(a) == other.GetVertex((b + 1) % 3) && node.GetVertex((a + 1) % 3) == other.GetVertex(b))
                            {
                                va = a;
                                a  = 3;
                                break;
                            }
                        }
                    }
                    if (va == -1)
                    {
                        //No direct connection
                    }
                    else
                    {
                        triBuffer[va] = other == prev || other == next ? 2 : 1;
                    }
                }

                for (int j = 0; j < 3; j++)
                {
                    //Tribuffer values
                    // 0 : Navmesh border, outer edge
                    // 1 : Inner edge, to node inside funnel
                    // 2 : Inner edge, to node outside funnel
                    if (triBuffer[j] == 0)
                    {
                        //Add edge to list of walls
                        wallBuffer.Add((Vector3)node.GetVertex(j));
                        wallBuffer.Add((Vector3)node.GetVertex((j + 1) % 3));
                    }
                }
            }
        }
Example #29
0
        public bool GetPortal(GraphNode _other, List <VInt3> left, List <VInt3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode triangleMeshNode = _other as TriangleMeshNode;
            int num  = this.GetVertexIndex(0) >> 12 & 524287;
            int num2 = triangleMeshNode.GetVertexIndex(0) >> 12 & 524287;

            if (num != num2 && TriangleMeshNode.GetNavmeshHolder(this.DataGroupIndex, base.GraphIndex) is RecastGraph)
            {
                INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(this.DataGroupIndex, base.GraphIndex);
                int            num3;
                int            num4;
                navmeshHolder.GetTileCoordinates(num, out num3, out num4);
                int num5;
                int num6;
                navmeshHolder.GetTileCoordinates(num2, out num5, out num6);
                int num7;
                if (Math.Abs(num3 - num5) == 1)
                {
                    num7 = 0;
                }
                else
                {
                    if (Math.Abs(num4 - num6) != 1)
                    {
                        throw new Exception(string.Concat(new object[]
                        {
                            "Tiles not adjacent (",
                            num3,
                            ", ",
                            num4,
                            ") (",
                            num5,
                            ", ",
                            num6,
                            ")"
                        }));
                    }
                    num7 = 2;
                }
                int vertexCount  = this.GetVertexCount();
                int vertexCount2 = triangleMeshNode.GetVertexCount();
                int num8         = -1;
                int num9         = -1;
                for (int i = 0; i < vertexCount; i++)
                {
                    int num10 = this.GetVertex(i)[num7];
                    for (int j = 0; j < vertexCount2; j++)
                    {
                        if (num10 == triangleMeshNode.GetVertex((j + 1) % vertexCount2)[num7] && this.GetVertex((i + 1) % vertexCount)[num7] == triangleMeshNode.GetVertex(j)[num7])
                        {
                            num8 = i;
                            num9 = j;
                            i    = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = num8;
                bIndex = num9;
                if (num8 != -1)
                {
                    VInt3 vertex  = this.GetVertex(num8);
                    VInt3 vertex2 = this.GetVertex((num8 + 1) % vertexCount);
                    int   i2      = (num7 == 2) ? 0 : 2;
                    int   num11   = Math.Min(vertex[i2], vertex2[i2]);
                    int   num12   = Math.Max(vertex[i2], vertex2[i2]);
                    num11 = Math.Max(num11, Math.Min(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    num12 = Math.Min(num12, Math.Max(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    if (vertex[i2] < vertex2[i2])
                    {
                        vertex[i2]  = num11;
                        vertex2[i2] = num12;
                    }
                    else
                    {
                        vertex[i2]  = num12;
                        vertex2[i2] = num11;
                    }
                    if (left != null)
                    {
                        left.Add(vertex);
                        right.Add(vertex2);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num13        = -1;
                int num14        = -1;
                int vertexCount3 = this.GetVertexCount();
                int vertexCount4 = triangleMeshNode.GetVertexCount();
                for (int k = 0; k < vertexCount3; k++)
                {
                    int vertexIndex = this.GetVertexIndex(k);
                    for (int l = 0; l < vertexCount4; l++)
                    {
                        if (vertexIndex == triangleMeshNode.GetVertexIndex((l + 1) % vertexCount4) && this.GetVertexIndex((k + 1) % vertexCount3) == triangleMeshNode.GetVertexIndex(l))
                        {
                            num13 = k;
                            num14 = l;
                            k     = vertexCount3;
                            break;
                        }
                    }
                }
                aIndex = num13;
                bIndex = num14;
                if (num13 == -1)
                {
                    return(false);
                }
                if (left != null)
                {
                    left.Add(this.GetVertex(num13));
                    right.Add(this.GetVertex((num13 + 1) % vertexCount3));
                }
            }
            return(true);
        }