예제 #1
0
        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;
            }
        }
예제 #2
0
        /// <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();
        }
예제 #3
0
        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);
        }