30#ifndef NAVMAP_CORE__ITERATORS_HPP_
31#define NAVMAP_CORE__ITERATORS_HPP_
64 if (stamp_.size() < n) {
70 std::fill(stamp_.begin(), stamp_.end(), 0);
80 if (stamp_[cid] == epoch_) {
return false;}
104 std::vector<std::uint32_t> stamp_;
105 std::uint32_t epoch_{0};
112template<
class F,
class ... A>
115 if constexpr (std::is_void_v<std::invoke_result_t<F &, A...>>) {
116 f(std::forward<A>(a)...);
119 return static_cast<bool>(f(std::forward<A>(a)...));
127 return a.
min.x() <= b.
max.x() && a.
max.x() >= b.
min.x() &&
135 for (
const auto v : nm.
navcels[cid].v) {
142inline bool in_polygon(
const std::vector<Eigen::Vector2f> & poly,
float x,
float y)
145 for (std::size_t i = 0, j = poly.size() - 1; i < poly.size(); j = i++) {
146 const auto & a = poly[i];
147 const auto & b = poly[j];
148 if ((a.y() > y) != (b.y() > y) &&
149 x < (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y()) + a.x())
160 Eigen::Vector3f bary, hit;
167 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & a,
const Eigen::Vector3f & b, F && f)
169 if (seed >= nm.
navcels.size()) {
return false;}
170 const Eigen::Vector2f a2(a.x(), a.y());
171 const Eigen::Vector2f d2(b.x() - a.x(), b.y() - a.y());
172 auto cross = [](
const Eigen::Vector2f & u,
const Eigen::Vector2f & v) {
173 return u.x() * v.y() - u.y() * v.x();
175 constexpr float kEps = 1e-6f;
178 for (std::size_t steps = 0; steps <= nm.
navcels.size(); ++steps) {
179 const auto & cel = nm.
navcels[c];
180 Eigen::Vector2f p[3];
181 for (
int k = 0; k < 3; ++k) {
183 p[k] = Eigen::Vector2f(v.x(), v.y());
185 const float area2 = cross(p[1] - p[0], p[2] - p[0]);
186 if (std::abs(area2) < 1e-12f) {
return false;}
187 const float sgn = area2 > 0.0f ? 1.0f : -1.0f;
189 float t_exit = std::numeric_limits<float>::infinity();
191 for (
int e = 0; e < 3; ++e) {
192 const Eigen::Vector2f edge = p[(e + 1) % 3] - p[e];
193 const float ds = sgn * cross(edge, d2);
194 if (ds >= 0.0f) {
continue;}
195 const float s0 = sgn * cross(edge, a2 - p[e]);
196 const float te = std::max(-s0 / ds, t_in);
197 if (cel.neighbor[e] == prev && te <= t_in + kEps) {
continue;}
203 if (e_exit < 0 || t_exit >= 1.0f) {
204 return visit(f, c, t_in, 1.0f);
206 if (t_exit - t_in > kEps || c == seed) {
207 if (!
visit(f, c, t_in, t_exit)) {
return false;}
209 const NavCelId next = cel.neighbor[e_exit];
210 if (next ==
kNoCel) {
return false;}
224 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & center,
float r_in,
float r_out,
227 if (seed >= nm.
navcels.size() || !(r_out >= 0.0f)) {
return 0;}
231 std::size_t visited = 0;
233 auto emit = [&](
NavCelId c,
float d) {
234 const bool forced = with_seed && c == seed;
235 if (!forced && (d < r_in || d > r_out)) {
return true;}
237 return visit(f, c, d);
242 sc.
stack.push_back(seed);
243 std::size_t head = 0;
244 while (head < sc.
stack.size()) {
247 if (c != seed && d > r_out) {
continue;}
248 if (!emit(c, d)) {
return visited;}
265 sc.
heap.push_back(e);
266 std::push_heap(sc.
heap.begin(), sc.
heap.end(), cmp);
268 auto visible = [&](
NavCelId from,
const Eigen::Vector3f & p,
const Eigen::Vector3f & q,
272 nm, from, p, q, [&](
NavCelId x,
float,
float) {last = x;});
273 return reached && last == target;
275 push({(nm.
navcel_centroid(seed) - center).norm(), seed, seed, 0.0f, center});
276 while (!sc.
heap.empty()) {
277 std::pop_heap(sc.
heap.begin(), sc.
heap.end(), cmp);
284 u.
d = std::numeric_limits<float>::infinity();
288 const float dm = sc.
dist[m] + (pu - pm).norm();
289 if (dm < u.
d) {u = {dm, u.
cid, m, sc.
dist[m], pm};}
294 if (u.
cid != seed && u.
d > r_out) {
continue;}
295 if (!emit(u.
cid, u.
d)) {
return visited;}
320 std::size_t visited = 0;
321 for (
const auto & s : nm.
surfaces) {
322 if (s.bvh.empty()) {
continue;}
324 sc.
nodes.push_back(0);
325 while (!sc.
nodes.empty()) {
334 for (
int i = 0; i < node.
count; ++i) {
335 const auto cid =
static_cast<NavCelId>(s.prim_indices[node.
start + i]);
353 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & center,
float radius, F && f,
357 return detail::grow(nm, seed, center, 0.0f, radius, metric,
true, scratch, g);
363 const NavMap & nm,
const Eigen::Vector3f & center,
float radius, F && f,
368 return for_each_in_disc(nm, seed, center, radius, std::forward<F>(f), metric, scratch);
379 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & center,
float r_in,
float r_out,
383 return detail::grow(nm, seed, center, r_in, r_out, metric,
false, scratch, g);
395 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & center,
float max_distance, F && f,
409 const NavMap & nm,
NavCelId seed,
const std::vector<Eigen::Vector2f> & poly, F && f,
412 if (seed >= nm.
navcels.size() || poly.size() < 3) {
return 0;}
417 sc.
stack.push_back(seed);
418 std::size_t head = 0, visited = 0;
419 while (head < sc.
stack.size()) {
423 if (!in && c != seed) {
continue;}
438 const NavMap & nm,
const Eigen::Vector3f & on_surface,
439 const std::vector<Eigen::Vector2f> & poly, F && f,
TraversalScratch * scratch =
nullptr)
459 const NavMap & nm,
NavCelId seed,
const Eigen::Vector3f & a,
const Eigen::Vector3f & b, F && f)
467 const NavMap & nm,
const Eigen::Vector3f & a,
const Eigen::Vector3f & b, F && f)
Core container and data structures for EasyNav navigable meshes.
Definition NavMap.hpp:561
Eigen::Vector3f navcel_centroid(NavCelId cid) const
Triangle centroid (computed on the fly).
Definition NavMap.cpp:1069
std::vector< NavCel > navcels
All triangles (global indexing).
Definition NavMap.hpp:565
bool locate_navcel(const Eigen::Vector3f &p_world, size_t &surface_idx, NavCelId &cid, Eigen::Vector3f &bary, Eigen::Vector3f *hit_pt) const
Locate the triangle under / near a world point (convenience).
Definition NavMap.hpp:1391
std::vector< Surface > surfaces
Surfaces (partitions of navcels).
Definition NavMap.hpp:566
Positions positions
Vertex positions (SoA).
Definition NavMap.hpp:563
Reusable traversal buffers. Not thread-safe: one per thread.
Definition Iterators.hpp:59
std::vector< int > nodes
BVH node stack.
Definition Iterators.hpp:101
bool marked(NavCelId cid) const
Definition Iterators.hpp:85
std::vector< NavCelId > stack
BFS frontier.
Definition Iterators.hpp:99
bool mark(NavCelId cid)
Marks cid; false if it was already marked in this traversal.
Definition Iterators.hpp:78
void begin(std::size_t n)
Starts a traversal over a map of n NavCels: every NavCel unmarked.
Definition Iterators.hpp:62
std::vector< float > dist
Per NavCel, valid once marked: its settled distance.
Definition Iterators.hpp:97
std::vector< Front > heap
Dijkstra frontier (min-heap).
Definition Iterators.hpp:100
Definition Iterators.hpp:109
bool boxes_overlap(const AABB &a, const AABB &b)
Definition Iterators.hpp:125
bool visit(F &f, A &&... a)
Definition Iterators.hpp:113
bool seed_at(const NavMap &nm, const Eigen::Vector3f &p, NavCelId &seed)
Definition Iterators.hpp:157
AABB navcel_box(const NavMap &nm, NavCelId cid)
Definition Iterators.hpp:132
bool for_each_on_segment_impl(const NavMap &nm, NavCelId seed, const Eigen::Vector3f &a, const Eigen::Vector3f &b, F &&f)
Definition Iterators.hpp:166
std::size_t grow(const NavMap &nm, NavCelId seed, const Eigen::Vector3f ¢er, float r_in, float r_out, Metric metric, bool with_seed, TraversalScratch *scratch, F &f)
Definition Iterators.hpp:223
constexpr NavCelId kNoCel
Definition Iterators.hpp:123
bool in_polygon(const std::vector< Eigen::Vector2f > &poly, float x, float y)
Definition Iterators.hpp:142
Definition Combine.hpp:39
std::size_t for_each_in_polygon(const NavMap &nm, NavCelId seed, const std::vector< Eigen::Vector2f > &poly, F &&f, TraversalScratch *scratch=nullptr)
Visits the NavCels whose centroid lies inside the XY polygon poly, connected to seed through NavCels ...
Definition Iterators.hpp:408
bool for_each_on_segment(const NavMap &nm, NavCelId seed, const Eigen::Vector3f &a, const Eigen::Vector3f &b, F &&f)
Walks the surface along segment a -> b (in XY), from seed (the NavCel under a), visiting each NavCel ...
Definition Iterators.hpp:458
std::size_t for_each_in_disc(const NavMap &nm, NavCelId seed, const Eigen::Vector3f ¢er, float radius, F &&f, Metric metric=Metric::EUCLIDEAN, TraversalScratch *scratch=nullptr)
Visits the NavCels within radius of center, connected to seed (which should contain the centre).
Definition Iterators.hpp:352
uint32_t NavCelId
Index of a triangle (NavCel) within the global mesh.
Definition NavMap.hpp:59
Metric
Distance from a centre used to grow a region.
Definition Iterators.hpp:52
@ EUCLIDEAN
3D distance from the centre to each NavCel centroid
Definition Iterators.hpp:53
@ GEODESIC
Along the surface: straight lines on it, bent only around borders.
Definition Iterators.hpp:54
std::size_t for_each_in_aabb(const NavMap &nm, const AABB &box, F &&f, TraversalScratch *scratch=nullptr)
Visits the NavCels whose bounding box overlaps box, on every surface (via the BVH).
Definition Iterators.hpp:315
std::size_t for_each_by_distance(const NavMap &nm, NavCelId seed, const Eigen::Vector3f ¢er, float max_distance, F &&f, TraversalScratch *scratch=nullptr)
Visits NavCels by geodesic distance from center, up to max_distance: a spiral over the surface (neare...
Definition Iterators.hpp:394
std::size_t for_each_in_ring(const NavMap &nm, NavCelId seed, const Eigen::Vector3f ¢er, float r_in, float r_out, F &&f, Metric metric=Metric::EUCLIDEAN, TraversalScratch *scratch=nullptr)
Visits the NavCels at distance in [r_in, r_out] from center, connected to seed through NavCels within...
Definition Iterators.hpp:378
Axis-aligned bounding box.
Definition Geometry.hpp:165
Vec3 max
Maximum corner (x_max, y_max, z_max).
Definition Geometry.hpp:175
Vec3 min
Minimum corner (x_min, y_min, z_min).
Definition Geometry.hpp:169
void expand(const Vec3 &p)
Expand the box to include a point p.
Definition Geometry.hpp:183
Node in a per-surface bounding volume hierarchy (BVH).
Definition NavMap.hpp:455
int right
Right child index (or -1 for leaf).
Definition NavMap.hpp:458
int start
Start index in primitive array (leaf only).
Definition NavMap.hpp:459
bool is_leaf() const
Definition NavMap.hpp:461
int count
Number of primitives in leaf (0 for inner nodes).
Definition NavMap.hpp:460
int left
Left child index (or -1 for leaf).
Definition NavMap.hpp:457
AABB box
Bounding box of this node (world coordinates).
Definition NavMap.hpp:456
Eigen::Vector3f at(PointId id) const
Returns vertex id as a 3D vector.
Definition NavMap.hpp:89
Dijkstra frontier entry: distance, NavCel, and the pivot it is measured from.
Definition Iterators.hpp:89
Eigen::Vector3f pivot
Definition Iterators.hpp:94
float d
Definition Iterators.hpp:90
float pivot_len
Definition Iterators.hpp:93
NavCelId pivot_cel
Definition Iterators.hpp:92
NavCelId cid
Definition Iterators.hpp:91