added nav-mesh support to indoor-map
some fixes/changes
This commit is contained in:
85
mapview/3DNavMesh/NavMeshModel.h
Normal file
85
mapview/3DNavMesh/NavMeshModel.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef NAVMESHMODEL_H
|
||||
#define NAVMESHMODEL_H
|
||||
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include <Indoor/navMesh/NavMesh.h>
|
||||
#include <Indoor/navMesh/NavMeshFactory.h>
|
||||
#include <Indoor/navMesh/NavMeshFactoryListener.h>
|
||||
|
||||
#include <QProgressDialog>
|
||||
#include <QApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include "QNavMeshSettings.h"
|
||||
|
||||
/**
|
||||
* used for 3D NavMesh rendering
|
||||
*/
|
||||
class NavMeshModel {
|
||||
|
||||
private:
|
||||
|
||||
NM::NavMesh<NM::NavMeshTriangle> navMesh;
|
||||
NM::NavMeshSettings settings;
|
||||
Floorplan::IndoorMap* im;
|
||||
|
||||
public:
|
||||
|
||||
NavMeshModel() : navMesh() {
|
||||
;
|
||||
}
|
||||
|
||||
NM::NavMesh<NM::NavMeshTriangle>* getNavMesh() {return &navMesh;}
|
||||
|
||||
|
||||
class Listener : public NM::NavMeshFactoryListener {
|
||||
|
||||
private:
|
||||
QDialog dlg;
|
||||
QLabel* lbl1;
|
||||
QProgressBar* bar1;
|
||||
|
||||
public:
|
||||
Listener() {
|
||||
QVBoxLayout* lay = new QVBoxLayout(&dlg);
|
||||
lbl1 = new QLabel(); lay->addWidget(lbl1);
|
||||
bar1 = new QProgressBar(); lay->addWidget(bar1);
|
||||
dlg.resize(350, 90);
|
||||
dlg.setWindowTitle("NavMesh building");
|
||||
dlg.show();
|
||||
}
|
||||
~Listener() {
|
||||
dlg.close();
|
||||
}
|
||||
|
||||
void onNavMeshBuildUpdateMajor(const std::string& what) override {
|
||||
lbl1->setText(what.c_str());
|
||||
QApplication::processEvents();
|
||||
}
|
||||
void onNavMeshBuildUpdateMajor(const int cnt, const int cur) override {
|
||||
bar1->setValue(cur*100/cnt);
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void rebuild(Floorplan::IndoorMap* im) {
|
||||
|
||||
Listener l;
|
||||
|
||||
QNavMeshSettings qs(&settings);
|
||||
qs.exec();
|
||||
|
||||
if (qs.ok) {
|
||||
NM::NavMeshFactory<NM::NavMeshTriangle> fac(&navMesh, settings);
|
||||
fac.build(im, &l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // NAVMESHMODEL_H
|
||||
172
mapview/3DNavMesh/NavMeshRenderer.h
Normal file
172
mapview/3DNavMesh/NavMeshRenderer.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#ifndef NAVMESHRENDERER_H
|
||||
#define NAVMESHRENDERER_H
|
||||
|
||||
|
||||
|
||||
#include <unordered_set>
|
||||
#include <Indoor/navMesh/NavMesh.h>
|
||||
#include <Indoor/navMesh/NavMeshTriangle.h>
|
||||
#include <Indoor/navMesh/NavMeshType.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGLWidget>
|
||||
|
||||
//enum class GridRendererColorMode {
|
||||
// SHOW_NODE_TYPE,
|
||||
// SHOW_NODE_IMPORTANCE,
|
||||
//};
|
||||
|
||||
class NavMeshRenderer {
|
||||
|
||||
private:
|
||||
|
||||
// settings
|
||||
//GridRendererColorMode colorMode = GridRendererColorMode::SHOW_NODE_IMPORTANCE;
|
||||
bool showEdges = false;
|
||||
|
||||
struct Color {
|
||||
float r,g,b;
|
||||
Color() : r(1), g(0), b(0) {;}
|
||||
Color(float r, float g, float b) : r(r), g(g), b(b) {;}
|
||||
};
|
||||
|
||||
/** node color depending on the node's type. see ctor */
|
||||
Color colors[200];
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
NavMeshRenderer() {
|
||||
|
||||
colors[GridNode::TYPE_FLOOR] = Color(0.4, 0.4, 0.4);
|
||||
colors[GridNode::TYPE_STAIR] = Color(0,0,1);
|
||||
colors[GridNode::TYPE_ELEVATOR] = Color(0,0,1);
|
||||
colors[GridNode::TYPE_DOOR] = Color(0.0, 0.0, 0.0);
|
||||
|
||||
colors[GridNode::TYPE_OUTDOOR] = Color(0.0, 0.5, 0.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// void setNodeColorMode(const GridRendererColorMode mode) {this->colorMode = mode;}
|
||||
void setShowEdges(const bool show) {this->showEdges = show;}
|
||||
|
||||
|
||||
/** render the given grid using GL commands */
|
||||
void paintGL(NM::NavMesh<NM::NavMeshTriangle>* navMesh, QGLWidget* dst) {
|
||||
|
||||
if (navMesh == nullptr) {return;}
|
||||
|
||||
// QPainter qp;
|
||||
// qp.begin(dst);
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
const float s = 2;
|
||||
|
||||
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
for (const NM::NavMeshTriangle* tria : *navMesh) {
|
||||
|
||||
// // get the color to use
|
||||
// switch(colorMode) {
|
||||
// case GridRendererColorMode::SHOW_NODE_TYPE: {
|
||||
// const Color c = colors[n.getType()];
|
||||
// glColor3f(c.r, c.g, c.b);
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case GridRendererColorMode::SHOW_NODE_IMPORTANCE: {
|
||||
// const float xx = n.navImportance - 0.6;
|
||||
// glColor3f(xx, xx, xx);
|
||||
// break;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
switch (tria->getType()) {
|
||||
case (int) NM::NavMeshType::FLOOR_INDOOR: glColor3f(0.8, 0.8, 0.8); break;
|
||||
case (int) NM::NavMeshType::FLOOR_OUTDOOR: glColor3f(0.1, 0.8, 0.1); break;
|
||||
case (int) NM::NavMeshType::DOOR: glColor3f(0.7, 0.7, 0.8); break;
|
||||
case (int) NM::NavMeshType::STAIR_LEVELED: glColor3f(0.5, 0.5, 0.5); break;
|
||||
case (int) NM::NavMeshType::STAIR_SKEWED: glColor3f(0.6, 0.6, 0.6); break;
|
||||
}
|
||||
|
||||
glVertex3f(tria->getP1().x, tria->getP1().z, tria->getP1().y);
|
||||
glVertex3f(tria->getP2().x, tria->getP2().z, tria->getP2().y);
|
||||
glVertex3f(tria->getP3().x, tria->getP3().z, tria->getP3().y);
|
||||
|
||||
}
|
||||
glEnd();
|
||||
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
//glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
//glColor3f(0.2,0.2,0.2);
|
||||
for (const NM::NavMeshTriangle* tria : *navMesh) {
|
||||
|
||||
switch (tria->getType()) {
|
||||
case (int) NM::NavMeshType::FLOOR_INDOOR: glColor3f(0.6, 0.6, 0.6); break;
|
||||
case (int) NM::NavMeshType::FLOOR_OUTDOOR: glColor3f(0.0, 0.6, 0.0); break;
|
||||
case (int) NM::NavMeshType::DOOR: glColor3f(0.5, 0.5, 0.6); break;
|
||||
case (int) NM::NavMeshType::STAIR_LEVELED: glColor3f(0.4, 0.4, 0.4); break;
|
||||
case (int) NM::NavMeshType::STAIR_SKEWED: glColor3f(0.4, 0.4, 0.4); break;
|
||||
}
|
||||
|
||||
glVertex3f(tria->getP1().x, tria->getP1().z+0.01, tria->getP1().y);
|
||||
glVertex3f(tria->getP2().x, tria->getP2().z+0.01, tria->getP2().y);
|
||||
|
||||
glVertex3f(tria->getP2().x, tria->getP2().z+0.01, tria->getP2().y);
|
||||
glVertex3f(tria->getP3().x, tria->getP3().z+0.01, tria->getP3().y);
|
||||
|
||||
glVertex3f(tria->getP3().x, tria->getP3().z+0.01, tria->getP3().y);
|
||||
glVertex3f(tria->getP1().x, tria->getP1().z+0.01, tria->getP1().y);
|
||||
|
||||
// glBegin(GL_LINE_LOOP);
|
||||
// glVertex3f(tria->getP1().x, tria->getP1().z+0.01, tria->getP1().y);
|
||||
// glVertex3f(tria->getP2().x, tria->getP2().z+0.01, tria->getP2().y);
|
||||
// glVertex3f(tria->getP3().x, tria->getP3().z+0.01, tria->getP3().y);
|
||||
// glEnd();
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
|
||||
// qp.drawText(20,20, "sdfsdkflsdfjasfklsdklfsdklfsdf");
|
||||
// qp.drawText(20,-20, "sdfsdkflsdfjasfklsdklfsdklfsdf");
|
||||
// qp.drawText(0.5,0.5, "sdfsdkflsdfjasfklsdklfsdklfsdf");
|
||||
// qp.end();
|
||||
|
||||
// renderText(1,1,1, "123");
|
||||
|
||||
const QString str1 = "Triangles: " + QString::number(navMesh->getNumTriangles());
|
||||
const QString str2 = "Size: ~" + QString::number(navMesh->getNumTriangles() * sizeof(NM::NavMeshTriangle) / 1024) + " kB";
|
||||
|
||||
glColor3f(0.0, 0.0, 0.0);
|
||||
dst->renderText(20,20, str1);
|
||||
dst->renderText(20,35, str2);
|
||||
|
||||
// dst->renderText(0,0, "2342342342342423423423423423423432");
|
||||
// dst->renderText(0.1, 0.1, 0.1, "lsdfsdfsdfsdfsdfsdfsdfol");
|
||||
}
|
||||
|
||||
// std::vector<MyNode> lint() {
|
||||
// std::vector<MyNode> vec;
|
||||
// lintStair(vec);
|
||||
// return vec;
|
||||
// }
|
||||
|
||||
// void lintStair(std::vector<MyNode>& vec) {
|
||||
// for (MyNode& n1 : *grid) {
|
||||
// if (n1.getNumNeighbors() <= 5) { vec.push_back(n1);}
|
||||
// }
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
#endif // NAVMESHRENDERER_H
|
||||
87
mapview/3DNavMesh/QNavMeshSettings.cpp
Normal file
87
mapview/3DNavMesh/QNavMeshSettings.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "QNavMeshSettings.h"
|
||||
|
||||
#include <Indoor/navMesh/NavMeshSettings.h>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QSlider>
|
||||
#include <QSlider>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
QNavMeshSettings::QNavMeshSettings(NM::NavMeshSettings* settings, QWidget* parent) : QDialog(parent) {
|
||||
|
||||
QGridLayout* lay = new QGridLayout(this);
|
||||
this->setLayout(lay);
|
||||
int row = 0;
|
||||
|
||||
this->setWindowTitle("NavMesh Settings");
|
||||
this->setMinimumWidth(350);
|
||||
|
||||
// MAX QUALITY
|
||||
{
|
||||
lay->addWidget(new QLabel("smallest element"), row, 0);
|
||||
QLabel* lblQuality = new QLabel("");
|
||||
lay->addWidget(lblQuality, row, 2);
|
||||
QSlider* sldQuality = new QSlider(Qt::Orientation::Horizontal); sldQuality->setMinimum(10); sldQuality->setMaximum(30);
|
||||
connect(sldQuality, &QSlider::valueChanged, [settings, sldQuality, lblQuality] () {
|
||||
settings->maxQuality_m = sldQuality->value() / 100.0f;
|
||||
lblQuality->setText(QString("%1 m").arg(settings->maxQuality_m, 5, 'f', 2, 0));
|
||||
});
|
||||
sldQuality->setValue(settings->maxQuality_m * 100.0f);
|
||||
lay->addWidget(sldQuality, row, 1);
|
||||
++row;
|
||||
}
|
||||
|
||||
// AGENT HEIGHT
|
||||
{
|
||||
lay->addWidget(new QLabel("agent height"), row, 0);
|
||||
QLabel* lblHeight = new QLabel("");
|
||||
lay->addWidget(lblHeight, row, 2);
|
||||
QSlider* sldHeight = new QSlider(Qt::Orientation::Horizontal); sldHeight->setMinimum(10); sldHeight->setMaximum(200);
|
||||
connect(sldHeight, &QSlider::valueChanged, [settings, sldHeight, lblHeight] () {
|
||||
settings->agentHeight = sldHeight->value() / 100.0f;
|
||||
lblHeight->setText(QString("%1 m").arg(settings->agentHeight, 5, 'f', 2, 0));
|
||||
});
|
||||
sldHeight->setValue(settings->agentHeight * 100.0f);
|
||||
lay->addWidget(sldHeight, row, 1);
|
||||
++row;
|
||||
}
|
||||
|
||||
// AGENT RADIUS
|
||||
{
|
||||
lay->addWidget(new QLabel("agent radius"), row, 0);
|
||||
QLabel* lblRadius = new QLabel("");
|
||||
lay->addWidget(lblRadius, row, 2);
|
||||
QSlider* sldRadius = new QSlider(Qt::Orientation::Horizontal); sldRadius->setMinimum(5); sldRadius->setMaximum(60);
|
||||
connect(sldRadius, &QSlider::valueChanged, [settings, sldRadius, lblRadius] () {
|
||||
settings->agentRadius = sldRadius->value() / 100.0f;
|
||||
lblRadius->setText(QString("%1 m").arg(settings->agentRadius, 5, 'f', 2, 0));
|
||||
});
|
||||
sldRadius->setValue(settings->agentRadius * 100.0f);
|
||||
lay->addWidget(sldRadius, row, 1);
|
||||
++row;
|
||||
}
|
||||
|
||||
|
||||
// MAX EDGE LENGTH
|
||||
{
|
||||
lay->addWidget(new QLabel("max edge length"), row, 0);
|
||||
QLabel* lblMaxEdgeLength = new QLabel("");
|
||||
lay->addWidget(lblMaxEdgeLength, row, 2);
|
||||
QSlider* sdlMaxEdgeLength = new QSlider(Qt::Orientation::Horizontal); sdlMaxEdgeLength->setMinimum(300); sdlMaxEdgeLength->setMaximum(2000);
|
||||
connect(sdlMaxEdgeLength, &QSlider::valueChanged, [settings, sdlMaxEdgeLength, lblMaxEdgeLength] () {
|
||||
settings->edgeMaxLen = sdlMaxEdgeLength->value() / 100.0f;
|
||||
lblMaxEdgeLength->setText(QString("%1 m").arg(settings->edgeMaxLen, 5, 'f', 2, 0));
|
||||
});
|
||||
sdlMaxEdgeLength->setValue(settings->edgeMaxLen * 100.0f);
|
||||
lay->addWidget(sdlMaxEdgeLength, row, 1);
|
||||
++row;
|
||||
}
|
||||
|
||||
QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Close);
|
||||
lay->addWidget(box, row, 0, 1, 3);
|
||||
|
||||
connect(box, &QDialogButtonBox::accepted, [&] () {ok = true; close();});
|
||||
connect(box, &QDialogButtonBox::rejected, [&] () {ok = false; close();});
|
||||
|
||||
}
|
||||
24
mapview/3DNavMesh/QNavMeshSettings.h
Normal file
24
mapview/3DNavMesh/QNavMeshSettings.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef QNAVMESHSETTINGS_H
|
||||
#define QNAVMESHSETTINGS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDialog>
|
||||
|
||||
namespace NM {
|
||||
class NavMeshSettings;
|
||||
}
|
||||
|
||||
class QNavMeshSettings : public QDialog {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
|
||||
QNavMeshSettings(NM::NavMeshSettings* settings, QWidget* parent = nullptr);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
};
|
||||
|
||||
#endif // QNAVMESHSETTINGS_H
|
||||
Reference in New Issue
Block a user