public static void Render(Nav.ExploreCell cell, float radius, PointF trans, PaintEventArgs e, bool draw_connections, bool draw_id) { DrawRectangle(e.Graphics, Pens.Magenta, trans, cell.Min, cell.Max); //DrawString(e.Graphics, Brushes.Black, trans, cell.Position, Math.Round(cell.CellsArea()).ToString(), 14); if (cell.Explored) { //DrawLine(e.Graphics, explored_pen, trans, cell.Min, cell.Max); //DrawLine(e.Graphics, explored_pen, trans, new Vec3(cell.Min.X, cell.Max.Y), new Vec3(cell.Max.X, cell.Min.Y)); FillRectangle(e.Graphics, explored_brush, trans, cell.Min, cell.Max); } else { //DrawCircle(e.Graphics, Pens.Red, trans, cell.Position, radius); //DrawString(e.Graphics, Brushes.Black, trans, cell.Position, cell.UserData.ToString(), 10); if (draw_connections) { foreach (Nav.Cell.Neighbour neighbour in cell.Neighbours) { ExploreCell neighbour_cell = (ExploreCell)neighbour.cell; DrawLine(e.Graphics, EXPLORE_CELL_CONNECTION_PEN, trans, cell.Position, neighbour_cell.Position); } } if (draw_id) { DrawString(e.Graphics, Brushes.Black, trans, cell.Position, cell.Id.ToString(), 10); } } }
protected override void OnCellExplored(ExploreCell cell) { base.OnCellExplored(cell); using (new WriteLock(ExplorePathDataLock)) ExplorePath.Remove(cell.Position); }
internal override ExploreCell GetDestinationCell() { ExploreCell dest_cell = base.GetDestinationCell(); if (dest_cell != null) { return(dest_cell); } ExploreCell current_explore_cell = GetCurrentExploreCell(); if (current_explore_cell == null) { return(current_explore_cell); } if (!current_explore_cell.Explored) { return(current_explore_cell); } HashSet <ExploreCell> unexplored_cells = GetUnexploredCells(current_explore_cell); ExploreCellSelector selector = CreateExploreCellSelector(); using (new ReadLock(DataLock)) Algorihms.VisitBreadth(current_explore_cell, MovementFlag.None, -1, unexplored_cells, selector); if (selector.dest_cell != null) { return(selector.dest_cell); } return(null); }
protected override ExploreCell GetDestinationCell(ExploreCell curr_explore_cell) { if (curr_explore_cell == null) { curr_explore_cell = GetCurrentExploreCell(); } if (curr_explore_cell == null) { return(curr_explore_cell); } if (!curr_explore_cell.Explored) { return(curr_explore_cell); } HashSet <ExploreCell> unexplored_cells = GetUnexploredCells(curr_explore_cell); if (unexplored_cells.Count > 0) { ExploreCellSelector selector = CreateExploreCellSelector(); using (new ReadLock(DataLock)) Algorihms.VisitBreadth(curr_explore_cell, MovementFlag.None, -1, unexplored_cells, selector); if (selector.dest_cell != null) { return(selector.dest_cell); } } return(null); }
private float GetExploredNeighboursPct(ExploreCell cell, int max_depth) { List<ExploreCell> cells_group = new List<ExploreCell>(); Algorihms.Visit(cell, ref cells_group, Navmesh.Navigator.MovementFlags, true, 0, max_depth, m_ExploreCells); //treat missing cells as explored thus explore edges to possibly load new navmesh data int max_cells_num = (int)Math.Pow(9, max_depth); int missing_cells = Math.Max(0, max_cells_num - cells_group.Count); return (float)(cells_group.Count(x => ((ExploreCell)x).Explored) + missing_cells) / (float)max_cells_num; }
private float GetExploredNeighboursPct(ExploreCell cell, int max_depth) { List <ExploreCell> cells_group = new List <ExploreCell>(); Algorihms.Visit(cell, ref cells_group, Navmesh.Navigator.MovementFlags, true, 0, max_depth, m_ExploreCells); //treat missing cells as explored thus explore edges to possibly load new navmesh data int max_cells_num = (int)Math.Pow(9, max_depth); int missing_cells = Math.Max(0, max_cells_num - cells_group.Count); return((float)(cells_group.Count(x => ((ExploreCell)x).Explored) + missing_cells) / (float)max_cells_num); }
private void UpdateExplorePath() { if (Navmesh == null) { return; } List <Vec3> new_explore_path = new List <Vec3>(); using (new ReadLock(DataLock)) { ExploreCell start_cell = null; Vec3 current_pos_copy = Navmesh.Navigator.CurrentPos; if (!current_pos_copy.IsEmpty) { List <ExploreCell> containing_cells = m_ExploreCells.FindAll(c => c.Contains2D(current_pos_copy) && c.Neighbours.Count > 0); float min_dist = float.MaxValue; foreach (ExploreCell e_cell in containing_cells) { foreach (Cell cell in e_cell.Cells) { float dist = cell.AABB.Distance2D(current_pos_copy); if (dist < min_dist) { start_cell = e_cell; min_dist = dist; } } } } if (start_cell == null) { return; } Algorihms.FindExplorePath2Opt(start_cell, m_ExploreCells, m_ExploreCellsDistancer, ref new_explore_path); } using (new WriteLock(ExplorePathDataLock)) { ExplorePath = new_explore_path; m_ExplorePathCalculated = true; } RequestExplorationUpdate(); }
internal override Vec3 GetDestinationCellPosition() { ExploreCell current_explore_cell = m_ExploreCells.Find(x => x.CellsContains2D(Navmesh.Navigator.CurrentPos)); // visit 'unexplored' cells on the way if (current_explore_cell != null && !current_explore_cell.Explored) { return(current_explore_cell.Position); } else { using (new ReadLock(ExplorePathDataLock, true)) return(ExplorePath.Count > 0 ? ExplorePath[0] : Vec3.Empty); } }
internal override Vec3 GetDestinationCellPosition() { Vec3 dest = base.GetDestinationCellPosition(); if (!dest.IsEmpty) { return(dest); } ExploreCell current_explore_cell = GetCurrentExploreCell(); if (current_explore_cell == null) { return(Vec3.Empty); } if (!current_explore_cell.Explored) { return(current_explore_cell.Position); } List <int> unexplored_cells_id = GetUnexploredCellsId(current_explore_cell); ExploreCell dest_cell = null; float dest_cell_distance = float.MaxValue; //const float DISTANCE_REDUCTION_PER_EXPLORED_NEIGHBOUR = 15; //const float DISTANCE_REDUCTION_PER_MISSING_NEIGHBOUR = 10; const float DISTANCE_REDUCTION_EXPLORE_PCT = 500; //const float DISTANCE_PCT_REDUCTION_PER_EXPLORED_NEIGHBOUR = 0.06f; //const float DISTANCE_PCT_REDUCTION_PER_MISSING_NEIGHBOUR = 0.05f; //const int AVG_NEIGHBOURS_COUNT = 8; foreach (int cell_id in unexplored_cells_id) { float base_dist = m_ExploreCellsDistancer.GetDistance(current_explore_cell.GlobalId, cell_id); //base_dist *= base_dist; // increase distance significance ExploreCell cell = m_ExploreCells.Find(x => x.GlobalId == cell_id); // decrease distance based on number of explored neighbours (do not leave small unexplored fragments) //int explored_neighbours_count = GetExploredNeighbours(cell, 2); //int missing_neighbours_count = Math.Max(0, AVG_NEIGHBOURS_COUNT - cell.Neighbours.Count); float dist = base_dist; dist -= DISTANCE_REDUCTION_EXPLORE_PCT * GetExploredNeighboursPct(cell, 1); //dist -= DISTANCE_REDUCTION_PER_EXPLORED_NEIGHBOUR * (float)explored_neighbours_count; //dist -= DISTANCE_REDUCTION_PER_MISSING_NEIGHBOUR * Math.Max(0, AVG_NEIGHBOURS_COUNT - cell.Neighbours.Count); //dist -= base_dist * DISTANCE_PCT_REDUCTION_PER_EXPLORED_NEIGHBOUR * (float)explored_neighbours_count; //dist -= base_dist * DISTANCE_PCT_REDUCTION_PER_MISSING_NEIGHBOUR * (float)missing_neighbours_count; //cell.UserData = (Int64)(GetExploredNeighboursPct(cell, 1) * 100); if (dist < dest_cell_distance) { dest_cell = cell; dest_cell_distance = dist; } } if (dest_cell != null) { return(dest_cell.Position); } return(Vec3.Empty); }