diff --git a/IndoorMap.pro b/IndoorMap.pro index 9545660..8227576 100644 --- a/IndoorMap.pro +++ b/IndoorMap.pro @@ -58,7 +58,9 @@ SOURCES += \ mapview/3D/navMesh/QNavMeshSettings.cpp \ params/ToolBoxWidget.cpp \ mapview/2D/MV2DElementFloorObstacleDoor.cpp \ - mapview/2D/MV2DElementFloorObstacleObject.cpp + mapview/2D/MV2DElementFloorObstacleObject.cpp \ + mapview/3D/grid/GridRenderer.cpp \ + mapview/3D/navMesh/NavMeshRenderer.cpp HEADERS += MainWindow.h \ diff --git a/mapview/3D/MapView3D.cpp b/mapview/3D/MapView3D.cpp index 06268f0..83eca0b 100644 --- a/mapview/3D/MapView3D.cpp +++ b/mapview/3D/MapView3D.cpp @@ -32,6 +32,8 @@ MapView3D::MapView3D(QWidget *parent) : QOpenGLWidget(parent) { gridRenderer = new GridRenderer(); + navMeshRenderer = new NavMeshRenderer(); + floorplanRenderer = new FloorplanRenderer(); floorplanRendererModel = new FloorplanRendererModel(); @@ -374,12 +376,13 @@ void MapView3D::draw() { // } -// if (showGrid && gridModel) { -// gridRenderer->paintGL(gridModel->getGrid()); -// } + if (showGrid && gridModel) { + //gridRenderer->paintGL(gridModel->getGrid()); + gridRenderer->render(rs, gridModel); + } if (showNavMesh && navMeshModel) { - navMeshRenderer->render(rs, navMeshModel->getNavMesh(), this); + navMeshRenderer->render(rs, navMeshModel); } // // transparant floorplan parts diff --git a/mapview/3D/grid/GridModel.h b/mapview/3D/grid/GridModel.h index cfb1baa..86769d7 100644 --- a/mapview/3D/grid/GridModel.h +++ b/mapview/3D/grid/GridModel.h @@ -26,6 +26,8 @@ private: Grid grid; Floorplan::IndoorMap* im; + int buildID = 0; + public: GridModel() : grid(gridSize_cm) { @@ -78,6 +80,10 @@ public: }; + int getBuildID() const { + return buildID; + } + void rebuild(Floorplan::IndoorMap* im) { Listener l; @@ -88,6 +94,8 @@ public: Importance::addImportance(grid, &l); //Importance::addImportance(grid, 400); + buildID = rand(); + } }; diff --git a/mapview/3D/grid/GridRenderer.cpp b/mapview/3D/grid/GridRenderer.cpp new file mode 100644 index 0000000..cdb6dff --- /dev/null +++ b/mapview/3D/grid/GridRenderer.cpp @@ -0,0 +1,109 @@ +#include "GridRenderer.h" + +#include +#include + +#include "GridModel.h" +#include + +/** render the given grid using GL commands */ +void GridRenderer::render(const RenderSettings& rs, GridModel* model) { + + if (model == nullptr) {return;} + + rebuildIfNeeded(model); + + rs.shader->bind(); + rs.shader->setModelMatrix(QMatrix4x4()); + + if (!edges.empty()) { + rs.shader->setVertices(edges.getVertices().data()); + rs.shader->setVertexColor(edges.getRGBA().data()); + rs.funcs->glDrawArrays(GL_LINES, 0, edges.getVertices().size()/3); + rs.shader->unsetVertices(); + rs.shader->unsetVertexColor(); + } + + if (!nodes.empty()) { + rs.shader->setVertices(nodes.getVertices().data()); + rs.shader->setVertexColor(nodes.getRGBA().data()); + rs.funcs->glDrawArrays(GL_POINTS, 0, nodes.getVertices().size()/3); + rs.shader->unsetVertices(); + rs.shader->unsetVertexColor(); + } + + rs.shader->release(); + +} + +void GridRenderer::rebuildIfNeeded(GridModel* model) { + + // rebuild needed? + if (lastBuildID == model->getBuildID()) {return;} + lastBuildID = model->getBuildID(); + + // reset previous nodes/edges + edges.clear(); + nodes.clear(); + + // get the grid + auto grid = model->getGrid(); + + const float sz = 1.0f; // scale-z: more/less z-spacing + const float oz = 0.1f; // z-offset + + // build edges + if (showEdges) { + + std::unordered_set used; + + for (MyNode& n1 : *grid) { + glColor3f(0.5, 0.5, 0.5); + for (MyNode& n2 : grid->neighbors(n1)) { + uint64_t min = std::min(n1.getIdx(), n2.getIdx()); + uint64_t max = std::max(n1.getIdx(), n2.getIdx()); + uint64_t idx = max << 32 | min; + if (used.find(idx) == used.end()) { + Point3 p1(n1.x_cm/100.0f, n1.y_cm/100.0f, n1.z_cm/100.0f*sz+oz); + Point3 p2(n2.x_cm/100.0f, n2.y_cm/100.0f, n2.z_cm/100.0f*sz+oz); + edges.addLine(p1, p2, 0,0,0, 0.5); + used.insert(idx); + } + } + } + + } + + // build nodes + if (showNodes) { + + TriangleData points; + + for (MyNode& n : *grid) { + + Color c; + + // get the color to use + switch(colorMode) { + + case GridRendererColorMode::SHOW_NODE_TYPE: { + c = colors[n.getType()]; + break; + } + + case GridRendererColorMode::SHOW_NODE_IMPORTANCE: { + const float xx = n.navImportance - 0.6; + c = Color(xx, xx, xx); + break; + } + + } + + const Point3 p(n.x_cm/100.0f, n.y_cm/100.0f, n.z_cm/100.0f*sz+oz); + points.addPoint(p, c.r, c.g, c.b, 1); + + } + + } + +} diff --git a/mapview/3D/grid/GridRenderer.h b/mapview/3D/grid/GridRenderer.h index 5733dba..abf1004 100644 --- a/mapview/3D/grid/GridRenderer.h +++ b/mapview/3D/grid/GridRenderer.h @@ -4,20 +4,26 @@ #include "MyNode.h" #include -#include + +#include "../misc/Renderable3D.h" +#include "../misc/Shader.h" +#include "../misc/TriangleData.h" enum class GridRendererColorMode { SHOW_NODE_TYPE, SHOW_NODE_IMPORTANCE, }; +class GridModel; + class GridRenderer { private: // settings GridRendererColorMode colorMode = GridRendererColorMode::SHOW_NODE_IMPORTANCE; - bool showEdges = false; + bool showEdges = true; + bool showNodes = true; struct Color { float r,g,b; @@ -28,6 +34,10 @@ private: /** node color depending on the node's type. see ctor */ Color colors[200]; + TriangleData edges; + TriangleData nodes; + int lastBuildID = 0; // to check whether the model has changed + public: /** ctor */ @@ -42,99 +52,15 @@ public: } - 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(Grid* grid) { + void render(const RenderSettings& rs, GridModel* model); - /* +private: - TODO_GL - - glDisable(GL_LIGHTING); - - const float sz = 1.0f; // scale-z: more/less z-spacing - const float oz = 0.1f; // z-offset - - if (showEdges) { - std::unordered_set used; - glBegin(GL_LINES); - for (MyNode& n1 : *grid) { - glColor3f(0.5, 0.5, 0.5); - for (MyNode& n2 : grid->neighbors(n1)) { - uint64_t min = std::min(n1.getIdx(), n2.getIdx()); - uint64_t max = std::max(n1.getIdx(), n2.getIdx()); - uint64_t idx = max << 32 | min; - if (used.find(idx) == used.end()) { - glVertex3f(n1.x_cm/100.0f, n1.z_cm/100.0f*sz+oz, n1.y_cm/100.0f); - glVertex3f(n2.x_cm/100.0f, n2.z_cm/100.0f*sz+oz, n2.y_cm/100.0f); - used.insert(idx); - } - } - } - glEnd(); - } - - - glPointSize(3.0f); - glBegin(GL_POINTS); - for (MyNode& n : *grid) { - - // 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; - } - - } - - glVertex3f(n.x_cm/100.0f, n.z_cm/100.0f*sz+oz, n.y_cm/100.0f); - - } - glEnd(); - - - -// std::vector vec = lint(); -// glPointSize(4.0f); -// glBegin(GL_POINTS); -// glColor3f(1,0,0); -// for (MyNode& n : vec) { -// glVertex3f(n.x_cm/100.0f, n.z_cm/100.0f*s, n.y_cm/100.0f); -// } -// glEnd(); - - //glEnable(GL_DEPTH_TEST); - - - glEnable(GL_LIGHTING); - - */ - - } - -// std::vector lint() { -// std::vector vec; -// lintStair(vec); -// return vec; -// } - -// void lintStair(std::vector& vec) { -// for (MyNode& n1 : *grid) { -// if (n1.getNumNeighbors() <= 5) { vec.push_back(n1);} -// } -// } + void rebuildIfNeeded(GridModel* model); }; diff --git a/mapview/3D/misc/TriangleData.h b/mapview/3D/misc/TriangleData.h index c685232..be97213 100644 --- a/mapview/3D/misc/TriangleData.h +++ b/mapview/3D/misc/TriangleData.h @@ -59,6 +59,17 @@ public: } + void addPoint(Point3 p, const float r, const float g, const float b, const float a) { + + vertices.insert(vertices.end(), {p.x, p.y, p.z}); + rgba.insert(rgba.end(), {r,g,b,a}); + + } + + bool empty() const { + return vertices.empty(); + } + void clear() { vertices.clear(); normals.clear(); diff --git a/mapview/3D/navMesh/NavMeshModel.h b/mapview/3D/navMesh/NavMeshModel.h index d68f174..cd030ba 100644 --- a/mapview/3D/navMesh/NavMeshModel.h +++ b/mapview/3D/navMesh/NavMeshModel.h @@ -24,6 +24,7 @@ private: NM::NavMesh navMesh; NM::NavMeshSettings settings; Floorplan::IndoorMap* im; + int buildID = 0; public: @@ -65,6 +66,10 @@ public: }; + int getBuildID() const { + return buildID; + } + void rebuild(Floorplan::IndoorMap* im) { Listener l; @@ -77,6 +82,8 @@ public: fac.build(im, &l); } + buildID = rand(); + } }; diff --git a/mapview/3D/navMesh/NavMeshRenderer.cpp b/mapview/3D/navMesh/NavMeshRenderer.cpp new file mode 100644 index 0000000..a4aab44 --- /dev/null +++ b/mapview/3D/navMesh/NavMeshRenderer.cpp @@ -0,0 +1,90 @@ +#include "NavMeshRenderer.h" +#include "NavMeshModel.h" + +NavMeshRenderer::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 NavMeshRenderer::rebuildIfNeeded(NavMeshModel* model) { + + // rebuild needed? + if (lastBuildID == model->getBuildID()) {return;} + lastBuildID = model->getBuildID(); + + // get the mesh + NM::NavMesh* navMesh = model->getNavMesh(); + + // clear previous + triangles.clear(); + outlines.clear(); + + // create triangles + for (const NM::NavMeshTriangle* tria : *navMesh) { + + Point3 color; + + switch (tria->getType()) { + case (int) NM::NavMeshType::FLOOR_INDOOR: color = Point3(0.8, 0.8, 0.8); break; + case (int) NM::NavMeshType::FLOOR_OUTDOOR: color = Point3(0.1, 0.8, 0.1); break; + case (int) NM::NavMeshType::DOOR: color = Point3(0.7, 0.7, 0.8); break; + case (int) NM::NavMeshType::STAIR_LEVELED: color = Point3(0.5, 0.5, 0.5); break; + case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.6, 0.6, 0.6); break; + } + + triangles.addTriangle(tria->getP1(), tria->getP3(), tria->getP2(), Point3(0,0,1), color.x, color.y, color.z, 1.0f); + + } + + // create outlines + for (const NM::NavMeshTriangle* tria : *navMesh) { + + Point3 color; + + switch (tria->getType()) { + case (int) NM::NavMeshType::FLOOR_INDOOR: color = Point3(0.6, 0.6, 0.6); break; + case (int) NM::NavMeshType::FLOOR_OUTDOOR: color = Point3(0.0, 0.6, 0.0); break; + case (int) NM::NavMeshType::DOOR: color = Point3(0.5, 0.5, 0.6); break; + case (int) NM::NavMeshType::STAIR_LEVELED: color = Point3(0.4, 0.4, 0.4); break; + case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.4, 0.4, 0.4); break; + } + + const float o = 0.001f; + outlines.addLine(tria->getP1(), tria->getP2(), color.x, color.y, color.z, 1); + outlines.addLine(tria->getP2(), tria->getP3(), color.x, color.y, color.z, 1); + outlines.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1); + + } + +} + +void NavMeshRenderer::render(const RenderSettings& rs, NavMeshModel* model) { + + if (model == nullptr) {return;} + + rebuildIfNeeded(model); + + rs.shader->bind(); + rs.shader->setModelMatrix(QMatrix4x4()); + + rs.shader->setVertices(triangles.getVertices().data()); + rs.shader->setVertexColor(triangles.getRGBA().data()); + rs.funcs->glDrawArrays(GL_TRIANGLES, 0, triangles.getVertices().size()/3); + rs.shader->unsetVertices(); + rs.shader->unsetVertexColor(); + + rs.shader->setVertices(outlines.getVertices().data()); + rs.shader->setVertexColor(outlines.getRGBA().data()); + rs.funcs->glDrawArrays(GL_LINES, 0, outlines.getVertices().size()/3); + rs.shader->unsetVertices(); + rs.shader->unsetVertexColor(); + + rs.shader->release(); + +} diff --git a/mapview/3D/navMesh/NavMeshRenderer.h b/mapview/3D/navMesh/NavMeshRenderer.h index 5b89706..d1a90f9 100644 --- a/mapview/3D/navMesh/NavMeshRenderer.h +++ b/mapview/3D/navMesh/NavMeshRenderer.h @@ -16,6 +16,8 @@ #include "../misc/Shader.h" #include "../misc/TriangleData.h" +class NavMeshModel; + class NavMeshRenderer { private: @@ -30,22 +32,17 @@ private: 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]; +// /** node color depending on the node's type. see ctor */ +// Color colors[200]; + + TriangleData triangles; + TriangleData outlines; + int lastBuildID = 0; // to check whether the model has changed 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); - - } + NavMeshRenderer(); // void setNodeColorMode(const GridRendererColorMode mode) {this->colorMode = mode;} @@ -53,105 +50,11 @@ public: /** render the given grid using GL commands */ - void render(const RenderSettings& rs, NM::NavMesh* navMesh, QOpenGLWidget* dst) { + void render(const RenderSettings& rs, NavMeshModel* model); - if (navMesh == nullptr) {return;} +private: - - rs.shader->bind(); - rs.shader->setModelMatrix(QMatrix4x4()); - - TriangleData data; - - for (const NM::NavMeshTriangle* tria : *navMesh) { - - Point3 color; - - switch (tria->getType()) { - case (int) NM::NavMeshType::FLOOR_INDOOR: color = Point3(0.8, 0.8, 0.8); break; - case (int) NM::NavMeshType::FLOOR_OUTDOOR: color = Point3(0.1, 0.8, 0.1); break; - case (int) NM::NavMeshType::DOOR: color = Point3(0.7, 0.7, 0.8); break; - case (int) NM::NavMeshType::STAIR_LEVELED: color = Point3(0.5, 0.5, 0.5); break; - case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.6, 0.6, 0.6); break; - } - - data.addTriangle(tria->getP1(), tria->getP3(), tria->getP2(), Point3(0,0,1), color.x, color.y, color.z, 1.0f); - -// vertices.insert(vertices.end(), {tria->getP1().x, tria->getP1().y, tria->getP1().z}); -// vertices.insert(vertices.end(), {tria->getP3().x, tria->getP3().y, tria->getP3().z}); -// vertices.insert(vertices.end(), {tria->getP2().x, tria->getP2().y, tria->getP2().z}); - -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); - - } - - rs.shader->setVertices(data.getVertices().data()); - rs.shader->setVertexColor(data.getRGBA().data()); - rs.funcs->glDrawArrays(GL_TRIANGLES, 0, data.getVertices().size()/3); - rs.shader->unsetVertices(); - rs.shader->unsetVertexColor(); - - data.clear(); - - - for (const NM::NavMeshTriangle* tria : *navMesh) { - - Point3 color; - - switch (tria->getType()) { - case (int) NM::NavMeshType::FLOOR_INDOOR: color = Point3(0.6, 0.6, 0.6); break; - case (int) NM::NavMeshType::FLOOR_OUTDOOR: color = Point3(0.0, 0.6, 0.0); break; - case (int) NM::NavMeshType::DOOR: color = Point3(0.5, 0.5, 0.6); break; - case (int) NM::NavMeshType::STAIR_LEVELED: color = Point3(0.4, 0.4, 0.4); break; - case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.4, 0.4, 0.4); break; - } - - const float o = 0.001f; - data.addLine(tria->getP1(), tria->getP2(), color.x, color.y, color.z, 1); - data.addLine(tria->getP2(), tria->getP3(), color.x, color.y, color.z, 1); - data.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1); - -// vertices.insert(vertices.end(), {tria->getP1().x, tria->getP1().y, tria->getP1().z+o}); -// vertices.insert(vertices.end(), {tria->getP2().x, tria->getP2().y, tria->getP2().z+o}); - -// vertices.insert(vertices.end(), {tria->getP2().x, tria->getP2().y, tria->getP2().z+o}); -// vertices.insert(vertices.end(), {tria->getP3().x, tria->getP3().y, tria->getP3().z+o}); - -// vertices.insert(vertices.end(), {tria->getP3().x, tria->getP3().y, tria->getP3().z+o}); -// vertices.insert(vertices.end(), {tria->getP1().x, tria->getP1().y, tria->getP1().z+o}); - -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); -// colors.insert(colors.end(), {color.x, color.y, color.z, 1}); - - } - - rs.shader->setVertices(data.getVertices().data()); - rs.shader->setVertexColor(data.getRGBA().data()); - rs.funcs->glDrawArrays(GL_LINES, 0, data.getVertices().size()/3); - rs.shader->unsetVertices(); - rs.shader->unsetVertexColor(); - - rs.shader->release(); - - } - -// std::vector lint() { -// std::vector vec; -// lintStair(vec); -// return vec; -// } - -// void lintStair(std::vector& vec) { -// for (MyNode& n1 : *grid) { -// if (n1.getNumNeighbors() <= 5) { vec.push_back(n1);} -// } -// } + void rebuildIfNeeded(NavMeshModel* model); };