//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(); //} }
private void InitializeUI() { settings = NavMeshGenerationSettings.Default; areaSettings = new AreaIdGenerationSettings(); DockBase dock = new DockBase(gwenCanvas); dock.Dock = Pos.Fill; dock.SetSize(Width, Height); dock.RightDock.Width = 280; dock.BottomDock.Height = 150; statusBar = new StatusBar(gwenCanvas); Label genTime = new Label(statusBar); genTime.Name = "GenTime"; genTime.Text = "Generation Time: 0ms"; genTime.Dock = Pos.Left; LabeledCheckBox catchCheckBox = new LabeledCheckBox(statusBar); catchCheckBox.Text = "Intercept and log exceptions"; catchCheckBox.Dock = Pos.Right; catchCheckBox.CheckChanged += (s, e) => interceptExceptions = catchCheckBox.IsChecked; catchCheckBox.IsChecked = true; Base genBase = new Base(dock); dock.RightDock.TabControl.AddPage("NavMesh Generation", genBase); Button generateButton = new Button(genBase); generateButton.Text = "Generate!"; generateButton.Height = 30; generateButton.Dock = Pos.Top; generateButton.Pressed += (s, e) => GenerateNavMesh(); GroupBox displaySettings = new GroupBox(genBase); displaySettings.Text = "Display"; displaySettings.Dock = Pos.Top; displaySettings.Height = 60; Base levelCheckBase = new Base(displaySettings); levelCheckBase.Dock = Pos.Top; Label levelCheckLabel = new Label(levelCheckBase); levelCheckLabel.Text = "Level"; levelCheckLabel.Dock = Pos.Left; CheckBox levelCheckBox = new CheckBox(levelCheckBase); levelCheckBox.Dock = Pos.Right; levelCheckBox.Checked += (s, e) => displayLevel = true; levelCheckBox.UnChecked += (s, e) => displayLevel = false; levelCheckBox.IsChecked = true; levelCheckBase.SizeToChildren(); Base displayModeBase = new Base(displaySettings); displayModeBase.Dock = Pos.Top; displayModeBase.Padding = new Padding(0, 4, 0, 0); Label displayModeLabel = new Label(displayModeBase); displayModeLabel.Text = "Generation Step"; displayModeLabel.Dock = Pos.Left; displayModeLabel.Padding = new Padding(0, 0, 4, 0); ComboBox displayModes = new ComboBox(displayModeBase); displayModes.Dock = Pos.Top; displayModes.AddItem("None", "", DisplayMode.None); displayModes.AddItem("Heightfield", "", DisplayMode.Heightfield); displayModes.AddItem("Compact Heightfield", "", DisplayMode.CompactHeightfield); displayModes.AddItem("Distance Field", "", DisplayMode.DistanceField); displayModes.AddItem("Regions", "", DisplayMode.Regions); displayModes.AddItem("Contours", "", DisplayMode.Contours); displayModes.AddItem("Polygon Mesh", "", DisplayMode.PolyMesh); displayModes.AddItem("Polygon Mesh Detail", "", DisplayMode.PolyMeshDetail); displayModes.AddItem("Pathfinding", "", DisplayMode.Pathfinding); displayModes.AddItem("Crowd", "", DisplayMode.Crowd); displayModes.ItemSelected += (s, e) => displayMode = (DisplayMode)e.SelectedItem.UserData; displayModes.SelectByUserData(DisplayMode.PolyMeshDetail); displayModeBase.SizeToChildren(); displayModeBase.Height += 4; //accounts for the padding, GWEN.NET should do this const int leftMax = 125; const int rightMax = 20; GroupBox rsSettings = new GroupBox(genBase); rsSettings.Text = "Rasterization"; rsSettings.Dock = Pos.Top; rsSettings.Height = 90; var levelTris = level.GetTriangles(); BBox3 bounds = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length).GetBoundingBox(); Base maxTriSlope = CreateSliderOption(rsSettings, "Max Tri Slope:", 0.0001f, 3.14f, 3.14f, "N2", leftMax, rightMax, v => areaSettings.MaxTriSlope = v); Base minLevelHeight = CreateSliderOption(rsSettings, "Min Height:", bounds.Min.Y, bounds.Max.Y, bounds.Min.Y, "N0", leftMax, rightMax, v => areaSettings.MinLevelHeight = v); Base maxLevelHeight = CreateSliderOption(rsSettings, "Max Height:", bounds.Min.Y, bounds.Max.Y, bounds.Max.Y, "N0", leftMax, rightMax, v => areaSettings.MaxLevelHeight = v); GroupBox hfSettings = new GroupBox(genBase); hfSettings.Text = "Heightfield"; hfSettings.Dock = Pos.Top; hfSettings.Height = 112; Base cellSizeSetting = CreateSliderOption(hfSettings, "Cell Size:", 0.1f, 2.0f, 0.3f, "N2", leftMax, rightMax, v => settings.CellSize = v); Base cellHeightSetting = CreateSliderOption(hfSettings, "Cell Height:", 0.1f, 2f, 0.2f, "N2", leftMax, rightMax, v => settings.CellHeight = v); Base maxSlopeSetting = CreateSliderOption(hfSettings, "Max Climb:", 0.1f, 5.0f, 0.9f, "N0", leftMax, rightMax, v => settings.MaxClimb = v); Base maxHeightSetting = CreateSliderOption(hfSettings, "Max Height:", 0.1f, 5.0f, 2.0f, "N0", leftMax, rightMax, v => settings.AgentHeight = v); GroupBox chfSettings = new GroupBox(genBase); chfSettings.Text = "CompactHeightfield"; chfSettings.Dock = Pos.Top; chfSettings.Height = 38; Base erodeRadius = CreateSliderOption(chfSettings, "Erode Radius:", 0.0f, 5.0f, 0.6f, "N1", leftMax, rightMax, v => settings.AgentRadius = v); GroupBox regionSettings = new GroupBox(genBase); regionSettings.Text = "Region"; regionSettings.Dock = Pos.Top; regionSettings.Height = 65; Base minRegionSize = CreateSliderOption(regionSettings, "Min Region Size:", 0f, 150f, 8f, "N0", leftMax, rightMax, v => settings.MinRegionSize = (int)Math.Round(v)); Base mrgRegionSize = CreateSliderOption(regionSettings, "Merged Region Size:", 0f, 150f, 20f, "N0", leftMax, rightMax, v => settings.MergedRegionSize = (int)Math.Round(v)); GroupBox navMeshSettings = new GroupBox(genBase); navMeshSettings.Text = "NavMesh"; navMeshSettings.Dock = Pos.Top; navMeshSettings.Height = 90; Base maxEdgeLength = CreateSliderOption(navMeshSettings, "Max Edge Length:", 0f, 50f, 12f, "N0", leftMax, rightMax, v => settings.MaxEdgeLength = (int)Math.Round(v)); Base maxEdgeErr = CreateSliderOption(navMeshSettings, "Max Edge Error:", 0f, 3f, 1.8f, "N1", leftMax, rightMax, v => settings.MaxEdgeError = v); Base vertsPerPoly = CreateSliderOption(navMeshSettings, "Verts Per Poly:", 3f, 12f, 6f, "N0", leftMax, rightMax, v => settings.VertsPerPoly = (int)Math.Round(v)); GroupBox navMeshDetailSettings = new GroupBox(genBase); navMeshDetailSettings.Text = "NavMeshDetail"; navMeshDetailSettings.Dock = Pos.Top; navMeshDetailSettings.Height = 65; Base sampleDistance = CreateSliderOption(navMeshDetailSettings, "Sample Distance:", 0f, 16f, 6f, "N0", leftMax, rightMax, v => settings.SampleDistance = (int)Math.Round(v)); Base maxSampleError = CreateSliderOption(navMeshDetailSettings, "Max Sample Error:", 0f, 16f, 1f, "N0", leftMax, rightMax, v => settings.MaxSampleError = (int)Math.Round(v)); Base logBase = new Base(dock); dock.BottomDock.TabControl.AddPage("Log", logBase); ListBox logBox = new ListBox(logBase); logBox.Dock = Pos.Fill; logBox.AllowMultiSelect = false; logBox.EnableScroll(true, true); Console.SetOut(new GwenTextWriter(logBox)); }
private void InitializeUI() { settings = NavMeshGenerationSettings.Default; areaSettings = new AreaIdGenerationSettings(); DockBase dock = new DockBase(gwenCanvas); dock.Dock = Pos.Fill; dock.SetSize(Width, Height); dock.RightDock.Width = 280; dock.BottomDock.Height = 150; statusBar = new StatusBar(gwenCanvas); Label genTime = new Label(statusBar); genTime.Name = "GenTime"; genTime.Text = "Generation Time: 0ms"; genTime.Dock = Pos.Left; LabeledCheckBox catchCheckBox = new LabeledCheckBox(statusBar); catchCheckBox.Text = "Intercept and log exceptions"; catchCheckBox.Dock = Pos.Right; catchCheckBox.CheckChanged += (s, e) => interceptExceptions = catchCheckBox.IsChecked; catchCheckBox.IsChecked = true; Base genBase = new Base(dock); dock.RightDock.TabControl.AddPage("NavMesh Generation", genBase); Button generateButton = new Button(genBase); generateButton.Text = "Generate!"; generateButton.Height = 30; generateButton.Dock = Pos.Top; generateButton.Released += (s, e) => GenerateNavMesh(); Base clientBase = new Base(dock); dock.RightDock.TabControl.AddPage("Game Loading", clientBase); TextBox clientInput = new TextBox(clientBase); clientInput.Text = @"C:\Dark Age of Camelot1118L"; clientInput.Height = 30; clientInput.Dock = Pos.Top; Button clientButton = new Button(clientBase); clientButton.Text = "Load!"; clientButton.Height = 30; clientButton.Dock = Pos.Top; clientButton.Released += (s, e) => LoadClient(clientInput.Text); GroupBox displaySettings = new GroupBox(genBase); displaySettings.Text = "Display"; displaySettings.Dock = Pos.Top; displaySettings.Height = 85; Base levelCheckBase = new Base(displaySettings); levelCheckBase.Dock = Pos.Top; Label levelCheckLabel = new Label(levelCheckBase); levelCheckLabel.Text = "Level"; levelCheckLabel.Dock = Pos.Left; CheckBox levelCheckBox = new CheckBox(levelCheckBase); levelCheckBox.Dock = Pos.Right; levelCheckBox.Checked += (s, e) => displayLevel = true; levelCheckBox.UnChecked += (s, e) => displayLevel = false; levelCheckBox.IsChecked = true; levelCheckBase.SizeToChildren(); Base displayModeBase = new Base(displaySettings); displayModeBase.Dock = Pos.Top; displayModeBase.Padding = new Padding(0, 4, 0, 0); Label displayModeLabel = new Label(displayModeBase); displayModeLabel.Text = "Generation Step"; displayModeLabel.Dock = Pos.Left; displayModeLabel.Padding = new Padding(0, 0, 4, 0); ComboBox displayModes = new ComboBox(displayModeBase); displayModes.Dock = Pos.Top; displayModes.AddItem("None", "", DisplayMode.None); displayModes.AddItem("Heightfield", "", DisplayMode.Heightfield); displayModes.AddItem("Compact Heightfield", "", DisplayMode.CompactHeightfield); displayModes.AddItem("Distance Field", "", DisplayMode.DistanceField); displayModes.AddItem("Regions", "", DisplayMode.Regions); displayModes.AddItem("Contours", "", DisplayMode.Contours); displayModes.AddItem("Polygon Mesh", "", DisplayMode.PolyMesh); displayModes.AddItem("Polygon Mesh Detail", "", DisplayMode.PolyMeshDetail); displayModes.AddItem("NavMesh", "", DisplayMode.NavMesh); displayModes.AddItem("Pathfinding", "", DisplayMode.Pathfinding); displayModes.ItemSelected += (s, e) => displayMode = (DisplayMode)e.SelectedItem.UserData; displayModes.SelectByUserData(DisplayMode.PolyMeshDetail); displayModeBase.SizeToChildren(); displayModeBase.Height += 4; //accounts for the padding, GWEN.NET should do this Base ZoneSelectBase = new Base(displaySettings); ZoneSelectBase.Dock = Pos.Top; ZoneSelectBase.Padding = new Padding(0, 4, 0, 0); Label ZoneSelect = new Label(ZoneSelectBase); ZoneSelect.Text = "Select Zone"; ZoneSelect.Dock = Pos.Left; ZoneSelect.Padding = new Padding(0, 0, 4, 0); _levelDisplay = new ComboBox(ZoneSelectBase); _levelDisplay.Dock = Pos.Top; _levelDisplay.AddItem("--- None ---", "", -1); _levelDisplay.SelectByUserData(-1); ZoneSelectBase.SizeToChildren(); ZoneSelectBase.Height += 4; //accounts for the padding, GWEN.NET should do this const int leftMax = 125; const int rightMax = 20; GroupBox areaSetting = new GroupBox(genBase); areaSetting.Text = "Area"; areaSetting.Dock = Pos.Top; areaSetting.Height = 90; var levelTris = new [] { new Triangle3(new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0)) }; BBox3 bounds = TriangleEnumerable.FromTriangle(levelTris, 0, levelTris.Length).GetBoundingBox(); Base maxTriSlope = CreateSliderOption(areaSetting, "Max Tri Slope:", 0.0001f, 3.14f, 3.14f, "N2", leftMax, rightMax, v => areaSettings.MaxTriSlope = v); Base minLevelHeight = CreateSliderOption(areaSetting, "Min Height:", bounds.Min.Y, bounds.Max.Y, bounds.Min.Y, "N0", leftMax, rightMax, v => areaSettings.MinLevelHeight = v); Base maxLevelHeight = CreateSliderOption(areaSetting, "Max Height:", bounds.Min.Y, bounds.Max.Y, bounds.Max.Y, "N0", leftMax, rightMax, v => areaSettings.MaxLevelHeight = v); _levelDisplay.ItemSelected += (s, e) => { _levelId = (int)e.SelectedItem.UserData; areaSetting.RemoveChild(minLevelHeight, true); areaSetting.RemoveChild(maxLevelHeight, true); bounds = _level != null ? _level.BoundingBox : TriangleEnumerable.FromTriangle(new [] { new Triangle3 { A = new Vector3(0, 0, 0), B = new Vector3(0, 0, 0), C = new Vector3(0, 0, 0) } }, 0, 1).GetBoundingBox(); minLevelHeight = CreateSliderOption(areaSetting, "Min Height:", bounds.Min.Y, bounds.Max.Y, bounds.Min.Y, "N0", leftMax, rightMax, v => areaSettings.MinLevelHeight = v); maxLevelHeight = CreateSliderOption(areaSetting, "Max Height:", bounds.Min.Y, bounds.Max.Y, bounds.Max.Y, "N0", leftMax, rightMax, v => areaSettings.MaxLevelHeight = v); }; GroupBox rsSettings = new GroupBox(genBase); rsSettings.Text = "Rasterization"; rsSettings.Dock = Pos.Top; rsSettings.Height = 90; Base cellSizeSetting = CreateSliderOption(rsSettings, "Cell Size:", 0.001f, 2.0f, 0.125f, "N3", leftMax, rightMax, v => settings.CellSize = v); Base cellHeightSetting = CreateSliderOption(rsSettings, "Cell Height:", 0.001f, 2f, 0.063f, "N3", leftMax, rightMax, v => settings.CellHeight = v); GroupBox agentSettings = new GroupBox(genBase); agentSettings.Text = "Agent"; agentSettings.Dock = Pos.Top; agentSettings.Height = 115; Base maxSlopeSetting = CreateSliderOption(agentSettings, "Max Climb:", 0.001f, 5.0f, 1.500f, "N3", leftMax, rightMax, v => settings.MaxClimb = v); Base maxHeightSetting = CreateSliderOption(agentSettings, "Height:", 0.001f, 2.0f, 0.250f, "N3", leftMax, rightMax, v => { settings.AgentHeight = v; agentCylinder.Height = v; }); Base erodeRadius = CreateSliderOption(agentSettings, "Radius:", 0.001f, 1.0f, 0.125f, "N3", leftMax, rightMax, v => { settings.AgentRadius = v; agentCylinder.Radius = v; }); Base addRemoveAgent = CreateAddRemoveButton(agentSettings, "Count", leftMax, rightMax, 0, MAX_AGENTS, () => { numActiveAgents++; GenerateCrowd(); }, () => { numActiveAgents--; GenerateCrowd(); }); GroupBox regionSettings = new GroupBox(genBase); regionSettings.Text = "Region"; regionSettings.Dock = Pos.Top; regionSettings.Height = 65; Base minRegionSize = CreateSliderOption(regionSettings, "Min Region Size:", 0f, 150f, 8f, "N0", leftMax, rightMax, v => settings.MinRegionSize = (int)Math.Round(v)); Base mrgRegionSize = CreateSliderOption(regionSettings, "Merged Region Size:", 0f, 150f, 20f, "N0", leftMax, rightMax, v => settings.MergedRegionSize = (int)Math.Round(v)); GroupBox navMeshSettings = new GroupBox(genBase); navMeshSettings.Text = "NavMesh"; navMeshSettings.Dock = Pos.Top; navMeshSettings.Height = 90; Base maxEdgeLength = CreateSliderOption(navMeshSettings, "Max Edge Length:", 0f, 50f, 12f, "N0", leftMax, rightMax, v => settings.MaxEdgeLength = (int)Math.Round(v)); Base maxEdgeErr = CreateSliderOption(navMeshSettings, "Max Edge Error:", 0f, 3f, 1.8f, "N1", leftMax, rightMax, v => settings.MaxEdgeError = v); Base vertsPerPoly = CreateSliderOption(navMeshSettings, "Verts Per Poly:", 3f, 12f, 6f, "N0", leftMax, rightMax, v => settings.VertsPerPoly = (int)Math.Round(v)); GroupBox navMeshDetailSettings = new GroupBox(genBase); navMeshDetailSettings.Text = "NavMeshDetail"; navMeshDetailSettings.Dock = Pos.Top; navMeshDetailSettings.Height = 65; Base sampleDistance = CreateSliderOption(navMeshDetailSettings, "Sample Distance:", 0f, 16f, 6f, "N0", leftMax, rightMax, v => settings.SampleDistance = (int)Math.Round(v)); Base maxSampleError = CreateSliderOption(navMeshDetailSettings, "Max Sample Error:", 0f, 16f, 1f, "N0", leftMax, rightMax, v => settings.MaxSampleError = (int)Math.Round(v)); Base logBase = new Base(dock); dock.BottomDock.TabControl.AddPage("Log", logBase); ListBox logBox = new ListBox(logBase); logBox.Dock = Pos.Fill; logBox.AllowMultiSelect = false; logBox.EnableScroll(true, true); Console.SetOut(new GwenTextWriter(logBox)); }
public void SetAdjacentBoundry(NavCellBoundry adjacent, NavMeshGenerationSettings settings) { if (adjacent == null) { connections = null; islandsToIslands = null; return; } else { lock (adjacentBoundryCalculationLock) lock (adjacent.adjacentBoundryCalculationLock) { // set adjacent connection this.connectedBoundry = adjacent; adjacent.connectedBoundry = this; // create maps for algorithm Dictionary <NavQuad, List <int> > thisToThatMap = new Dictionary <NavQuad, List <int> >(); Dictionary <NavQuad, List <int> > thatToThisMap = new Dictionary <NavQuad, List <int> >(); Dictionary <NavigationIsland, List <NavigationIsland> > thisToThatIslands = new Dictionary <NavigationIsland, List <NavigationIsland> >(); Dictionary <NavigationIsland, List <NavigationIsland> > thatToThisIslands = new Dictionary <NavigationIsland, List <NavigationIsland> >(); // intialize maps foreach (var quad in this.quads) { thisToThatMap.Add(quad, new List <int>()); } foreach (var quad in adjacent.quads) { thatToThisMap.Add(quad, new List <int>()); } // The multiplication by 0.999999 helps combat floating point rounding errors float requiredWidth = settings.orientation.VoxelSize * 0.5f; float requiredHeight = settings.crouchHeightInVoxels * settings.orientation.VoxelSize * 0.5f; for (int i = 0; i < quads.Length; i++) { NavQuad thisQuad = quads[i]; for (int j = 0; j < adjacent.quads.Length; j++) { NavQuad otherQuad = adjacent.quads[j]; if (NavQuad.IsOverlappingVertical(thisQuad, otherQuad, requiredWidth, requiredHeight)) { float aHeight = thisQuad.position.y - thisQuad.scale.y * 0.5f; float bHeight = otherQuad.position.y - otherQuad.scale.y * 0.5f; if (settings.CanClimbTo(aHeight, bHeight)) { thisToThatMap[thisQuad].Add(j); } else if (settings.CanDropTo(aHeight, bHeight)) { thisToThatMap[thisQuad].Add(j); } if (settings.CanClimbTo(bHeight, aHeight)) { thatToThisMap[otherQuad].Add(i); } else if (settings.CanDropTo(bHeight, aHeight)) { thatToThisMap[otherQuad].Add(i); } } } } connections = thisToThatMap.ToDictionary(x => x.Key, x => x.Value.ToArray()); adjacent.connections = thatToThisMap.ToDictionary(x => x.Key, x => x.Value.ToArray()); // link this boundries islands to that boundries islands foreach (var quad in this.quads) { var thisIsland = boundryQuadsToIslands[quad]; // ensure map contains island if (!thisToThatIslands.ContainsKey(thisIsland)) { thisToThatIslands.Add(thisIsland, new List <NavigationIsland>()); } // add link in map var thisList = thisToThatIslands[thisIsland]; foreach (var other in GetConnectedQuads(quad)) { // get islands var otherIsland = adjacent.boundryQuadsToIslands[other]; if (!thisList.Contains(otherIsland)) { thisList.Add(otherIsland); } } } // link that boundries islands to this boundries islands foreach (var other in adjacent.quads) { var otherIsland = adjacent.boundryQuadsToIslands[other]; // ensure map contains island if (!thatToThisIslands.ContainsKey(otherIsland)) { thatToThisIslands.Add(otherIsland, new List <NavigationIsland>()); } var otherList = thatToThisIslands[otherIsland]; foreach (var quad in adjacent.GetConnectedQuads(other)) { // get islands var thisIsland = boundryQuadsToIslands[quad]; // add link in map if (!otherList.Contains(thisIsland)) { otherList.Add(thisIsland); } } } this.islandsToIslands = thisToThatIslands; adjacent.islandsToIslands = thatToThisIslands; } } }
public Coroutine Generate(NavMeshGenerationSettings generationSettings) { return(Cell.Generate(collidersInCell.ToArray(), generationSettings)); }
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; }