fixed issues with random walks
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "../math/DrawList.h"
|
||||
#include "../geo/Point3.h"
|
||||
#include "../misc/PerfCheck.h"
|
||||
#include "../math/stats/Histogram.h"
|
||||
|
||||
#include "NavMeshLocation.h"
|
||||
|
||||
@@ -20,27 +21,22 @@ namespace NM {
|
||||
template <typename Tria> class NavMeshRandom {
|
||||
|
||||
DrawList<size_t> lst;
|
||||
std::minstd_rand gen;
|
||||
std::uniform_real_distribution<float> dOnTriangle = std::uniform_real_distribution<float>(0.0f, 1.0f);
|
||||
std::uniform_real_distribution<float> dHeading = std::uniform_real_distribution<float>(0, M_PI*2);
|
||||
std::vector<const Tria*> triangles;
|
||||
|
||||
|
||||
uint32_t nextSeed() {
|
||||
static uint32_t seed = 0;
|
||||
return ++seed;
|
||||
return seed += 13;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** ctor (const/non-const using T) */
|
||||
template <typename T> NavMeshRandom(const std::vector<T*>& srcTriangles) : lst(nextSeed()), gen(nextSeed()) {
|
||||
template <typename T> NavMeshRandom(const std::vector<T*>& srcTriangles) : lst(nextSeed()) {
|
||||
|
||||
Assert::isFalse(srcTriangles.empty(), "no triangles given. mesh is empty");
|
||||
|
||||
// 1st = almost always the same number?!
|
||||
gen(); 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) {
|
||||
@@ -53,6 +49,9 @@ namespace NM {
|
||||
/** draw a random point */
|
||||
NavMeshLocation<Tria> draw() {
|
||||
|
||||
// re-use to provide stable random numbers!
|
||||
static std::mt19937 gen;
|
||||
|
||||
PERF_REGION(3, "NavMeshRandom::draw()");
|
||||
|
||||
// pick a random triangle to draw from
|
||||
@@ -63,6 +62,15 @@ namespace NM {
|
||||
float u = dOnTriangle(gen);
|
||||
float v = dOnTriangle(gen);
|
||||
|
||||
#ifdef WITH_DEBUG_PLOT_2
|
||||
static Stats::Histogram<float> histU(0, 1, 200);
|
||||
static Stats::Histogram<float> histV(0, 1, 200);
|
||||
if (histU.count() > 200) {histU.showPlot(); histU.clear();}
|
||||
if (histV.count() > 200) {histV.showPlot(); histV.clear();}
|
||||
histU.add(u);
|
||||
histV.add(v);
|
||||
#endif
|
||||
|
||||
// if the (u,v) is outside of the triangle, mirror it so its inside the triangle again
|
||||
if ((u+v) > 1) {
|
||||
u = 1.0f - u;
|
||||
@@ -78,15 +86,25 @@ namespace NM {
|
||||
/** draw a random location within the given radius */
|
||||
NavMeshLocation<Tria> drawWithin(const Point3 center, const float radius) {
|
||||
|
||||
// re-use to provide stable random numbers!
|
||||
static std::mt19937 gen;
|
||||
|
||||
std::uniform_real_distribution<float> dDistance(0.001, radius);
|
||||
|
||||
while(true) {
|
||||
|
||||
const float head = dHeading(gen);
|
||||
const float dist = dDistance(gen);
|
||||
|
||||
const float ox = std::cos(head) * dist;
|
||||
const float oy = std::sin(head) * dist;
|
||||
|
||||
#ifdef WITH_DEBUG_PLOT_2
|
||||
static Stats::Histogram<float> hist(0, 10, 200);
|
||||
if (hist.count() > 1000) {hist.showPlot(); hist.clear();}
|
||||
hist.add(dist);
|
||||
#endif
|
||||
|
||||
// 2D destination (ignore z)
|
||||
const Point2 dst(center.x + ox, center.y + oy);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user