Esempio n. 1
0
        /// <summary>
        /// Generates a <see cref="NavMesh"/> given a collection of triangles and some settings.
        /// </summary>
        /// <param name="triangles">The triangles that form the level.</param>
        /// <param name="settings">The settings to generate with.</param>
        /// <returns>A <see cref="NavMesh"/>.</returns>
        public static NavMesh Generate(IEnumerable <Triangle3> triangles, NavMeshGenerationSettings settings)
        {
            BBox3 bounds = triangles.GetBoundingBox(settings.CellSize);
            var   hf     = new Heightfield(bounds, settings);

            hf.RasterizeTriangles(triangles);
            hf.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb);
            hf.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb);
            hf.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight);

            var chf = new CompactHeightfield(hf, settings);

            chf.Erode(settings.VoxelAgentRadius);
            chf.BuildDistanceField();
            chf.BuildRegions(2, settings.MinRegionSize, settings.MergedRegionSize);

            var cont = chf.BuildContourSet(settings);

            var polyMesh = new PolyMesh(cont, settings);

            var polyMeshDetail = new PolyMeshDetail(polyMesh, chf, settings);

            var buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new Pathfinding.OffMeshConnection[0], settings);

            var navMesh = new NavMesh(buildData);

            return(navMesh);
        }
Esempio n. 2
0
		/// <summary>
		/// Generates a <see cref="NavMesh"/> given a collection of triangles and some settings.
		/// </summary>
		/// <param name="triangles">The triangles that form the level.</param>
		/// <param name="settings">The settings to generate with.</param>
		/// <returns>A <see cref="NavMesh"/>.</returns>
		public static NavMesh Generate(IEnumerable<Triangle3> triangles, NavMeshGenerationSettings settings)
		{
			BBox3 bounds = triangles.GetBoundingBox(settings.CellSize);
			var hf = new Heightfield(bounds, settings);
			hf.RasterizeTriangles(triangles);
			hf.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb);
			hf.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb);
			hf.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight);

			var chf = new CompactHeightfield(hf, settings);
			chf.Erode(settings.VoxelAgentRadius);
			chf.BuildDistanceField();
			chf.BuildRegions(2, settings.MinRegionSize, settings.MergedRegionSize);

			var cont = chf.BuildContourSet(settings);

			var polyMesh = new PolyMesh(cont, settings);

			var polyMeshDetail = new PolyMeshDetail(polyMesh, chf, settings);

			var buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new Pathfinding.OffMeshConnection[0], settings);

			var navMesh = new NavMesh(buildData);
			return navMesh;
		}
Esempio n. 3
0
        private void GenerateNavMesh()
        {
            Console.WriteLine("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);

                Console.WriteLine("Heightfield");
                Console.WriteLine(" + 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);

                Console.WriteLine(" + Rasterization\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                Console.WriteLine(" + Filtering");
                prevMs = sw.ElapsedMilliseconds;

                heightfield.FilterLedgeSpans(settings.VoxelAgentHeight, settings.VoxelMaxClimb);

                Console.WriteLine("   + Ledge Spans\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                heightfield.FilterLowHangingWalkableObstacles(settings.VoxelMaxClimb);

                Console.WriteLine("   + Low Hanging Obstacles\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                heightfield.FilterWalkableLowHeightSpans(settings.VoxelAgentHeight);

                Console.WriteLine("   + Low Height Spans\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                compactHeightfield = new CompactHeightfield(heightfield, settings);

                Console.WriteLine("CompactHeightfield");
                Console.WriteLine(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                compactHeightfield.Erode(settings.VoxelAgentRadius);

                Console.WriteLine(" + Erosion\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                compactHeightfield.BuildDistanceField();

                Console.WriteLine(" + Distance Field\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                compactHeightfield.BuildRegions(0, settings.MinRegionSize, settings.MergedRegionSize);

                Console.WriteLine(" + Regions\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                Random r = new Random();
                regionColors = new Color4[compactHeightfield.MaxRegions];
                regionColors[0] = Color4.Black;
                for (int i = 1; i < regionColors.Length; i++)
                    regionColors[i] = new Color4((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255), 255);

                Console.WriteLine(" + Colors\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                contourSet = compactHeightfield.BuildContourSet(settings);

                Console.WriteLine("ContourSet");
                Console.WriteLine(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                polyMesh = new PolyMesh(contourSet, settings);

                Console.WriteLine("PolyMesh");
                Console.WriteLine(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                polyMeshDetail = new PolyMeshDetail(polyMesh, compactHeightfield, settings);

                Console.WriteLine("PolyMeshDetail");
                Console.WriteLine(" + Ctor\t\t\t\t" + (sw.ElapsedMilliseconds - prevMs).ToString("D3") + " ms");
                prevMs = sw.ElapsedMilliseconds;

                hasGenerated = true;

            }
            catch (Exception e)
            {
                if (!interceptExceptions)
                    throw;
                else
                    Console.WriteLine("Navmesh generation failed with exception:" + Environment.NewLine + e.ToString());
            }
            finally
            {
                sw.Stop();
            }

            if (hasGenerated)
            {
                try
                {
                    GeneratePathfinding();

                    //Pathfinding with multiple units
                    GenerateCrowd();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Pathfinding generation failed with exception" + Environment.NewLine + e.ToString());
                    hasGenerated = false;
                }

                Label l = (Label)statusBar.FindChildByName("GenTime");
                l.Text = "Generation Time: " + sw.ElapsedMilliseconds + "ms";

                Console.WriteLine("Navmesh generated successfully in " + sw.ElapsedMilliseconds + "ms.");
                Console.WriteLine("Rasterized " + level.GetTriangles().Length + " triangles.");
                Console.WriteLine("Generated " + contourSet.Count + " regions.");
                Console.WriteLine("PolyMesh contains " + polyMesh.VertCount + " vertices in " + polyMesh.PolyCount + " polys.");
                Console.WriteLine("PolyMeshDetail contains " + polyMeshDetail.VertCount + " vertices and " + polyMeshDetail.TrisCount + " tris in " + polyMeshDetail.MeshCount + " meshes.");
            }
        }
Esempio n. 4
0
		public void Filter_LowHangingWalkable_Success()
		{
			var hf = new Heightfield(new BBox3(Vector3.Zero, Vector3.One), 0.5f, 0.02f);
			var span = new Span(10, 15, Area.Default);
			var span2 = new Span(16, 20, Area.Null);

			hf[0].AddSpan(span);
			hf[0].AddSpan(span2);

			hf.FilterLowHangingWalkableObstacles(20);

			Assert.AreEqual(hf[0].Spans[0].Area, hf[0].Spans[1].Area);
		}
Esempio n. 5
0
		public void Filter_LowHangingWalkable_Fail()
		{
			var hf = new Heightfield(new BBox3(Vector3.Zero, Vector3.One), 0.5f, 0.02f);
			var span = new Span(1, 2, Area.Default);
			var span2 = new Span(10, 20, Area.Null);

			hf[2].AddSpan(span);
			hf[2].AddSpan(span2);

			//walkable step cannot cover the gap (difference between span2 maximum and span 1 maximum) so fail
			hf.FilterLowHangingWalkableObstacles(10);
			Assert.AreNotEqual(hf[0, 1].Spans[0].Area, hf[0, 1].Spans[1].Area);
		}