/// <summary> /// 比较并获取三角形邻居边索引 /// </summary> /// <param name="triNext">三角形</param> /// <returns>邻边索引</returns> public int GetNeighborWall(Triangle triNext) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (GetSide(i).Equals(triNext.GetSide(j))) return i; } } return -1; }
/// <summary> /// 根据传进来BinaryReader读取数据 /// </summary> /// <param name="navTriangles"></param> /// <param name="binReader"></param> /// <returns></returns> public NavResCode LoadNavMeshFromFile(ref List<Triangle> navTriangles, BinaryReader binReader) { try { // 读取版本号 string fileVersion = new string(binReader.ReadChars(NAVMESH_VERSION.Length)); if (fileVersion != NAVMESH_VERSION) return NavResCode.VersionNotMatch; // 读取导航三角形数量 int navCount = binReader.ReadInt32(); Triangle currTri; for (int i = 0; i < navCount; i++) { currTri = new Triangle(); currTri.Read(binReader); navTriangles.Add(currTri); } } catch { //Debug.LogError(e.Message); return NavResCode.Failed; } finally { } return NavResCode.Success; }
/// <summary> /// 创建导航网格 /// </summary> /// <param name="polyAll">所有阻挡区域</param> /// <param name="triAll">输出的导航网格</param> /// <returns></returns> public NavResCode CreateNavMesh(List<Polygon> polyAll , ref int id , int groupid , ref List<Triangle> triAll) { triAll.Clear(); List<Line2D> allLines = new List<Line2D>(); //线段堆栈 //Step1 保存顶点和边 NavResCode initRes = InitData(polyAll); if (initRes != NavResCode.Success) return initRes; int lastNeighborId = -1; Triangle lastTri = null; //Step2.遍历边界边作为起点 { Line2D sEdge = startEdge; allLines.Add(sEdge); Line2D edge = null; do { //Step3.选出计算出边的DT点,构成约束Delaunay三角形 edge = allLines[allLines.Count - 1]; allLines.Remove(edge); Vector2 dtPoint; bool isFindDt = FindDT(edge, out dtPoint); if (!isFindDt) continue; Line2D lAD = new Line2D(edge.GetStartPoint(), dtPoint); Line2D lDB = new Line2D(dtPoint, edge.GetEndPoint()); //创建三角形 Triangle delaunayTri = new Triangle(edge.GetStartPoint(), edge.GetEndPoint(), dtPoint, id++ , groupid); // 保存邻居节点 // if (lastNeighborId != -1) // { // delaunayTri.SetNeighbor(lastNeighborId); // if(lastTri != null) // lastTri.SetNeighbor(delaunayTri.ID); // } //save result triangle triAll.Add(delaunayTri); // 保存上一次的id和三角形 lastNeighborId = delaunayTri.GetID(); lastTri = delaunayTri; int lineIndex; //Step4.检测刚创建的的线段ad,db;如果如果它们不是约束边 //并且在线段堆栈中,则将其删除,如果不在其中,那么将其放入 if (!Line2D.CheckLineIn(allEdges, lAD, out lineIndex)) { if (!Line2D.CheckLineIn(allLines, lAD, out lineIndex)) allLines.Add(lAD); else allLines.RemoveAt(lineIndex); } if (!Line2D.CheckLineIn(allEdges, lDB, out lineIndex)) { if (!Line2D.CheckLineIn(allLines, lDB, out lineIndex)) allLines.Add(lDB); else allLines.RemoveAt(lineIndex); } //Step5.如果堆栈不为空,则转到第Step3.否则结束循环 } while (allLines.Count > 0); } // 计算邻接边和每边中点距离 for (int i = 0; i < triAll.Count; i++) { Triangle tri = triAll[i]; //// 计算每个三角形每边中点距离 //tri.calcWallDistance(); // 计算邻居边 for (int j = 0; j < triAll.Count; j++) { Triangle triNext = triAll[j]; if (tri.GetID() == triNext.GetID()) continue; int result = tri.isNeighbor(triNext); if (result != -1) { tri.SetNeighbor(result , triNext.GetID() ); } } } return NavResCode.Success; }
/// <summary> /// Checks the cross. /// </summary> /// <returns><c>true</c>, if cross was checked, <c>false</c> otherwise.</returns> /// <param name="line">Line.</param> /// <param name="tri">Tri.</param> public static bool CheckCross( Line2D line , Triangle tri ) { for(int i = 0 ; i < 3 ; i++ ) { Line2D lineTri = tri.GetSide(i); if( CheckCross(line.GetStartPoint() , line.GetEndPoint() , lineTri.GetStartPoint() , lineTri.GetEndPoint()) ) { return true; } } return false; }