#ifndef NAVMESHRANDOM_H #define NAVMESHRANDOM_H #include #include #include "../math/DrawList.h" #include "../geo/Point3.h" #include "NavMeshLocation.h" namespace NM { /** * randomly pick points within the area of the nav-mesh. * points are picked evenly: * bigger triangles are used more often * */ template class NavMeshRandom { DrawList lst; std::minstd_rand gen; std::uniform_real_distribution dOnTriangle = std::uniform_real_distribution(0.0f, 1.0f); std::vector triangles; uint32_t nextSeed() { static uint32_t seed = 0; return ++seed; } public: /** ctor (const/non-const using T) */ template NavMeshRandom(const std::vector& srcTriangles) : lst(nextSeed()), gen(nextSeed()) { // almost always the same number?! gen(); // construct a DrawList (probability = size[area] of the triangle // bigger triangles must be choosen more often for (size_t idx = 0; idx < srcTriangles.size(); ++idx) { this->triangles.push_back(srcTriangles[idx]); this->lst.add(idx, srcTriangles[idx]->getArea()); } } /** draw a random point */ NavMeshLocation draw() { // pick a random triangle to draw from const size_t idx = lst.get(); const Tria* tria = triangles[idx]; while (true) { const float u = dOnTriangle(gen); const float v = dOnTriangle(gen); if ((u+v) > 1) {continue;} const Point3 pos = tria->getPoint(u,v); //tria->getA() + (tria.getAB() * u) + (tria.getAC() * v); return NavMeshLocation(pos, tria); } } }; } #endif // NAVMESHRANDOM_H