#ifndef NAVMESHSUB_H #define NAVMESHSUB_H #include "../NavMesh.h" #include "../NavMeshLocation.h" #include "../NavMeshRandom.h" #include #include namespace NM { template class NavMeshSub { std::vector toVisit; public: NavMeshSub(const NavMeshLocation& loc, float radius_m) { build(loc,radius_m); } /** does this submesh contain the given point? */ bool contains(const Point2 p2) const { for (const Tria* t : toVisit) { if (t->contains(p2)) {return true;} } return false; } /** get the triangle that contains the given point (if any) */ const Tria* getContainingTriangle(const Point2 p2) const { for (const Tria* t : toVisit) { if (t->contains(p2)) {return t;} } return nullptr; } /** perform random operations on the submesh */ NavMeshRandom getRandom() { return NavMeshRandom(toVisit); } private: void build(const NavMeshLocation& loc, float radius_m) { std::unordered_set visited; // starting-triangle + all its (max 3) neighbors toVisit.push_back(loc.tria); visited.insert(loc.tria); for (const auto* n : *loc.tria) { toVisit.push_back( (const Tria*)n ); } size_t next = 1; // start with the first neighbor (skip starting triangle itself) while (next < toVisit.size()) { // next triangle const NavMeshTriangle* cur = toVisit[next]; ++next; // neighbors for (const auto* n : *cur) { const Tria* t = (const Tria*) n; const float dist = loc.pos.getDistance(n->getCenter()); if (dist > radius_m) {continue;} if (visited.find(t) != visited.end()) {continue;} toVisit.push_back(t); visited.insert(t); } } } }; } #endif // NAVMESHSUB_H