public NavMeshBuilder GenerateNavmesh(BBox3 bbox) { float[] vertices; int[] indices; AreaId[] areas; GetRawData(out vertices, out indices, out areas); var settings = WoWSettings; var hf = new Heightfield(bbox, settings); hf.RasterizeTrianglesWithAreas(vertices, areas); hf.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb); hf.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb); hf.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight); var chf = new CompactHeightfield(hf, settings); chf.Erode(settings.VoxelAgentWidth); chf.BuildDistanceField(); chf.BuildRegions((int)(settings.AgentWidth / settings.CellSize) + 8, settings.MinRegionSize, settings.MergedRegionSize); var cset = new ContourSet(chf, settings); var pmesh = new PolyMesh(cset, settings); var dmesh = new PolyMeshDetail(pmesh, chf, settings); var buildData = new NavMeshBuilder(pmesh, dmesh, new SharpNav.Pathfinding.OffMeshConnection[0], settings); return(buildData); }
//private void GenerateNavMesh() //{ // Console.WriteLine("Generating NavMesh"); // long prevMs = 0; // try // { // var levelTris = level.GetTriangles(); // var triEnumerable = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length); // BBox3 bounds = triEnumerable.GetBoundingBox(); // settings = NavMeshGenerationSettings.Default; // heightfield = new Heightfield(bounds, settings); // heightfield.RasterizeTriangles(levelTris, Area.Default); // heightfield.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb); // heightfield.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb); // heightfield.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight); // compactHeightfield = new CompactHeightfield(heightfield, settings); // compactHeightfield.Erode(settings.VoxelAgentRadius); // compactHeightfield.BuildDistanceField(); // compactHeightfield.BuildRegions(0, settings.MinRegionSize, settings.MergedRegionSize); // contourSet = compactHeightfield.BuildContourSet(settings); // polyMesh = new PolyMesh(contourSet, settings); // polyMeshDetail = new PolyMeshDetail(polyMesh, compactHeightfield, settings); // buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings); // tiledNavMesh = new TiledNavMesh(buildData); // navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048); // } // catch (Exception e) // { // //if (!interceptExceptions) // // throw; // //else // // Console.WriteLine("Navmesh generation failed with exception:" + Environment.NewLine + e.ToString()); // } // finally // { // //sw.Stop(); // } //} private void GenerateNavMesh() { Console.WriteLine("Generating NavMesh"); long prevMs = 0; //try //{ var levelTris = level.GetTriangles(); var triEnumerable = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length); BBox3 bounds = triEnumerable.GetBoundingBox(); settings = NavMeshGenerationSettings.Default; heightfield = new Heightfield(bounds, settings); heightfield.RasterizeTriangles(levelTris, Area.Default); heightfield.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb); heightfield.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb); heightfield.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight); compactHeightfield = new CompactHeightfield(heightfield, settings); compactHeightfield.Erode(settings.VoxelAgentRadius); compactHeightfield.BuildDistanceField(); compactHeightfield.BuildRegions(0, settings.MinRegionSize, settings.MergedRegionSize); contourSet = compactHeightfield.BuildContourSet(settings); polyMesh = new PolyMesh(contourSet, settings); polyMeshDetail = new PolyMeshDetail(polyMesh, compactHeightfield, settings); buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings); tiledNavMesh = new TiledNavMesh(buildData); navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048); OutMesh(); //} //catch (Exception e) //{ // //if (!interceptExceptions) // // throw; // //else // // Console.WriteLine("Navmesh generation failed with exception:" + Environment.NewLine + e.ToString()); //} //finally //{ // //sw.Stop(); //} }
public void Filter_WalkableLowHeight_Success() { var hf = new Heightfield(new BBox3(Vector3.Zero, Vector3.One), 0.5f, 0.02f); var span = new Span(10, 20, Area.Default); var span2 = new Span(25, 30, Area.Default); hf[0].AddSpan(span); hf[0].AddSpan(span2); //too low to walk through. there is only a gap of 5 units to walk through, //but at least 15 units is needed hf.FilterWalkableLowHeightSpans(15); //so one span is unwalkable and the other is fine Assert.AreEqual(hf[0].Spans[0].Area, Area.Null); Assert.AreEqual(hf[0].Spans[1].Area, Area.Default); }
public NavMeshBuilder Build() { // Generate tile data LoadTileData(); // Extract raw data from geometry float[] vertices; int[] indices; s_Geometry.GetRawData(out vertices, out indices /*, out areas*/); var hf = new Heightfield(Bounds, NavmeshSettings); hf.RasterizeTriangles(vertices, Area.Default); hf.FilterLedgeSpans(NavmeshSettings.VoxelAgentHeight, NavmeshSettings.VoxelMaxClimb); hf.FilterLowHangingWalkableObstacles(NavmeshSettings.VoxelMaxClimb); hf.FilterWalkableLowHeightSpans(NavmeshSettings.VoxelAgentHeight); var chf = new CompactHeightfield(hf, NavmeshSettings); chf.Erode(NavmeshSettings.VoxelAgentRadius); chf.BuildDistanceField(); chf.BuildRegions((int)(NavmeshSettings.AgentRadius / NavmeshSettings.CellSize) + 8, NavmeshSettings.MinRegionSize, NavmeshSettings.MergedRegionSize); var cset = chf.BuildContourSet(NavmeshSettings); var pmesh = new PolyMesh(cset, NavmeshSettings); var dmesh = new PolyMeshDetail(pmesh, chf, NavmeshSettings); var buildData = new NavMeshBuilder(pmesh, dmesh, new SharpNav.Pathfinding.OffMeshConnection[0], NavmeshSettings); Console.WriteLine("Rasterized " + vertices.Length / 9 + " triangles."); Console.WriteLine("Generated " + cset.Count + " regions."); Console.WriteLine("PolyMesh contains " + pmesh.VertCount + " vertices in " + pmesh.PolyCount + " polys."); Console.WriteLine("PolyMeshDetail contains " + dmesh.VertCount + " vertices and " + dmesh.TrisCount + " tris in " + dmesh.MeshCount + " meshes."); return(buildData); }
private void GenerateNavMesh() { //Debug.Log("Generating NavMesh"); Stopwatch sw = new Stopwatch(); sw.Start(); long prevMs = 0; try { //level.SetBoundingBoxOffset(new SVector3(settings.CellSize * 0.5f, settings.CellHeight * 0.5f, settings.CellSize * 0.5f)); var levelTris = level.GetTriangles(); var triEnumerable = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length); BBox3 bounds = triEnumerable.GetBoundingBox(); heightfield = new Heightfield(bounds, settings); //Debug.Log("Heightfield"); //Debug.Log(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; /*Area[] areas = AreaGenerator.From(triEnumerable, Area.Default) * .MarkAboveHeight(areaSettings.MaxLevelHeight, Area.Null) * .MarkBelowHeight(areaSettings.MinLevelHeight, Area.Null) * .MarkBelowSlope(areaSettings.MaxTriSlope, Area.Null) * .ToArray(); * heightfield.RasterizeTrianglesWithAreas(levelTris, areas);*/ heightfield.RasterizeTriangles(levelTris, Area.Default); //Debug.Log(" + Rasterization\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); //Debug.Log(" + Filtering"); prevMs = sw.ElapsedMilliseconds; heightfield.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb); //Debug.Log(" + Ledge Spans\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; heightfield.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb); //Debug.Log(" + Low Hanging Obstacles\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; heightfield.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight); //Debug.Log(" + Low Height Spans\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; compactHeightfield = new CompactHeightfield(heightfield, settings); //Debug.Log("CompactHeightfield"); //Debug.Log(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; compactHeightfield.Erode(settings.VoxelAgentRadius); //Debug.Log(" + Erosion\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; compactHeightfield.BuildDistanceField(); //Debug.Log(" + Distance Field\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; compactHeightfield.BuildRegions(0, settings.MinRegionSize, settings.MergedRegionSize); //Debug.Log(" + Regions\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; contourSet = compactHeightfield.BuildContourSet(settings); //Debug.Log("ContourSet"); //Debug.Log(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; polyMesh = new PolyMesh(contourSet, settings); //Debug.Log("PolyMesh"); //Debug.Log(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; polyMeshDetail = new PolyMeshDetail(polyMesh, compactHeightfield, settings); //Debug.Log("PolyMeshDetail"); //Debug.Log(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms"); prevMs = sw.ElapsedMilliseconds; hasGenerated = true; } catch (Exception e) { if (!interceptExceptions) { throw; } else { //Debug.Log("Navmesh generation failed with exception:" + Environment.NewLine + e.ToString()); } } finally { sw.Stop(); } if (hasGenerated) { try { GeneratePathfinding(); //Pathfinding with multiple units //GenerateCrowd(); } catch (Exception e) { //Debug.Log("Pathfinding generation failed with exception" + Environment.NewLine + e.ToString()); hasGenerated = false; } //Label l = (Label)statusBar.FindChildByName("GenTime"); //l.Text = "Generation Time: " + sw.ElapsedMilliseconds + "ms"; //Debug.Log("Navmesh generated successfully in " + sw.ElapsedMilliseconds + "ms."); //Debug.Log("Rasterized " + level.GetTriangles().Length + " triangles."); //Debug.Log("Generated " + contourSet.Count + " regions."); //Debug.Log("PolyMesh contains " + polyMesh.VertCount + " vertices in " + polyMesh.PolyCount + " polys."); //Debug.Log("PolyMeshDetail contains " + polyMeshDetail.VertCount + " vertices and " + polyMeshDetail.TrisCount + " tris in " + polyMeshDetail.MeshCount + " meshes."); } }
public void GenNavMesh() { // MeshCollider List <Triangle3> colliderTringles = new List <Triangle3>(); Collider[] colliders = GameObject.FindObjectsOfType <Collider>(); List <GameObject> destroyGos = new List <GameObject>(); foreach (Collider collider in colliders) { Mesh mesh = null; Matrix4x4 localToWorldMatrix = Matrix4x4.identity; if (collider is MeshCollider) { MeshCollider mc = collider as MeshCollider; mesh = mc.sharedMesh; localToWorldMatrix = mc.transform.localToWorldMatrix; } if (collider is BoxCollider) { BoxCollider bc = collider as BoxCollider; GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); mesh = go.GetComponent <MeshFilter>().sharedMesh; go.transform.parent = collider.transform; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = bc.center; go.transform.localScale = bc.size; localToWorldMatrix = go.transform.localToWorldMatrix; destroyGos.Add(go); } if (null != mesh) { UnityEngine.Vector3[] vertices = mesh.vertices; for (int i = 0; i < mesh.subMeshCount; ++i) { var subMesh = mesh.GetIndices(i); for (int j = 0; j < subMesh.Length; j += 3) { UnityEngine.Vector3 a = localToWorldMatrix.MultiplyPoint(vertices[subMesh[j]]); UnityEngine.Vector3 b = localToWorldMatrix.MultiplyPoint(vertices[subMesh[j + 1]]); UnityEngine.Vector3 c = localToWorldMatrix.MultiplyPoint(vertices[subMesh[j + 2]]); colliderTringles.Add(new Triangle3(ConvertVector3(a), ConvertVector3(b), ConvertVector3(c))); } } } } foreach (var go in destroyGos) { GameObject.DestroyImmediate(go); } destroyGos.Clear(); Triangle3[] levelTris = colliderTringles.ToArray(); var triEnumerable = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length); BBox3 bounds = triEnumerable.GetBoundingBox(); heightfield = new Heightfield(bounds, settings); heightfield.RasterizeTriangles(levelTris, Area.Default); heightfield.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb); heightfield.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb); heightfield.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight); compactHeightfield = new CompactHeightfield(heightfield, settings); compactHeightfield.Erode(settings.VoxelAgentRadius); compactHeightfield.BuildDistanceField(); compactHeightfield.BuildRegions(0, settings.MinRegionSize, settings.MergedRegionSize); contourSet = compactHeightfield.BuildContourSet(settings); polyMesh = new PolyMesh(contourSet, settings); polyMeshDetail = new PolyMeshDetail(polyMesh, compactHeightfield, settings); buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings); tiledNavMesh = new TiledNavMesh(buildData); navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048); { System.Random r = new System.Random(); regionColors = new Color[compactHeightfield.MaxRegions]; regionColors[0] = Color.black; for (int i = 1; i < regionColors.Length; i++) { regionColors[i] = new Color((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255), 255); } } this.GenDrawMesh(); Debug.Log("GenNavMesh Done!"); }
public bool BuildNavMesh( out string error ) { DestroyNavMesh(); if( !EnabledInHierarchy ) { error = "Is not enabled."; return false; } //get geometry data var collector = GetAllGeometriesForNavigationMesh(); Vector3[] vertices = collector.resultVertices; int[] indices = collector.resultIndices; int vertexCount = collector.resultVertexCount; int indexCount = collector.resultIndexCount; if( vertexCount == 0 ) { error = "No vertices were gathered from collision objects."; return false; } //get settings var settings = new NavMeshGenerationSettings(); settings.CellSize = (float)CellSize; settings.CellHeight = (float)CellHeight; settings.MaxClimb = (float)AgentMaxClimb; settings.AgentHeight = (float)AgentHeight; settings.AgentRadius = (float)AgentRadius; settings.MinRegionSize = MinRegionSize; settings.MergedRegionSize = MergedRegionSize; settings.MaxEdgeLength = MaxEdgeLength; settings.MaxEdgeError = (float)MaxEdgeError; settings.VertsPerPoly = MaxVerticesPerPolygon; settings.SampleDistance = DetailSampleDistance; settings.MaxSampleError = DetailMaxSampleError; settings.BuildBoundingVolumeTree = true; TiledNavMesh newTiledNavMesh; try { //level.SetBoundingBoxOffset(new SVector3(settings.CellSize * 0.5f, settings.CellHeight * 0.5f, settings.CellSize * 0.5f)); var bounds = Bounds.Cleared; bounds.Add( vertices ); var heightfield = new Heightfield( ToSharpNav( bounds ), settings ); var vertices2 = new SharpNav.Geometry.Vector3[ indexCount ]; for( int index = 0; index < indexCount; index++ ) vertices2[ index ] = ToSharpNav( vertices[ indices[ index ] ] ); //Area[] areas = AreaGenerator.From( vertices2, Area.Default ) // .MarkBelowSlope( (float)AgentMaxSlope.Value.InRadians(), Area.Null ) // .ToArray(); //Area[] areas = AreaGenerator.From(triEnumerable, Area.Default) // .MarkAboveHeight(areaSettings.MaxLevelHeight, Area.Null) // .MarkBelowHeight(areaSettings.MinLevelHeight, Area.Null) // .MarkBelowSlope(areaSettings.MaxTriSlope, Area.Null) // .ToArray(); //heightfield.RasterizeTrianglesWithAreas( vertices2, areas ); heightfield.RasterizeTriangles( vertices2, Area.Default ); heightfield.FilterLedgeSpans( settings.VoxelAgentHeight, settings.VoxelMaxClimb ); heightfield.FilterLowHangingWalkableObstacles( settings.VoxelMaxClimb ); heightfield.FilterWalkableLowHeightSpans( settings.VoxelAgentHeight ); var compactHeightfield = new CompactHeightfield( heightfield, settings ); compactHeightfield.Erode( settings.VoxelAgentRadius ); compactHeightfield.BuildDistanceField(); compactHeightfield.BuildRegions( 0, settings.MinRegionSize, settings.MergedRegionSize ); //!!!! System.Random r = new System.Random(); var regionColors = new ColorByte[ compactHeightfield.MaxRegions ]; regionColors[ 0 ] = new ColorByte( 0, 0, 0 ); for( int i = 1; i < regionColors.Length; i++ ) regionColors[ i ] = new ColorByte( (byte)r.Next( 0, 255 ), (byte)r.Next( 0, 255 ), (byte)r.Next( 0, 255 ), (byte)255 ); var contourSet = compactHeightfield.BuildContourSet( settings ); var polyMesh = new PolyMesh( contourSet, settings ); var polyMeshDetail = new PolyMeshDetail( polyMesh, compactHeightfield, settings ); var buildData = new NavMeshBuilder( polyMesh, polyMeshDetail, new OffMeshConnection[ 0 ], settings ); newTiledNavMesh = new TiledNavMesh( buildData ); //!!!! ////Pathfinding with multiple units //GenerateCrowd(); } catch( Exception e ) { DestroyNavMesh(); error = e.Message; return false; } int dataLength; byte[] data; using( var memoryStream = new MemoryStream() ) { var serializer = new NavMeshBinarySerializer(); serializer.Serialize( memoryStream, newTiledNavMesh ); dataLength = (int)memoryStream.Length; data = memoryStream.GetBuffer(); } //generate nav mesh data var writer = new ArrayDataWriter(); writer.Write( navMeshDataVersion ); writer.Write( dataLength ); writer.Write( data, 0, dataLength ); //set NavMeshData and init var newNavMeshData = new byte[ writer.BitLength / 8 ]; Buffer.BlockCopy( writer.Data, 0, newNavMeshData, 0, newNavMeshData.Length ); NavMeshData = newNavMeshData; error = ""; return true; }