This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
IndoorMap/mapview/3D/MapView3D.cpp
root e5e19779d5 worked on android port
opengl1 -> es
2018-01-31 17:15:11 +01:00

329 lines
6.7 KiB
C++

#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<MapModelElement*> 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<MapModelElement*> elements = getModel()->getVisibleElements();
for (MapModelElement* el : elements) {
if (el->getMV3D() && el->getMV3D()->isTransparent()) {el->getMV3D()->render(rs);}
}
}
*/
}