107 lines
3.0 KiB
C++
107 lines
3.0 KiB
C++
#ifndef BVHDEBUG_H
|
|
#define BVHDEBUG_H
|
|
|
|
#include "BVH.h"
|
|
#include <KLib/misc/gnuplot/GnuplotSplot.h>
|
|
#include <KLib/misc/gnuplot/GnuplotSplotElementPoints.h>
|
|
#include <KLib/misc/gnuplot/GnuplotSplotElementColorPoints.h>
|
|
#include <KLib/misc/gnuplot/GnuplotSplotElementLines.h>
|
|
#include <KLib/misc/gnuplot/Gnuplot.h>
|
|
#include "../BBox3.h"
|
|
#include <random>
|
|
|
|
/** adds some debug helpers to the BVH */
|
|
template <typename Element, typename Volume, typename Wrapper> class BVHDebug : public BVH<Element, Volume, Wrapper> {
|
|
|
|
using BVHNode = typename BVH<Element, Volume, Wrapper>::BVHNode;
|
|
using BVHLeaf = typename BVH<Element, Volume, Wrapper>::BVHLeaf;
|
|
|
|
public:
|
|
|
|
// std::vecto<std::string> colors {
|
|
// "#888888", "#888800", "#008888", "#880088", "#ee0000", "#00ee00", "#0000ee"
|
|
// };
|
|
|
|
void show(int maxPts = 1500, bool showLeafs = true) {
|
|
|
|
std::stringstream out;
|
|
|
|
static K::Gnuplot gp;
|
|
K::GnuplotSplot plot;
|
|
K::GnuplotSplotElementColorPoints pVol; plot.add(&pVol); //pVol.setColor(K::GnuplotColor::fromRGB(128,128,128));
|
|
K::GnuplotSplotElementPoints pElemPoints; plot.add(&pElemPoints); pElemPoints.setColor(K::GnuplotColor::fromRGB(0,0,255));
|
|
K::GnuplotSplotElementLines pElemLines; plot.add(&pElemLines); pElemLines.getStroke().setColor(K::GnuplotColor::fromRGB(0,0,255));
|
|
|
|
const int depth = recurse(maxPts, showLeafs, 0, &this->root, pVol, pElemPoints, pElemLines);
|
|
|
|
plot.getAxisCB().setRange(0, depth);
|
|
|
|
gp << "set view equal xyz\n";
|
|
gp.draw(plot);
|
|
gp.flush();
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
int recurse(int maxPts, bool showLeafs, int curDepth, const BVHNode* node, K::GnuplotSplotElementColorPoints& vol, K::GnuplotSplotElementPoints& pElemPoints, K::GnuplotSplotElementLines& elemLines) {
|
|
|
|
int resDepth = curDepth;
|
|
|
|
for (BVHNode* sub : node->childNodes) {
|
|
resDepth = recurse(maxPts, showLeafs, curDepth+1, sub, vol, pElemPoints, elemLines);
|
|
}
|
|
|
|
if (!node->isLeaf || showLeafs) {
|
|
|
|
const int numPts = maxPts / (curDepth+1);
|
|
|
|
for (int i = 0; i < numPts; ++i) {
|
|
const Point3 p = getRandomPoint(node->boundingVolume);
|
|
vol.add(K::GnuplotPoint3(p.x, p.y, p.z), curDepth);
|
|
}
|
|
|
|
}
|
|
|
|
if (node->isLeaf) {
|
|
BVHLeaf* leaf = (BVHLeaf*) node;
|
|
std::vector<Point3> verts = Wrapper::getVertices(leaf->element);
|
|
for (const Point3 p : verts) {
|
|
pElemPoints.add(K::GnuplotPoint3(p.x, p.y, p.z));
|
|
}
|
|
addLines(leaf->element, elemLines);
|
|
}
|
|
|
|
return resDepth;
|
|
|
|
}
|
|
|
|
Point3 getRandomPoint(BoundingVolumeSphere sphere) {
|
|
static std::minstd_rand gen;
|
|
std::uniform_real_distribution<float> dist(-1, +1);
|
|
Point3 dir = Point3(dist(gen), dist(gen), dist(gen)).normalized() * sphere.radius;
|
|
return sphere.center + dir;
|
|
}
|
|
|
|
void addLines(const Element& elem, K::GnuplotSplotElementLines& elemLines) {
|
|
|
|
std::vector<Point3> pts = Wrapper::getDebugLines(elem);
|
|
|
|
for (size_t i = 0; i< pts.size(); i+=2) {
|
|
|
|
const Point3 p1 = pts[i+0];
|
|
const Point3 p2 = pts[i+1];
|
|
|
|
K::GnuplotPoint3 gp1(p1.x, p1.y, p1.z);
|
|
K::GnuplotPoint3 gp2(p2.x, p2.y, p2.z);
|
|
|
|
elemLines.addSegment(gp1, gp2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif // BVHDEBUG_H
|