diff --git a/mapview/3D/MV3DElement.h b/mapview/3D/MV3DElement.h index 583132f..b27f14b 100644 --- a/mapview/3D/MV3DElement.h +++ b/mapview/3D/MV3DElement.h @@ -19,6 +19,9 @@ public: /** repaint me */ virtual void paintGL() = 0; + /** is this a transparent element? */ + virtual bool isTransparent() const = 0; + }; diff --git a/mapview/3D/MV3DElementAccessPoint.h b/mapview/3D/MV3DElementAccessPoint.h index 54cfff5..0634e7d 100644 --- a/mapview/3D/MV3DElementAccessPoint.h +++ b/mapview/3D/MV3DElementAccessPoint.h @@ -30,6 +30,10 @@ protected: } + bool isTransparent() const override { + return false; + } + }; #endif // MV3DELEMENTACCESSPOINT_H diff --git a/mapview/3D/MV3DElementFingerprintLocation.h b/mapview/3D/MV3DElementFingerprintLocation.h index e39102e..9b15232 100644 --- a/mapview/3D/MV3DElementFingerprintLocation.h +++ b/mapview/3D/MV3DElementFingerprintLocation.h @@ -31,6 +31,11 @@ protected: } + bool isTransparent() const override { + return false; + } + + }; #endif // MV3DELEMENTFINGERPRINTLOCATION_H diff --git a/mapview/3D/MV3DElementFloorObstacleDoor.h b/mapview/3D/MV3DElementFloorObstacleDoor.h index 01bf481..82ea3bf 100644 --- a/mapview/3D/MV3DElementFloorObstacleDoor.h +++ b/mapview/3D/MV3DElementFloorObstacleDoor.h @@ -4,8 +4,9 @@ #include #include +#include "misc/Cube.h" #include "MV3DElement.h" -#include "misc/Plane.h" +//#include "misc/Plane.h" @@ -24,12 +25,43 @@ public: /** repaint me */ void paintGL() override { - glColor3f(0.4, 0.4, 0.4); - Plane p(fo->from, fo->to, f->atHeight, fo->height); - p.paintGL(); + const Point2 from = fo->from; + const Point2 to = fo->to; + const float atHeight = f->atHeight; + const float height = fo->height; + const float thickness_m = 0.05; // 5cm door + + const float rad = std::atan2(to.y - from.y, to.x - from.x); + const float deg = rad * 180 / M_PI; + + const Point2 cen2 = (from+to)/2; + const Point3 pos(cen2.x, cen2.y, atHeight + height/2); + + // div by 2.01 to prevent overlapps and z-fi + const float sx = from.getDistance(to) / 2.01f; + const float sy = thickness_m / 2.01f; + const float sz = height / 2.01f; // prevent overlaps + const Point3 size(sx, sy, sz); + const Point3 rot(0,0,deg); + + // fill color + glColor3f(0.395, 0.263, 0.129); + + // build + Cube cube(pos, size, rot); + cube.paintGL(); + + //glColor3f(0.4, 0.4, 0.4); + //Plane p(fo->from, fo->to, f->atHeight, fo->height); + //p.paintGL(); } + bool isTransparent() const override { + return false; + } + + }; #endif // MV3DELEMENTFLOOROBSTACLEDOOR_H diff --git a/mapview/3D/MV3DElementFloorObstacleWall.h b/mapview/3D/MV3DElementFloorObstacleWall.h index 06f2533..28d6edf 100644 --- a/mapview/3D/MV3DElementFloorObstacleWall.h +++ b/mapview/3D/MV3DElementFloorObstacleWall.h @@ -4,6 +4,7 @@ #include #include +#include "misc/Cube.h" #include "MV3DElement.h" @@ -28,17 +29,93 @@ protected: Point2 from; Point2 to; + float thickness_m; + Floorplan::Material mat; float atHeight; float height; - Wall(const Point2 from, const Point2 to, float atHeight, float height) : - from(from), to(to), atHeight(atHeight), height(height) {;} + Wall(const Point2 from, const Point2 to, const float thickness_m, const Floorplan::Material mat, float atHeight, float height) : + from(from), to(to), thickness_m(thickness_m), mat(mat), atHeight(atHeight), height(height) {;} void paintGL() { + const float rad = std::atan2(to.y - from.y, to.x - from.x); + const float deg = rad * 180 / M_PI; + + //const Point2 dir = (to - from).normalized(); + //const Point2 dirPerp = dir.perpendicular(); + //const float w = 0.1; + + const Point2 cen2 = (from+to)/2; + const Point3 pos(cen2.x, cen2.y, atHeight + height/2); + + // div by 2.01 to prevent overlapps and z-fi + const float sx = from.getDistance(to) / 2.01f; + const float sy = thickness_m / 2.01f; + const float sz = height / 2.01f; // prevent overlaps + const Point3 size(sx, sy, sz); + const Point3 rot(0,0,deg); + + // fill color + if (mat == Floorplan::Material::CONCRETE) { + glColor3f(0.5, 0.5, 0.5); + } else { + glColor3f(0.75, 0.75, 0.75); + } + + // build + Cube cube(pos, size, rot); + cube.paintGL(); + + + /* float y1 = atHeight; float y2 = atHeight + height; + + const Point2 p01 = from + dirPerp * w; + const Point2 p02 = from - dirPerp * w; + const Point2 p03 = to - dirPerp * w; + const Point2 p04 = to + dirPerp * w; + + // fill the wall + if (mat == Floorplan::Material::CONCRETE) { + glColor3f(0.5, 0.5, 0.5); + } else { + glColor3f(0.75, 0.75, 0.75); + } + + auto renderQuad = [&] (const Point2 p1, const Point2 p2) { + glVertex3f(p1.x, y1, p1.y); + glVertex3f(p2.x, y1, p2.y); + glVertex3f(p2.x, y2, p2.y); + glVertex3f(p1.x, y2, p1.y); + }; + + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + //glNormal3f(n.x, n.y, n.z); + + // short + renderQuad(p01, p02); + renderQuad(p03, p04); + + // long + renderQuad(p02, p03); + renderQuad(p04, p01); + + //glVertex3f(p1.x, p1.y, p1.z); + //glVertex3f(p2.x, p2.y, p2.z); + //glVertex3f(p3.x, p3.y, p3.z); + //glVertex3f(p4.x, p4.y, p4.z); + glEnd(); + glBegin(GL_CULL_FACE); + + + */ + + +/* // polygon edges Point3 p1 = Point3(from.x, y1, from.y); Point3 p2 = Point3(to.x, y1, to.y); @@ -56,8 +133,8 @@ protected: Point3 view(99,99,99); if ((view-n).length() > (view+n).length()) {n = -n;} - // fill the wall - glColor3f(0.75, 0.75, 0.75); + + glDisable(GL_CULL_FACE); glBegin(GL_QUADS); glNormal3f(n.x, n.y, n.z); @@ -68,6 +145,54 @@ protected: glEnd(); glEnable(GL_CULL_FACE); + */ + } + + + }; + + struct Window { + + Point2 from; + Point2 to; + float atHeight; + float height; + + Window(const Point2 from, const Point2 to, float atHeight, float height) : + from(from), to(to), atHeight(atHeight), height(height) {;} + + void paintGL() { + + float y1 = atHeight; + float y2 = atHeight + height; + + // polygon edges + Point3 p1 = Point3(from.x, y1, from.y); + Point3 p2 = Point3(to.x, y1, to.y); + Point3 p3 = Point3(to.x, y2, to.y); + Point3 p4 = Point3(from.x, y2, from.y); + + // calculate normal + Point3 n = Math::normal(p2-p1, p3-p1); + + // align normals to virtual viewport + Point3 view(99,99,99); + if ((view-n).length() > (view+n).length()) {n = -n;} + + glColor4f(0.75, 0.85, 1.0, 0.35); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + glNormal3f(n.x, n.y, n.z); + glVertex3f(p1.x, p1.y, p1.z); + glVertex3f(p2.x, p2.y, p2.z); + glVertex3f(p3.x, p3.y, p3.z); + glVertex3f(p4.x, p4.y, p4.z); + glEnd(); + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); + } }; @@ -97,7 +222,7 @@ protected: glDisable(GL_LIGHTING); glBegin(GL_LINES); - glColor3f(1,1,1); + glColor3f(0.9, 0.9, 0.9); // top glVertex3f(p3.x, p3.y, p3.z); @@ -134,13 +259,14 @@ protected: /** repaint me */ void paintGL() override { + if (fo->material == Floorplan::Material::GLASS) { + Window win(fo->from, fo->to, f->atHeight, f->height); + win.paintGL(); + } else if (fo->type == Floorplan::ObstacleType::WALL) { - - if (fo->type == Floorplan::ObstacleType::WALL) { - - Wall wall(fo->from, fo->to, f->atHeight, f->height); + Wall wall(fo->from, fo->to, fo->thickness_m, fo->material, f->atHeight, f->height); wall.paintGL(); } else if (fo->type == Floorplan::ObstacleType::HANDRAIL) { @@ -152,6 +278,11 @@ protected: } + bool isTransparent() const override { + return fo->material == Floorplan::Material::GLASS; + } + + }; #endif // MV3DELEMENTFLOOROBSTACLEWALL_H diff --git a/mapview/3D/MV3DElementFloorOutline.h b/mapview/3D/MV3DElementFloorOutline.h index 541a657..5ed6747 100644 --- a/mapview/3D/MV3DElementFloorOutline.h +++ b/mapview/3D/MV3DElementFloorOutline.h @@ -118,6 +118,9 @@ protected: } + bool isTransparent() const override { + return false; + } }; diff --git a/mapview/3D/MV3DElementRegistrationPoint.h b/mapview/3D/MV3DElementRegistrationPoint.h index 9232a7a..612f477 100644 --- a/mapview/3D/MV3DElementRegistrationPoint.h +++ b/mapview/3D/MV3DElementRegistrationPoint.h @@ -29,6 +29,10 @@ protected: } + bool isTransparent() const override { + return false; + } + }; #endif // MV3DELEMENTREGISTRATIONPOINT_H diff --git a/mapview/3D/MV3DElementStair.h b/mapview/3D/MV3DElementStair.h index 8b204ca..2d27dd4 100644 --- a/mapview/3D/MV3DElementStair.h +++ b/mapview/3D/MV3DElementStair.h @@ -57,6 +57,10 @@ protected: } + bool isTransparent() const override { + return false; + } + }; #endif // MV3DELEMENTSTAIR_H diff --git a/mapview/3D/MapView3D.cpp b/mapview/3D/MapView3D.cpp index 540642b..883b0cf 100644 --- a/mapview/3D/MapView3D.cpp +++ b/mapview/3D/MapView3D.cpp @@ -212,8 +212,21 @@ void MapView3D::draw() { } else { + std::vector elements = getModel()->getVisibleElements(); + + // order: transparent last + auto func = [] (const MapModelElement* e1, const MapModelElement* e2) { + if (e1->getMV3D() == nullptr) {return false;} + if (e2->getMV3D() == nullptr) {return true;} + const bool e1t = e1->getMV3D()->isTransparent(); + const bool e2t = e2->getMV3D()->isTransparent(); + return e1t < e2t; + }; + + std::sort(elements.begin(), elements.end(), func); + // show floorplan - for (MapModelElement* el : getModel()->getVisibleElements()) { + for (MapModelElement* el : elements) { if (el->getMV3D()) {el->getMV3D()->paintGL();} } diff --git a/mapview/3D/misc/Cube.h b/mapview/3D/misc/Cube.h index 748a08a..79ce094 100644 --- a/mapview/3D/misc/Cube.h +++ b/mapview/3D/misc/Cube.h @@ -9,21 +9,38 @@ class Cube { private: Point3 pos; - float size; + Point3 size; + Point3 rot; public: - Cube(Point3 pos, float size) : pos(pos), size(size) { + Cube(Point3 pos, float size) : pos(pos), size(size,size,size), rot(0,0,0) { + + } + + Cube(Point3 pos, Point3 size, Point3 rot) : pos(pos), size(size), rot(rot) { } void paintGL() { - float s = size; + float s = 1; glPushMatrix(); - glTranslatef(pos.x, pos.z, pos.y); + + // 3) move to destination + glTranslatef(pos.x, pos.z, pos.y); // swap yz + + // 2) rotate + glRotatef(rot.x, 1, 0, 0); + glRotatef(rot.y, 0, 0, 1); // swap yz + glRotatef(rot.z, 0, 1, 0); + + // 1) scale + glScalef(size.x, size.z, size.y); // swap yz + + glBegin(GL_QUADS);