#ifndef MV3DELEMENTFLOOROBSTACLEWALL_H #define MV3DELEMENTFLOOROBSTACLEWALL_H #include #include #include "misc/Cube.h" #include "MV3DElement.h" class MV3DElementFloorObstacleWall : public MV3DElement { Floorplan::Floor* f; Floorplan::FloorObstacleLine* fo; public: /** ctor */ MV3DElementFloorObstacleWall(Floorplan::Floor* f, Floorplan::FloorObstacleLine* fo) : f(f), fo(fo) { ; } protected: struct Wall { Point2 from; Point2 to; float thickness_m; Floorplan::Material mat; float atHeight; float 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); Point3 p3 = Point3(to.x, y2, to.y); Point3 p4 = Point3(from.x, y2, from.y); // calculate normal // Point3 v1 = p2-p1; // Point3 v2 = p3-p1; // Point3 n = cross(v1, v2); // n/=n.length(); 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;} 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); */ } }; 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); } }; struct Handrail { Point2 from; Point2 to; float atHeight; float height; Handrail(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(from.x, y2, from.y); Point3 p4 = Point3(to.x, y2, to.y); glDisable(GL_LIGHTING); glBegin(GL_LINES); glColor3f(0.9, 0.9, 0.9); // top glVertex3f(p3.x, p3.y, p3.z); glVertex3f(p4.x, p4.y, p4.z); // start bar glVertex3f(p1.x, p1.y, p1.z); glVertex3f(p3.x, p3.y, p3.z); // end bar glVertex3f(p2.x, p2.y, p2.z); glVertex3f(p4.x, p4.y, p4.z); glColor3f(0.6, 0.6, 0.6); // intermediate bars const Point3 d1 = p2-p1; const Point3 d2 = p4-p3; const int numBars = d2.length() / 1; for (int i = 1; i < numBars; ++i) { const Point3 s = p1 + d1 * i / numBars; const Point3 e = p3 + d2 * i / numBars; glVertex3f(s.x, s.y, s.z); glVertex3f(e.x, e.y, e.z); } glEnd(); glEnable(GL_LIGHTING); } }; /** 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) { Wall wall(fo->from, fo->to, fo->thickness_m, fo->material, f->atHeight, f->height); wall.paintGL(); } else if (fo->type == Floorplan::ObstacleType::HANDRAIL) { Handrail rail(fo->from, fo->to, f->atHeight, 1.0); rail.paintGL(); } } bool isTransparent() const override { return fo->material == Floorplan::Material::GLASS; } }; #endif // MV3DELEMENTFLOOROBSTACLEWALL_H