public PathFinder(List <Vector3> points, Dictionary <int, Poly> polys, Dictionary <int, List <NodeEdge> > edges, float left, float bottom, float tileSize, int width, int height, int componentCount, List <int>[,] aoiList, List <int>[,] pths = null) { this.points = points; this.edges = edges; this.polys = polys; this.componentCount = componentCount; navAOI = new NavAOI(left, bottom, width, height, tileSize, aoiList); this.isPathPreCalculate = (pths != null); if (pths != null) { this.paths = pths; } }
/// <summary> /// 得到处理过后的导航文件,包含信息(顶点、多边形、多边形连接、预计算路径信息、多边形的AOI信息) /// </summary> /// <param name="fileName"></param> /// <param name="ifPreCalculatePath"></param> public static void WriteProcessedNavFile(NavMesh navMesh, string fileName, bool ifPreCalculatePath) { if (File.Exists(fileName)) { File.Delete(fileName); } StreamWriter sw = new StreamWriter(fileName); StringBuilder lBuilder; for (int i = 0; i < navMesh.Points.Count; i++)//顶点信息 { lBuilder = new StringBuilder("v").Append(navMesh.Points[i].x.ToString()).Append(" ").Append(navMesh.Points[i].y.ToString()).Append(" ").Append(navMesh.Points[i].z); sw.WriteLine(lBuilder.ToString()); } SortedDictionary <int, Poly> .Enumerator polyIter = navMesh.Polys.GetEnumerator(); while (polyIter.MoveNext()) //Poly 信息 { lBuilder = new StringBuilder("p").Append(polyIter.Current.Key.ToString()).Append(" "); Poly p = polyIter.Current.Value; foreach (GeoEdge e in p.Edges) { lBuilder.Append("|").Append(e.A.ToString()).Append(" ").Append(e.B); } sw.WriteLine(lBuilder.ToString()); } polyIter.Dispose(); SortedDictionary <int, HashSet <PolyConnection> > .Enumerator iter = navMesh.NearPolys.GetEnumerator(); while (iter.MoveNext())//Poly connection信息 { //有连接的poly的序号 lBuilder = new StringBuilder("c ").Append(iter.Current.Key.ToString()); HashSet <PolyConnection> cons = iter.Current.Value; foreach (PolyConnection con in cons) { lBuilder.Append(" ").Append(con.Other(iter.Current.Key).ToString()).Append(" ").Append(con.Weight.ToString()).Append(" ").Append(con.ConnectionEdge.A.ToString()).Append(" ").Append(con.ConnectionEdge.B.ToString()); //每个连接有4个数据,分别是:连向的Poly的序号、此连接的权重、对应此连接的边的两个顶点 } sw.WriteLine(lBuilder.ToString()); } iter.Dispose(); if (ifPreCalculatePath) {//预存储的路径信息, 存在文件的后部 List <int>[,] paths = navMesh.Paths; for (int m = 0; m < navMesh.Polys.Count; m++) { for (int n = 0; n < navMesh.Polys.Count; n++) { List <int> pth = paths[m, n]; if (pth != null && pth.Count > 0) { lBuilder = new StringBuilder("from ").Append(m.ToString()).Append(" to ").Append(n.ToString()); for (int x = 0; x < pth.Count; x++) { lBuilder.Append(" ").Append(pth[x].ToString()); } sw.WriteLine(lBuilder.ToString()); } } } } sw.WriteLine("componentCount " + navMesh.ComponentCount); //这里把AOI信息也写进来 NavAOI navAOI = NavAOIProcesser.ProcessPolyAOI(navMesh.Polys, navMesh); sw.WriteLine("navAOI:"); lBuilder = new StringBuilder("AOIInfo ").Append(navAOI.Left.ToString()).Append(" ").Append(navAOI.Bottom).Append(" ").Append(navAOI.TileSize).Append(" ").Append(navAOI.Width).Append(" ").Append(navAOI.Height); sw.WriteLine(lBuilder.ToString()); for (int i = 0; i < navAOI.Width; i++) { for (int j = 0; j < navAOI.Height; j++) { List <int> aoiList = navAOI.NavPolyAOI[i, j]; if (aoiList != null) { lBuilder = new StringBuilder(i.ToString()).Append(",").Append(j.ToString()).Append(":"); for (int k = 0; k < aoiList.Count; k++) { lBuilder.Append(" ").Append(aoiList[k]); } sw.WriteLine(lBuilder.ToString()); } } } sw.Close(); sw.Dispose(); }
public static NavAOI ProcessPolyAOI(SortedDictionary <int, Poly> polys, NavMesh mesh) { float l = Mathf.Infinity; float r = Mathf.NegativeInfinity; float b = Mathf.Infinity; float t = Mathf.NegativeInfinity; float area = 0f; SortedDictionary <int, Poly> .Enumerator polyIter = polys.GetEnumerator(); while (polyIter.MoveNext()) {//Poly 信息 Poly poly = polyIter.Current.Value; foreach (int pIndex in poly.GetPoints()) { Vector3 point = mesh.Point(pIndex); if (point.x < l) { l = point.x; } if (point.z < b) { b = point.z; } if (point.x > r) { r = point.x; } if (point.z > t) { t = point.z; } } area += poly.GetGeo2D().GetArea(); } polyIter.Dispose(); area /= polys.Count; left = l; bottom = b; width = r - l; height = t - b; tileSize = Mathf.Sqrt(area); int w = Mathf.CeilToInt(width / tileSize); int h = Mathf.CeilToInt(height / tileSize); NavAOI navAOI = new NavAOI(left, bottom, width, height, tileSize); polyIter = polys.GetEnumerator(); while (polyIter.MoveNext()) { Poly poly = polyIter.Current.Value; Geo2D geo2D = poly.GetGeo2D(); int xStart = Mathf.FloorToInt(geo2D.MinX / tileSize); int xEnd = Mathf.CeilToInt(geo2D.MaxX / tileSize); int yStart = Mathf.FloorToInt(geo2D.MinY / tileSize); int yEnd = Mathf.CeilToInt(geo2D.MaxY / tileSize); for (int i = xStart; i < xEnd; i++) { for (int j = yStart; j < yEnd; j++) { if (IsIntersect(poly, i, j)) { navAOI.AddPolyToAOI(i, j, polyIter.Current.Key); } } } } polyIter.Dispose(); return(navAOI); }