//void SaveCollisionMap(NavMeshData data) public void SaveCollisionMap(string serverPath) { List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary(); if (serverPath != null) { using (StreamWriter outputFile = new StreamWriter(serverPath + @"CollisionMap.txt")) { for (int i = 0; i < boundary.Count; i++) { BoundaryEdge edge = boundary[i]; outputFile.Write(WG_Helper.Vectro3ToString(edge.start) + "|" + WG_Helper.Vectro3ToString(edge.end) + (i == boundary.Count - 1 ? "" : "|")); //IntIntClass edge = edgesList[boundaryEdges[i]].GetEdgeVertices(); //outputFile.Write(WG_Helper.Vectro3ToString(vertexList[edge.value1].position) + "|" + WG_Helper.Vectro3ToString(vertexList[edge.value2].position) + (i == boundaryEdges.Count - 1 ? "" : "|")); } } } }
public static List <BoundaryEdge> GetNavmeshBoundary() { //copy algorithm NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation(); Vector3[] originalVertices = triangulatedNavMesh.vertices; int[] originalIndexes = triangulatedNavMesh.indices; float weldValue = 0.01f; List <VertexData> vertexList = new List <VertexData>(); for (int i = 0; i < originalVertices.Length; i++) { Vector3 vPos = originalVertices[i]; bool isNew = true; //Try to find this vertex on vertexList for (int vIndex = 0; vIndex < vertexList.Count; vIndex++) { VertexData v = vertexList[vIndex]; if (Vector3.Distance(vPos, v.position) < weldValue) {//i-th vertex placed in the same position as vIndex in the list. Add it index v.indexes.Add(i); vIndex = vertexList.Count; isNew = false; } } if (isNew) { VertexData newVertex = new VertexData(); newVertex.position = vPos; newVertex.indexes = new List <int>(); newVertex.indexes.Add(i); vertexList.Add(newVertex); } } List <EdgeData> edgesList = new List <EdgeData>(); int originalTrianglesCount = originalIndexes.Length / 3; for (int i = 0; i < originalTrianglesCount; i++) { int i1 = WG_Helper.GetVertexIndex(originalIndexes[3 * i], vertexList); int i2 = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 1], vertexList); int i3 = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 2], vertexList); bool isFindI12 = false; bool isFindI23 = false; bool isFindI31 = false; for (int eIndex = 0; eIndex < edgesList.Count; eIndex++) { isFindI12 = edgesList[eIndex].TryToAdd(i1, i2) || isFindI12; isFindI23 = edgesList[eIndex].TryToAdd(i2, i3) || isFindI23; isFindI31 = edgesList[eIndex].TryToAdd(i3, i1) || isFindI31; } if (!isFindI12) { EdgeData newEdge = new EdgeData(i1, i2); edgesList.Add(newEdge); } if (!isFindI23) { EdgeData newEdge = new EdgeData(i2, i3); edgesList.Add(newEdge); } if (!isFindI31) { EdgeData newEdge = new EdgeData(i3, i1); edgesList.Add(newEdge); } } //filter boundary edges, if it contains vertex of the other boundary edge inside it List <int> boundaryIndexes = new List <int>(); for (int i = 0; i < edgesList.Count; i++) { if (edgesList[i].IsBoundary()) { boundaryIndexes.Add(i); } } bool isUpdate = true; while (isUpdate) { isUpdate = false; int i = 0; while (i < boundaryIndexes.Count) { IntInt currentEdge; currentEdge.value01 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value1; currentEdge.value02 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value2; //IntIntClass currentEdge = edgesList[boundaryIndexes[i]].GetEdgeVertices(); Vector3 currentStart = vertexList[currentEdge.value01].position; Vector3 currentEnd = vertexList[currentEdge.value02].position; if (Vector3.Distance(currentStart, currentEnd) < 0.01f) { boundaryIndexes.RemoveAt(i); i = boundaryIndexes.Count + 1; isUpdate = true; } else { int j = 0; while (j < boundaryIndexes.Count) { IntInt testEdge; testEdge.value01 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value1; testEdge.value02 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value2; //IntIntClass testEdge = edgesList[boundaryIndexes[j]].GetEdgeVertices(); Vector3 testStart = vertexList[testEdge.value01].position; Vector3 testEnd = vertexList[testEdge.value02].position; if (Vector3.Distance(testStart, testEnd) < 0.01f) { boundaryIndexes.RemoveAt(j); j = boundaryIndexes.Count + 1; i = boundaryIndexes.Count + 1; isUpdate = true; } else if (i != j && boundaryIndexes[i] < boundaryIndexes[j]) { if (IsEdgesCollinear(currentStart, currentEnd, testStart, testEnd)) { if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(testStart, currentStart, currentEnd)) { EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02); EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(testEnd, currentStart, currentEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02); EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(currentEnd, testStart, testEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02); EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(currentStart, testStart, testEnd)) { EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02); EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointsClose(currentStart, testEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, currentEdge.value01); EdgeData jth = new EdgeData(testEdge.value01, testEdge.value01); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } } } j++; } } i++; } } //copy to the output List <BoundaryEdge> toReturn = new List <BoundaryEdge>(); for (int i = 0; i < boundaryIndexes.Count; i++) { int index = boundaryIndexes[i]; IntIntClass edge = edgesList[index].GetEdgeVertices(); BoundaryEdge newEdge = new BoundaryEdge(); newEdge.index = index; newEdge.start = vertexList[edge.value1].position; newEdge.end = vertexList[edge.value2].position; newEdge.startVertex = edge.value1; newEdge.endVertes = edge.value2; toReturn.Add(newEdge); } return(toReturn); }
void OnDrawGizmos() { #if UNITY_EDITOR if (visualMap != null && visualizeMap) { for (int x = 0; x < visualMap.GetLength(0); x++) { for (int y = 0; y < visualMap.GetLength(1); y++) { Gizmos.color = (visualMap[x, y]) ? new Color(0, 0, 0, gizmoAlpha) : new Color(1, 1, 1, gizmoAlpha); Vector3 pos = new Vector3(-visualAreaSize / 2 + (x + 0.5f) * visualSquareSize + visualAreaCenter.position.x, 0, -visualAreaSize / 2 + (y + 0.5f) * visualSquareSize + visualAreaCenter.position.z); Gizmos.DrawCube(pos, new Vector3(visualSquareSize * 0.75f, 0.0f, visualSquareSize * 0.75f)); } } Vector2 minCorner = new Vector2(visualAreaCenter.position.x - visualAreaSize / 2, visualAreaCenter.position.z - visualAreaSize / 2); Vector2 maxCorner = new Vector2(visualAreaCenter.position.x + visualAreaSize / 2, visualAreaCenter.position.z + visualAreaSize / 2); int minX = (int)(minCorner.x / (segmentSize / 2)) + (minCorner.x > 0 ? 1 : 0); int maxX = (int)(maxCorner.x / (segmentSize / 2)) + (maxCorner.x > 0 ? 1 : 0); int minY = (int)(minCorner.y / (segmentSize / 2)) + (minCorner.y > 0 ? 1 : 0); int maxY = (int)(maxCorner.y / (segmentSize / 2)) + (maxCorner.y > 0 ? 1 : 0); Gizmos.color = visualZoneLine; for (int x = minX - 1; x < maxX + 1; x++) { for (int y = minY - 1; y < maxY + 1; y++) { if (x % 2 == 0 && y % 2 == 0) { Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y - 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y + 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y + 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y - 1)); string labelString = "(" + (x / 2).ToString() + ", " + (y / 2).ToString() + ")"; Vector3 labelPos = new Vector3(x * segmentSize / 2, 2.0f, y * segmentSize / 2); Handles.Label(labelPos, labelString); } } } } if (visualizeBoundaryEdges) { List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary(); Gizmos.color = boundaryLine; for (int i = 0; i < boundary.Count; i++) { BoundaryEdge edge = boundary[i]; if (true) { Gizmos.DrawLine(edge.start, edge.end); //Handles.DrawSolidDisc(edge.start, Vector3.up, 0.03f); //Handles.Label(edge.start, edge.startVertex.ToString()); //Handles.DrawSolidDisc(edge.end, Vector3.up, 0.03f); //Handles.Label(edge.end, edge.endVertes.ToString()); //Handles.Label((edge.start + edge.end) / 2.0f, edge.index.ToString()); } } } #endif }