예제 #1
0
        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);
        }
예제 #2
0
        //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();
            //}
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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.");
            }
        }
예제 #6
0
        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!");
        }
예제 #7
0
		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;
		}