// Token: 0x060005DF RID: 1503 RVA: 0x00035EB4 File Offset: 0x000342B4 public void CreateTileTypesFromGraph() { RecastGraph.NavmeshTile[] tiles = this.graph.GetTiles(); if (tiles == null || tiles.Length != this.graph.tileXCount * this.graph.tileZCount) { throw new InvalidOperationException("Graph tiles are invalid (either null or number of tiles is not equal to width*depth of the graph"); } for (int i = 0; i < this.graph.tileZCount; i++) { for (int j = 0; j < this.graph.tileXCount; j++) { RecastGraph.NavmeshTile navmeshTile = tiles[j + i * this.graph.tileXCount]; Int3 @int = (Int3)this.graph.GetTileBounds(j, i).min; Int3 tileSize = new Int3(this.graph.tileSizeX, 1, this.graph.tileSizeZ) * (1000f * this.graph.cellSize); @int += new Int3(tileSize.x * navmeshTile.w / 2, 0, tileSize.z * navmeshTile.d / 2); @int = -@int; TileHandler.TileType tileType = new TileHandler.TileType(navmeshTile.verts, navmeshTile.tris, tileSize, @int, navmeshTile.w, navmeshTile.d); this.tileTypes.Add(tileType); int num = j + i * this.graph.tileXCount; this.activeTileTypes[num] = tileType; this.activeTileRotations[num] = 0; this.activeTileOffsets[num] = 0; } } }
/** Creates a mesh of the surfaces of the navmesh for use in OnDrawGizmos in the editor */ Mesh CreateNavmeshSurfaceVisualization(RecastGraph.NavmeshTile tile) { var mesh = new Mesh(); mesh.hideFlags = HideFlags.DontSave; var vertices = ListPool <Vector3> .Claim(tile.verts.Length); var colors = ListPool <Color32> .Claim(tile.verts.Length); for (int j = 0; j < tile.verts.Length; j++) { vertices.Add((Vector3)tile.verts[j]); colors.Add(new Color32()); } // TODO: Uses AstarPath.active var debugPathData = AstarPath.active.debugPathData; for (int j = 0; j < tile.nodes.Length; j++) { var node = tile.nodes[j]; for (int v = 0; v < 3; v++) { var color = target.NodeColor(node, debugPathData); colors[node.GetVertexArrayIndex(v)] = (Color32)color; //(Color32)AstarColor.GetAreaColor(node.Area); } } mesh.SetVertices(vertices); mesh.SetTriangles(tile.tris, 0); mesh.SetColors(colors); // Upload all data and mark the mesh as unreadable mesh.UploadMeshData(true); // Return lists to the pool ListPool <Vector3> .Release(vertices); ListPool <Color32> .Release(colors); return(mesh); }
private static RecastGraph buildGraph(River river) { RecastGraph recastGraph = LevelNavigation.addGraph(); int graphIndex = AstarPath.active.astarData.GetGraphIndex(recastGraph); TriangleMeshNode.SetNavmeshHolder(graphIndex, recastGraph); recastGraph.forcedBoundsCenter = river.readSingleVector3(); recastGraph.forcedBoundsSize = river.readSingleVector3(); recastGraph.tileXCount = (int)river.readByte(); recastGraph.tileZCount = (int)river.readByte(); RecastGraph.NavmeshTile[] array = new RecastGraph.NavmeshTile[recastGraph.tileXCount * recastGraph.tileZCount]; recastGraph.SetTiles(array); for (int i = 0; i < recastGraph.tileZCount; i++) { for (int j = 0; j < recastGraph.tileXCount; j++) { RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile(); navmeshTile.x = j; navmeshTile.z = i; navmeshTile.w = 1; navmeshTile.d = 1; navmeshTile.bbTree = new BBTree(navmeshTile); int num = j + i * recastGraph.tileXCount; array[num] = navmeshTile; navmeshTile.tris = new int[(int)river.readUInt16()]; for (int k = 0; k < navmeshTile.tris.Length; k++) { navmeshTile.tris[k] = (int)river.readUInt16(); } navmeshTile.verts = new Int3[(int)river.readUInt16()]; for (int l = 0; l < navmeshTile.verts.Length; l++) { navmeshTile.verts[l] = new Int3(river.readInt32(), river.readInt32(), river.readInt32()); } navmeshTile.nodes = new TriangleMeshNode[navmeshTile.tris.Length / 3]; num <<= 12; for (int m = 0; m < navmeshTile.nodes.Length; m++) { navmeshTile.nodes[m] = new TriangleMeshNode(AstarPath.active); TriangleMeshNode triangleMeshNode = navmeshTile.nodes[m]; triangleMeshNode.GraphIndex = (uint)graphIndex; triangleMeshNode.Penalty = 0u; triangleMeshNode.Walkable = true; triangleMeshNode.v0 = (navmeshTile.tris[m * 3] | num); triangleMeshNode.v1 = (navmeshTile.tris[m * 3 + 1] | num); triangleMeshNode.v2 = (navmeshTile.tris[m * 3 + 2] | num); triangleMeshNode.UpdatePositionFromVertices(); navmeshTile.bbTree.Insert(triangleMeshNode); } recastGraph.CreateNodeConnections(navmeshTile.nodes); } } for (int n = 0; n < recastGraph.tileZCount; n++) { for (int num2 = 0; num2 < recastGraph.tileXCount; num2++) { RecastGraph.NavmeshTile tile = array[num2 + n * recastGraph.tileXCount]; recastGraph.ConnectTileWithNeighbours(tile); } } return(recastGraph); }
public static void save() { River river = new River(Level.info.path + "/Environment/Bounds.dat", false); river.writeByte(LevelNavigation.SAVEDATA_BOUNDS_VERSION); river.writeByte((byte)LevelNavigation.bounds.Count); byte b = 0; while ((int)b < LevelNavigation.bounds.Count) { river.writeSingleVector3(LevelNavigation.bounds[(int)b].center); river.writeSingleVector3(LevelNavigation.bounds[(int)b].size); b += 1; } river.closeRiver(); River river2 = new River(Level.info.path + "/Environment/Flags_Data.dat", false); river2.writeByte(LevelNavigation.SAVEDATA_FLAG_DATA_VERSION); river2.writeByte((byte)LevelNavigation.flagData.Count); byte b2 = 0; while ((int)b2 < LevelNavigation.flagData.Count) { river2.writeString(LevelNavigation.flagData[(int)b2].difficultyGUID); river2.writeByte(LevelNavigation.flagData[(int)b2].maxZombies); river2.writeBoolean(LevelNavigation.flagData[(int)b2].spawnZombies); b2 += 1; } river2.closeRiver(); River river3 = new River(Level.info.path + "/Environment/Flags.dat", false); river3.writeByte(LevelNavigation.SAVEDATA_FLAGS_VERSION); int num = LevelNavigation.flags.Count; while (ReadWrite.fileExists(string.Concat(new object[] { Level.info.path, "/Environment/Navigation_", num, ".dat" }), false, false)) { ReadWrite.deleteFile(string.Concat(new object[] { Level.info.path, "/Environment/Navigation_", num, ".dat" }), false, false); num++; } river3.writeByte((byte)LevelNavigation.flags.Count); byte b3 = 0; while ((int)b3 < LevelNavigation.flags.Count) { Flag flag = LevelNavigation.flags[(int)b3]; river3.writeSingleVector3(flag.point); river3.writeSingle(flag.width); river3.writeSingle(flag.height); if (flag.needsNavigationSave) { River river4 = new River(string.Concat(new object[] { Level.info.path, "/Environment/Navigation_", b3, ".dat" }), false); river4.writeByte(LevelNavigation.SAVEDATA_NAVIGATION_VERSION); RecastGraph graph = flag.graph; river4.writeSingleVector3(graph.forcedBoundsCenter); river4.writeSingleVector3(graph.forcedBoundsSize); river4.writeByte((byte)graph.tileXCount); river4.writeByte((byte)graph.tileZCount); RecastGraph.NavmeshTile[] tiles = graph.GetTiles(); for (int i = 0; i < graph.tileZCount; i++) { for (int j = 0; j < graph.tileXCount; j++) { RecastGraph.NavmeshTile navmeshTile = tiles[j + i * graph.tileXCount]; river4.writeUInt16((ushort)navmeshTile.tris.Length); for (int k = 0; k < navmeshTile.tris.Length; k++) { river4.writeUInt16((ushort)navmeshTile.tris[k]); } river4.writeUInt16((ushort)navmeshTile.verts.Length); for (int l = 0; l < navmeshTile.verts.Length; l++) { Int3 @int = navmeshTile.verts[l]; river4.writeInt32(@int.x); river4.writeInt32(@int.y); river4.writeInt32(@int.z); } } } river4.closeRiver(); flag.needsNavigationSave = false; } b3 += 1; } river3.closeRiver(); }
/** Exports the INavmesh graph to a file */ public void ExportToFile(RecastGraph target) { //INavmesh graph = (INavmesh)target; if (target == null) { return; } RecastGraph.NavmeshTile[] tiles = target.GetTiles(); if (tiles == null) { if (EditorUtility.DisplayDialog("Scan graph before exporting?", "The graph does not contain any mesh data. Do you want to scan it?", "Ok", "Cancel")) { AstarPath.MenuScan(); tiles = target.GetTiles(); if (tiles == null) { return; } } else { return; } } string path = EditorUtility.SaveFilePanel("Export .obj", "", "navmesh.obj", "obj"); if (path == "") { return; } //Generate .obj System.Text.StringBuilder sb = new System.Text.StringBuilder(); string name = System.IO.Path.GetFileNameWithoutExtension(path); sb.Append("g ").Append(name).AppendLine(); //Vertices start from 1 int vCount = 1; //Define single texture coordinate to zero sb.Append("vt 0 0\n"); for (int t = 0; t < tiles.Length; t++) { RecastGraph.NavmeshTile tile = tiles[t]; if (tile == null) { continue; } Int3[] vertices = tile.verts; //Write vertices for (int i = 0; i < vertices.Length; i++) { Vector3 v = (Vector3)vertices[i]; sb.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z)); } //Write triangles TriangleMeshNode[] nodes = tile.nodes; for (int i = 0; i < nodes.Length; i++) { TriangleMeshNode node = nodes[i]; if (node == null) { Debug.LogError("Node was null or no TriangleMeshNode. Critical error. Graph type " + target.GetType().Name); return; } if (node.GetVertexArrayIndex(0) < 0 || node.GetVertexArrayIndex(0) >= vertices.Length) { throw new System.Exception("ERR"); } sb.Append(string.Format("f {0}/1 {1}/1 {2}/1\n", (node.GetVertexArrayIndex(0) + vCount), (node.GetVertexArrayIndex(1) + vCount), (node.GetVertexArrayIndex(2) + vCount))); } vCount += vertices.Length; } string obj = sb.ToString(); using (System.IO.StreamWriter sw = new System.IO.StreamWriter(path)) { sw.Write(obj); } }
/** Creates an outline of the navmesh for use in OnDrawGizmos in the editor */ static Mesh CreateNavmeshOutlineVisualization(RecastGraph.NavmeshTile tile) { var sharedEdges = new bool[3]; var mesh = new Mesh(); mesh.hideFlags = HideFlags.DontSave; var colorList = ListPool <Color32> .Claim(); var edgeList = ListPool <Int3> .Claim(); for (int j = 0; j < tile.nodes.Length; j++) { sharedEdges[0] = sharedEdges[1] = sharedEdges[2] = false; var node = tile.nodes[j]; for (int c = 0; c < node.connections.Length; c++) { var other = node.connections[c] as TriangleMeshNode; // Loop throgh neighbours to figure // out which edges are shared if (other != null && other.GraphIndex == node.GraphIndex) { for (int v = 0; v < 3; v++) { for (int v2 = 0; v2 < 3; v2++) { if (node.GetVertexIndex(v) == other.GetVertexIndex((v2 + 1) % 3) && node.GetVertexIndex((v + 1) % 3) == other.GetVertexIndex(v2)) { // Found a shared edge with the other node sharedEdges[v] = true; v = 3; break; } } } } } for (int v = 0; v < 3; v++) { if (!sharedEdges[v]) { edgeList.Add(node.GetVertex(v)); edgeList.Add(node.GetVertex((v + 1) % 3)); var color = (Color32)AstarColor.GetAreaColor(node.Area); colorList.Add(color); colorList.Add(color); } } } // Use pooled lists to avoid excessive allocations var vertices = ListPool <Vector3> .Claim(edgeList.Count *2); var colors = ListPool <Color32> .Claim(edgeList.Count *2); var normals = ListPool <Vector3> .Claim(edgeList.Count *2); var tris = ListPool <int> .Claim(edgeList.Count *3); // Loop through each endpoint of the lines // and add 2 vertices for each for (int j = 0; j < edgeList.Count; j++) { var vertex = (Vector3)edgeList[j]; vertices.Add(vertex); vertices.Add(vertex); // Encode the side of the line // in the alpha component var color = colorList[j]; colors.Add(new Color32(color.r, color.g, color.b, 0)); colors.Add(new Color32(color.r, color.g, color.b, 255)); } // Loop through each line and add // one normal for each vertex for (int j = 0; j < edgeList.Count; j += 2) { var lineDir = (Vector3)(edgeList[j + 1] - edgeList[j]); lineDir.Normalize(); // Store the line direction in the normals // A line consists of 4 vertices // The line direction will be used to // offset the vertices to create a // line with a fixed pixel thickness normals.Add(lineDir); normals.Add(lineDir); normals.Add(lineDir); normals.Add(lineDir); } // Setup triangle indices // A triangle consists of 3 indices // A line (4 vertices) consists of 2 triangles, so 6 triangle indices for (int j = 0, v = 0; j < edgeList.Count * 3; j += 6, v += 4) { // First triangle tris.Add(v + 0); tris.Add(v + 1); tris.Add(v + 2); // Second triangle tris.Add(v + 1); tris.Add(v + 3); tris.Add(v + 2); } // Set all data on the mesh mesh.SetVertices(vertices); mesh.SetTriangles(tris, 0); mesh.SetColors(colors); mesh.SetNormals(normals); // Upload all data and mark the mesh as unreadable mesh.UploadMeshData(true); // Release the lists back to the pool ListPool <Color32> .Release(colorList); ListPool <Int3> .Release(edgeList); ListPool <Vector3> .Release(vertices); ListPool <Color32> .Release(colors); ListPool <Vector3> .Release(normals); ListPool <int> .Release(tris); return(mesh); }