#include "../../fixC11.h" #include "MapView3D.h" #include "../model/MapModelElement.h" #include "../model/MapModel.h" #include "../3DGrid/GridModel.h" #include "../3DGrid/GridRenderer.h" #include "../3DNavMesh/NavMeshModel.h" #include "../3DNavMesh/NavMeshRenderer.h" MapView3D::MapView3D(QWidget *parent) : QOpenGLWidget(parent) { rot.x = 0; rot.y = 0; rot.z = 0; center.x = 0; center.y = 0; center.z = 0; scale.x = 0.05f; scale.y = 0.05f; scale.z = 0.05f; gridRenderer = new GridRenderer(); } void MapView3D::initializeGL() { //setFormat(QGLFormat(QGL::SampleBuffers)); QOpenGLWidget::initializeGL(); glCullFace(GL_FRONT); glFrontFace(GL_CCW); //glDisable(GL_CULL_FACE); glEnable(GL_CULL_FACE); // culling, lighting, depth-test, ... glEnable(GL_DEPTH_TEST); //glShadeModel(GL_SMOOTH); // glEnable(GL_MULTISAMPLE); // glEnable(GL_LINE_SMOOTH); /* TODO_GL glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); // GLfloat light0_position [] = {+50, 50, +50, 1}; // GLfloat light1_position [] = {-50, 50, -50, 1}; // glLightfv ( GL_LIGHT0, GL_POSITION, light0_position ); // glLightfv ( GL_LIGHT1, GL_POSITION, light1_position ); GLfloat light_diffuse []={ 0.7, 0.7, 0.7, 1.0 }; glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse ); glLightfv ( GL_LIGHT1, GL_DIFFUSE, light_diffuse ); // otherwise scaling the scene kills lighting normals! glEnable(GL_NORMALIZE); // allow using glColor3(r,g,b) glEnable(GL_COLOR_MATERIAL); // GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; // GLfloat mat_shininess[] = { 50.0 }; // glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); // glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); */ // background color //glClearColor(Qt::white); glClearColor(1,1,1,1); } void MapView3D::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* TODO_GL glLoadIdentity(); glScalef(+1, -1, +1); // 3) scale glScalef(scale.x, scale.y, scale.z); // 2) rotate around center glRotatef(rot.x, 1.0, 0.0, 0.0); glRotatef(rot.z, 0.0, 1.0, 0.0); glRotatef(rot.y, 0.0, 0.0, 1.0); // 1) post translate (mouse moving) glTranslatef(center.x, center.z, center.y); // 0) swap the y axis //glScalef(+1, -1, +1); GLfloat light0_position [] = {100, 50, 100, 1}; glLightfv ( GL_LIGHT0, GL_POSITION, light0_position ); GLfloat light1_position [] = {0, 50, 0, 1}; glLightfv ( GL_LIGHT1, GL_POSITION, light1_position ); // // 1) translate into center // glTranslatef(tra.x, tra.y, tra.z); */ draw(); } void MapView3D::resizeGL(int width, int height) { //int side = qMin(width, height); //glViewport((width - side) / 2, (height - side) / 2, side, side); //glViewport(0, 0, width, height); /* TODO_GL glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glOrtho(-2, +2, -2, +2, 1.0, 25.0); //glFrustum(-1,1, -1,1, 0.1,20); viewport.size.x = 2.0f; viewport.size.y = 2.0f * height / width; const float w = viewport.size.x; const float h = viewport.size.y; glOrtho(-w, +w, -h, +h, -20, +20); //glScalef(1,-1,1); //glFrustum(+w, -w, -h, +h, -20, +20); glMatrixMode(GL_MODELVIEW); */ } void MapView3D::mousePressEvent(QMouseEvent* e) { mouse.btn = e->button(); mouse.x = e->x(); mouse.y = e->y(); update(); } void MapView3D::mouseMoveEvent(QMouseEvent* e) { float dx = mouse.x - e->x(); float dy = mouse.y - e->y(); if (mouse.btn == 1) { rot.z -= dx/2.0f; rot.x -= dy/2.0f; } else if (mouse.btn == 4) { //Point3 vec(-dx / width() * 2 * viewport.size.x, 0, +dy / height() * 2 * viewport.size.y); Point3 vec(-dx / width() * 2 * viewport.size.x, 0, +dy / height() * 2 * viewport.size.y); //Point3 vec(-dx * 2 / width() , 0, +dy * 2 / height()); vec = vec.rot(rot.x/180*M_PI, rot.y/180*M_PI, rot.z/180*M_PI); vec /= scale; center += vec; } mouse.x = e->x(); mouse.y = e->y(); update(); } void MapView3D::mouseReleaseEvent(QMouseEvent* e) { (void) e; update(); } void MapView3D::wheelEvent(QWheelEvent* e) { float f = e->delta() / 120.0f; scale *= (f > 0) ? (2) : (0.5); update(); } void MapView3D::setShowFloorplan(bool show) { this->showFloorplan = show; //if (gridModel) {delete gridModel; gridModel = nullptr;} //if (navMeshModel) {delete navMeshModel; navMeshModel = nullptr;} update(); } void MapView3D::setShowGrid(bool show) { this->showGrid = show; if (!show) {update(); return;} // delete the previous grid (if any) if (gridModel) {delete gridModel; gridModel = nullptr;} // build a new model GridModel* gm = new GridModel(); Floorplan::IndoorMap* im = getModel()->getMap(); gm->rebuild(im); // remember this->gridModel = gm; // update UI update(); } void MapView3D::setShowNavMesh(bool show) { this->showNavMesh = show; if (!show) {update(); return;} // delete the previous grid (if any) if (navMeshModel) {delete navMeshModel; navMeshModel = nullptr;} // build a new model NavMeshModel* nm = new NavMeshModel(); Floorplan::IndoorMap* im = getModel()->getMap(); nm->rebuild(im); // remember this->navMeshModel = nm; // update UI update(); } #include "misc/Shader.h" void MapView3D::draw() { static RenderSettings rs = RenderSettings(new Shader()); glViewport(0, 0, width(), height()); //glCullFace(GL_FRONT); //glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // view QMatrix4x4 V; V.scale(scale.x, scale.y, scale.z); V.rotate(rot.x, 1.0, 0.0, 0.0); V.rotate(rot.y, 0.0, 1.0, 0.0); V.rotate(rot.z, 0.0, 0.0, 1.0); V.translate(center.x, center.z, center.y); V.translate(0,0,-50); // V.lookAt(QVector3D(30,-25,25), QVector3D(30,10,0), QVector3D(0,1,0)); // projection QMatrix4x4 P; float aspect = (float) width() / (float) height(); float w = 2.0f; float h = 2.0f * height() / width(); viewport.size.x = w; viewport.size.y = h; //P.ortho(-w, +w, +h, -h, 0.1f, +30); // glOrtho(-w, +w, -h, +h, -20, +20); P.perspective(45.0f, aspect, 0.01, 100); rs.shader->bind(); rs.shader->setViewMatrix(V); rs.shader->setProjectionMatrix(P); Cube cube(Point3(0,0,0), 1); cube.setColor(1,0,0); cube.render(rs); /* // solid floorplan parts if (showFloorplan) { std::vector elements = getModel()->getVisibleElements(); for (MapModelElement* el : elements) { if (el->getMV3D() && !el->getMV3D()->isTransparent()) {el->getMV3D()->render(rs);} } } if (showGrid && gridModel) { gridRenderer->paintGL(gridModel->getGrid()); } if (showNavMesh && navMeshModel) { navMeshRenderer->paintGL(navMeshModel->getNavMesh(), this); } // transparant floorplan parts if (showFloorplan) { std::vector elements = getModel()->getVisibleElements(); for (MapModelElement* el : elements) { if (el->getMV3D() && el->getMV3D()->isTransparent()) {el->getMV3D()->render(rs);} } } */ }