private int GenerateExploreCells(AABB cell_aabb) { // should not happen //if (m_ExploreCells.Exists(x => x.AABB.Equals(cell_aabb))) // return; MovementFlag movement_flags = Navmesh.Navigator.MovementFlags; //using (new Profiler("[Nav] Nav data generated [{t}]")) using (Navmesh.AquireReadDataLock()) { List <Cell> cells = new List <Cell>(); // find all cells inside cell_aabb foreach (GridCell grid_cell in Navmesh.m_GridCells) { if (!cell_aabb.Overlaps2D(grid_cell.AABB)) { continue; } cells.AddRange(grid_cell.Cells.FindAll(x => !x.Replacement && x.HasFlags(movement_flags) && cell_aabb.Overlaps2D(x.AABB))); } // add all replaced cells overlapped by explore cell //cells.AddRange(Navmesh.GetReplacedCells().FindAll(x => x.HasFlags(movement_flags) && cell_aabb.Overlaps2D(x.AABB))); //create ExploreCell for each interconnected group of cells List <Cell> cells_copy = new List <Cell>(cells); int last_explore_cells_count = m_ExploreCells.Count; while (cells_copy.Count > 0) { List <Cell> visited = new List <Cell>(); Algorihms.Visit(cells_copy[0], ref visited, movement_flags, true, 1, -1, cells_copy); List <AABB> intersections = new List <AABB>(); AABB intersections_aabb = new AABB(); foreach (Cell c in visited) { AABB intersection = cell_aabb.Intersect(c.AABB); intersections.Add(intersection); intersections_aabb.Extend(intersection); } Vec3 nearest_intersection_center = Vec3.Empty; float nearest_intersection_dist = float.MaxValue; foreach (AABB inter_aabb in intersections) { float dist = inter_aabb.Center.Distance2D(intersections_aabb.Center); if (dist < nearest_intersection_dist) { nearest_intersection_center = inter_aabb.Center; nearest_intersection_dist = dist; } } ExploreCell ex_cell = new ExploreCell(cell_aabb, visited, nearest_intersection_center, m_LastExploreCellId++); Add(ex_cell); ex_cell.Small = (ex_cell.CellsArea() < MAX_AREA_TO_MARK_AS_SMALL); cells_copy.RemoveAll(x => visited.Contains(x)); } return(m_ExploreCells.Count - last_explore_cells_count); } }
private int GenerateExploreCells(AABB cell_aabb) { // should not happen //if (m_ExploreCells.Exists(x => x.AABB.Equals(cell_aabb))) // return; MovementFlag movement_flags = Navmesh.Navigator.MovementFlags; //using (new Profiler("[Nav] Nav data generated [{t}]")) using (Navmesh.AquireReadDataLock()) { List<Cell> cells = new List<Cell>(); // find all cells inside cell_aabb foreach (GridCell grid_cell in Navmesh.m_GridCells) { if (!cell_aabb.Overlaps2D(grid_cell.AABB)) continue; cells.AddRange(grid_cell.Cells.FindAll(x => !x.Replacement && x.HasFlags(movement_flags) && cell_aabb.Overlaps2D(x.AABB))); } // add all replaced cells overlapped by explore cell //cells.AddRange(Navmesh.GetReplacedCells().FindAll(x => x.HasFlags(movement_flags) && cell_aabb.Overlaps2D(x.AABB))); //create ExploreCell for each interconnected group of cells List<Cell> cells_copy = new List<Cell>(cells); int last_explore_cells_count = m_ExploreCells.Count; while (cells_copy.Count > 0) { List<Cell> visited = new List<Cell>(); Algorihms.Visit(cells_copy[0], ref visited, movement_flags, true, 1, -1, cells_copy); List<AABB> intersections = new List<AABB>(); AABB intersections_aabb = new AABB(); foreach (Cell c in visited) { AABB intersection = cell_aabb.Intersect(c.AABB); intersections.Add(intersection); intersections_aabb.Extend(intersection); } Vec3 nearest_intersection_center = Vec3.Empty; float nearest_intersection_dist = float.MaxValue; foreach (AABB inter_aabb in intersections) { float dist = inter_aabb.Center.Distance2D(intersections_aabb.Center); if (dist < nearest_intersection_dist) { nearest_intersection_center = inter_aabb.Center; nearest_intersection_dist = dist; } } ExploreCell ex_cell = new ExploreCell(cell_aabb, visited, nearest_intersection_center, m_LastExploreCellId++); Add(ex_cell); ex_cell.Small = (ex_cell.CellsArea() < MAX_AREA_TO_MARK_AS_SMALL); cells_copy.RemoveAll(x => visited.Contains(x)); } return m_ExploreCells.Count - last_explore_cells_count; } }
// assume Navmesh data lock is aquired private int GenerateExploreCells(AABB cell_aabb) { // should not happen //if (m_ExploreCells.Exists(x => x.AABB.Equals(cell_aabb))) // return; MovementFlag movement_flags = m_Navigator.MovementFlags; //using (new Profiler("[Nav] Nav data generated [%t]")) //using (m_Navmesh.AquireReadDataLock()) { List <Cell> cells = new List <Cell>(); // i'm interested in unique list HashSet <int> tmp_overlapping_grid_cells = new HashSet <int>(); // find all cells inside cell_aabb foreach (GridCell grid_cell in m_Navmesh.m_GridCells.Where(x => x.AABB.Overlaps2D(cell_aabb))) { tmp_overlapping_grid_cells.Add(grid_cell.Id); cells.AddRange(grid_cell.GetCells(x => x.HasFlags(movement_flags) && cell_aabb.Overlaps2D(x.AABB), false)); } // for traversing purposes list will be faster List <int> overlapping_grid_cells = tmp_overlapping_grid_cells.ToList(); //create ExploreCell for each interconnected group of cells HashSet <Cell> cells_copy = new HashSet <Cell>(cells); int last_explore_cells_count = m_ExploreCells.Count; while (cells_copy.Count > 0) { HashSet <Cell> visited = new HashSet <Cell>(); Algorihms.Visit(cells_copy.First(), ref visited, movement_flags, true, 1, -1, cells_copy); List <AABB> intersections = new List <AABB>(); AABB intersections_aabb = new AABB(); AABB intersection = default(AABB); foreach (Cell c in visited) { if (cell_aabb.Intersect(c.AABB, ref intersection)) { intersections.Add(intersection); intersections_aabb.Extend(intersection); } } Vec3 nearest_intersection_center = Vec3.ZERO; float nearest_intersection_dist = float.MaxValue; foreach (AABB inter_aabb in intersections) { float dist = inter_aabb.Center.Distance2D(intersections_aabb.Center); if (dist < nearest_intersection_dist) { nearest_intersection_center = inter_aabb.Center; nearest_intersection_dist = dist; } } ExploreCell ex_cell = new ExploreCell(cell_aabb, visited.ToList(), overlapping_grid_cells, nearest_intersection_center, m_LastExploreCellId++); Add(ex_cell); ex_cell.Small = (ex_cell.CellsArea() < MAX_AREA_TO_MARK_AS_SMALL); cells_copy.RemoveWhere(x => visited.Contains(x)); } return(m_ExploreCells.Count - last_explore_cells_count); } }