/// <summary> /// Builds the mesh for a single tile. /// NOTE: This sets the Terrain's NavMesh property. /// In order to move between tiles, we need to generate one mesh for the entire map /// </summary> public void BuildMesh(TerrainTile tile) { // let recast build the navmesh and then call our callback var inputFile = GetInputMeshFile(tile.Terrain.MapId, tile.TileX, tile.TileY); var navMeshFile = GetNavMeshFile(tile.Terrain.MapId, tile.TileX, tile.TileY); var exists = DoesNavMeshExist(tile.Terrain.MapId, tile.TileX, tile.TileY); if (!exists) { var directory = new FileInfo(inputFile).Directory; if (directory != null) { Directory.CreateDirectory(directory.FullName); } directory = new FileInfo(navMeshFile).Directory; if (directory != null) { Directory.CreateDirectory(directory.FullName); } // export input mesh to file ExportRecastInputMesh(tile, inputFile); Console.WriteLine("Building new NavMesh..."); } var start = DateTime.Now; var result = RecastAPI.BuildMesh( GenerateTileId(tile), inputFile, navMeshFile, SmashMeshDlgt); if (result == 0) { throw new Exception("Could not build mesh for tile " + TerrainConstants.GetTileName(tile.TileX, tile.TileY) + " in map " + Terrain.MapId); } if (!exists) { Console.WriteLine("Done in {0:0.000}s", (DateTime.Now - start).TotalSeconds); } //// move all vertices above the surface //var mesh = tile.Terrain.NavMesh; //for (var i = 0; i < mesh.Vertices.Length; i++) //{ // var vert = mesh.Vertices[i]; // vert.Z += 0.001f; // var ray = new Ray(vert, Vector3.Down); // see if vertex is above surface // var hit = tile.FindFirstHitTriangle(ray); // if (hit == -1) // { // vert.Z -= 0.001f; // // vertex is below surface // ray = new Ray(vert, Vector3.Up); // find surface right above mesh // hit = tile.FindFirstHitTriangle(ray); // if (hit != -1) // { // // set vertex height equal to terrain // var tri = tile.GetTriangle(hit); // var plane = new Plane(tri.Point1, tri.Point2, tri.Point3); // Intersection.LineSegmentIntersectsPlane(ray.Position, ray.Direction, plane, out mesh.Vertices[i]); // } // } //} }
public static string GetInputMeshFile(MapId map, int tileX, int tileY) { var tileName = TerrainConstants.GetTileName(tileX, tileY); return(WCellTerrainSettings.RecastInputMeshFolder + (int)map + "/" + tileName + RecastAPI.InputMeshExtension); }
/// <summary> /// The filename of extracted heightfields /// </summary> public static string GetFileName(MapId map, int tileX, int tileY) { var path = GetMapDirectory(map); return(Path.Combine(path, TerrainConstants.GetTileName(tileX, tileY) + FileExtension)); }