VIPRA Documentation
Loading...
Searching...
No Matches
pathing_graph.hpp
1#pragma once
2
3#include <array>
4#include <limits>
5
6#include "vipra/geometry/f3d.hpp"
7#include "vipra/macros/performance.hpp"
8#include "vipra/modules/map.hpp"
9#include "vipra/types/float.hpp"
10#include "vipra/types/idx.hpp"
11#include "vipra/types/size.hpp"
12
13namespace VIPRA::Goals {
14struct GridPoint {
15 std::array<bool, 8> neighbors;
16 bool traversable;
17};
18
19class PathingGraph {
20 public:
21 [[nodiscard]] VIPRA_INLINE auto node_count() const noexcept -> size_t
22 {
23 return _grids.size();
24 }
25
26 [[nodiscard]] auto neighbors(VIPRA::idx gridIdx) const noexcept
27 -> std::array<VIPRA::idx, 8>
28 {
29 assert(gridIdx < _grids.size());
30
31 std::array<VIPRA::idx, 8> neighbors{};
32
33 VIPRA::idx nIdx = 0;
34 for ( bool neighbor : _grids[gridIdx].neighbors ) {
35 if ( ! neighbor || (neighbor_idx(gridIdx, nIdx) > _grids.size() ||
36 neighbor_idx(gridIdx, nIdx) < 0) ) {
37 neighbors[nIdx] = std::numeric_limits<VIPRA::idx>::max();
38 ++nIdx;
39 continue;
40 }
41
42 neighbors[nIdx] = neighbor_idx(gridIdx, nIdx);
43 ++nIdx;
44 }
45
46 return neighbors;
47 }
48
49 [[nodiscard]] VIPRA_INLINE auto pos(VIPRA::idx gridIdx) const noexcept -> VIPRA::f3d
50 {
51 assert(gridIdx < _grids.size());
52 return _positions[gridIdx];
53 }
60 [[nodiscard]] auto get_closest_grid_idx(VIPRA::f3d position) const noexcept
61 -> VIPRA::idx
62 {
63 auto const gridX = static_cast<VIPRA::idx>(std::floor(position.x / _gridSize));
64 auto const gridY = static_cast<VIPRA::idx>(std::floor(position.y / _gridSize));
65
66 return get_index(gridX, gridY);
67 }
68
69 private:
70 VIPRA::size _xCount{};
71 VIPRA::size _yCount{};
72 VIPRA::f_pnt _gridSize{};
73 VIPRA::f_pnt _closestObstacle{};
74
75 std::vector<GridPoint> _grids;
76 std::vector<VIPRA::f3d> _positions;
77
78 void set_grid_counts(VIPRA::Modules::Map const& map);
79 void construct_graph(VIPRA::Modules::Map const& map);
80 void set_adjacents(VIPRA::idx currIdx);
81
82 [[nodiscard]] auto neighbor_idx(VIPRA::idx gridIdx,
83 VIPRA::idx neighbor) const noexcept -> VIPRA::idx
84 {
85 const int xCount = static_cast<int>(_xCount);
86 const std::array<int, 8> deltaIdx = {
87 (-xCount - 1), -xCount, (-xCount + 1), -1, 1, (xCount - 1), xCount, (xCount + 1),
88 };
89
90 return gridIdx + deltaIdx[neighbor];
91 }
92
101 [[nodiscard]] VIPRA_INLINE auto get_index(
102 VIPRA::size gridX, VIPRA::size gridY) const noexcept -> VIPRA::idx
103 {
104 assert(gridX + (gridY * _xCount) < _grids.size());
105 return gridX + (gridY * _xCount);
106 }
107
108 public:
109 PathingGraph(Modules::Map const& map, VIPRA::f_pnt gridSize,
110 VIPRA::f_pnt closestObstacle)
111 : _gridSize(gridSize), _closestObstacle(closestObstacle)
112 {
113 construct_graph(map);
114 }
115 PathingGraph() = default;
116 PathingGraph(const PathingGraph&) = default;
117 PathingGraph(PathingGraph&&) = default;
118 auto operator=(const PathingGraph&) -> PathingGraph& = default;
119 auto operator=(PathingGraph&&) -> PathingGraph& = default;
120 ~PathingGraph() = default;
121};
122} // namespace VIPRA::Goals
auto get_closest_grid_idx(VIPRA::f3d position) const noexcept -> VIPRA::idx
Gets the closest grid index to the coordinate.
Definition pathing_graph.hpp:60
Definition pathing_graph.hpp:14
Definition f3d.hpp:27