예제 #1
0
        public static HashSet <CellsPatch> GenerateCellsPatches(IEnumerable <Cell> cells, MovementFlag movement_flags, bool skip_disabled = false)
        {
            var patches = new HashSet <CellsPatch>();

            //create cells patch for each interconnected group of cells
            var cells_copy = new HashSet <Cell>(cells.Where(x => x.HasFlags(movement_flags) && (!skip_disabled || !x.Disabled)));

            while (cells_copy.Count > 0)
            {
                var start_cell = cells_copy.FirstOrDefault();

                if (start_cell == null)
                {
                    break;
                }

                PatchVisitor   patchVisitor = new PatchVisitor();
                HashSet <Cell> visited      = new HashSet <Cell>();

                Algorihms.Visit(start_cell, ref visited, movement_flags, !skip_disabled, visitor: patchVisitor);

                patches.Add(new CellsPatch(patchVisitor.cells, patchVisitor.cellsGrid, movement_flags));
                cells_copy.ExceptWith(visited);
            }

            return(patches);
        }
예제 #2
0
        protected HashSet <ExploreCell> GetUnexploredCells(ExploreCell origin_cell)
        {
            using (new ReadLock(DataLock))
            {
                UnexploredSelector selector = new UnexploredSelector();
                Algorihms.Visit <ExploreCell>(origin_cell, MovementFlag.None, -1, null, selector);

                m_CellsToExploreCount = selector.all_cells_count;
                m_ExploredCellsCount  = m_CellsToExploreCount - selector.unexplored_cells.Count;

                // first try all big cells unvisited by anyone (undelayed)
                HashSet <ExploreCell> unexplored_cells_subset = new HashSet <ExploreCell>(selector.unexplored_cells.Where(x => !x.Small && !x.Delayed));

                if (unexplored_cells_subset.Count > 0)
                {
                    return(unexplored_cells_subset);
                }

                // try all big cells unvisited by me
                unexplored_cells_subset = new HashSet <ExploreCell>(selector.unexplored_cells.Where(x => !x.Small));

                if (unexplored_cells_subset.Count > 0)
                {
                    return(unexplored_cells_subset);
                }

                // try all remaining cells
                return(selector.unexplored_cells);
            }
        }
예제 #3
0
        protected HashSet <ExploreCell> GetUnexploredCells(ExploreCell origin_cell)
        {
            using (new ReadLock(DataLock))
            {
                var agent_pos = m_Navigator.CurrentPos;

                // unexplored selector is collecting ALL unexplored cells matching constraints and filter criteria
                UnexploredSelector selector = new UnexploredSelector(ExploreConstraints, ExploreFilter, IgnoreSmall, agent_pos, m_Navmesh);
                Algorihms.Visit <ExploreCell>(origin_cell, MovementFlag.None, -1, null, selector);

                m_CellsToExploreCount = selector.all_cells_count;
                m_ExploredCellsCount  = m_CellsToExploreCount - selector.unexplored_cells.Count;

                // first try all big cells unvisited by anyone (undelayed)
                HashSet <ExploreCell> unexplored_cells_subset = new HashSet <ExploreCell>(selector.unexplored_cells.Where(x => !x.Small && !x.Delayed));

                if (unexplored_cells_subset.Count > 0)
                {
                    return(unexplored_cells_subset);
                }

                // try all big cells unvisited by me
                unexplored_cells_subset = new HashSet <ExploreCell>(selector.unexplored_cells.Where(x => !x.Small));

                if (unexplored_cells_subset.Count > 0)
                {
                    return(unexplored_cells_subset);
                }

                // try all remaining cells
                return(selector.unexplored_cells);
            }
        }
예제 #4
0
파일: Algorihms.cs 프로젝트: HiPoEGH/Nav
        public static List <CellsPatch> GenerateCellsPatches(List <Cell> cells, MovementFlag movement_flags)
        {
            List <CellsPatch> patches = new List <CellsPatch>();

            //create cells patch for each interconnected group of cells
            HashSet <Cell> cells_copy = new HashSet <Cell>(cells);

            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);

                patches.Add(new CellsPatch(visited, movement_flags));

                cells_copy.RemoveWhere(x => visited.Contains(x));
            }

            return(patches);
        }
예제 #5
0
        // 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
                using (m_Navmesh.AcquireReadDataLock())
                {
                    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>();

                    using (m_Navmesh.AcquireReadDataLock())
                        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 = intersections_aabb.Extend(intersection);
                        }
                    }

                    ExploreCell ex_cell = new ExploreCell(cell_aabb, visited.ToList(), overlapping_grid_cells, m_LastExploreCellId++);
                    Add(ex_cell);

                    ex_cell.Small = (ex_cell.CellsArea < MaxAreaToMarkAsSmall) || (ex_cell.CellsAABB.Dimensions.Max() < MaxDimensionToMarkAsSmall);

                    cells_copy.RemoveWhere(x => visited.Contains(x));
                }

                return(m_ExploreCells.Count - last_explore_cells_count);
            }
        }
예제 #6
0
        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);
            }
        }