示例#1
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();
            //}
        }
示例#2
0
        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));
        }
示例#3
0
        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));
        }
示例#4
0
    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));
 }
示例#6
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;
		}