worked on 3D display

some ui changes
refactoring
new icons
This commit is contained in:
2018-02-03 23:30:55 +01:00
parent e5e19779d5
commit 3b62f23c0e
21 changed files with 1054 additions and 765 deletions

View File

@@ -6,11 +6,10 @@
#include "misc/Cube.h"
#include "misc/Window.h"
#include "misc/Handrail.h"
#include "MV3DElement.h"
class MV3DElementFloorObstacleWall : public MV3DElement {
Floorplan::Floor* f;
@@ -52,9 +51,10 @@ protected:
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.02f;
const float sy = thickness_m / 2.02f;
const float sz = height / 2.02f; // prevent overlaps
const float div = 2.015f; // prevent overlaps
const float sx = from.getDistance(to) / div;
const float sy = thickness_m / div;
const float sz = height / div;
const Point3 size(sx, sy, sz);
const Point3 rot(0,0,deg);
@@ -72,71 +72,6 @@ protected:
};
struct Handrail : public Renderable3D {
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 render(const RenderSettings& rs) override {
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);
/*
TODO_GL
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 render(const RenderSettings& rs) override {

View File

@@ -8,114 +8,44 @@
#include "../../lib/gpc/gpc.h"
#include "misc/Polygon.h"
#include "misc/Shader.h"
#include "misc/Outline.h"
class MV3DElementFloorOutline : public MV3DElement {
Floorplan::Floor* f;
Floorplan::FloorOutline* out;
struct ToRender {
struct Temp {
Point2 cacheSum;
Polygon* pol = nullptr;
std::vector<std::vector<Point3>> trias;
};
std::unordered_map<std::string, ToRender*> elements;
Temp tempIndoor;
Temp tempOutdoor;
Outline outlineIndoor;
Outline outlineOutdoor;
public:
/** ctor */
MV3DElementFloorOutline(Floorplan::Floor* f, Floorplan::FloorOutline* out) : f(f), out(out) {
;
outlineOutdoor.setColor(0.0, 0.5, 0.0);
outlineIndoor.setColor(0.2, 0.2, 0.2);
}
protected:
/** repaint me */
void render(const RenderSettings& rs) override {
rebuildIfNeeded();
rs.shader->bind();
glDisable(GL_CULL_FACE);
QMatrix4x4 mat;
rs.shader->setModelMatrix(mat);
for (auto& it : elements) {
//Polygon& pol = it.second->pol;
std::vector<std::vector<Point3>>& trias = it.second->trias;
if (it.first == "outdoor") {
rs.shader->setColor(0.0, 0.5, 0.0);
} else {
rs.shader->setColor(0.2, 0.2, 0.2);
}
std::vector<float> values;
std::vector<float> normals;
for (const std::vector<Point3>& tria : trias) {
for (int i = 2; i < tria.size(); ++i) {
const Point3 p1 = tria[i-2];
const Point3 p2 = tria[i-1];
const Point3 p3 = tria[i-0];
values.push_back(p1.x); values.push_back(p1.y); values.push_back(p1.z);
values.push_back(p2.x); values.push_back(p2.y); values.push_back(p2.z);
values.push_back(p3.x); values.push_back(p3.y); values.push_back(p3.z);
normals.push_back(0); normals.push_back(1); normals.push_back(0);
normals.push_back(0); normals.push_back(1); normals.push_back(0);
normals.push_back(0); normals.push_back(1); normals.push_back(0);
}
}
rs.shader->setVertices(values.data());
rs.shader->setNormals(normals.data());
glDrawArrays(GL_TRIANGLES, 0, values.size() / 3);
rs.shader->unsetVertices();
rs.shader->unsetNormals();
/*
TODO_GL
if (it.first == "outdoor") {
glColor3f(0.0, 0.5, 0.0);
} else {
glColor3f(0.2, 0.2, 0.2);
}
glDisable(GL_CULL_FACE);
for (const std::vector<Point3>& tria : trias) {
glNormal3f(0, 1, 0);
glBegin(GL_TRIANGLE_STRIP);
for (const Point3& p3 : tria) {
glVertex3f(p3.x, p3.z, p3.y);
}
glEnd();
}
glEnable(GL_CULL_FACE);
*/
}
glEnable(GL_CULL_FACE);
rs.shader->release();
outlineIndoor.render(rs);
outlineOutdoor.render(rs);
}
@@ -124,17 +54,12 @@ protected:
auto filterIndoor = [] (const Floorplan::FloorOutlinePolygon* p) {return p->outdoor == false;};
auto filterOutdoor = [] (const Floorplan::FloorOutlinePolygon* p) {return p->outdoor == true;};
if (elements.empty()) {
elements["indoor"] = new ToRender();
elements["outdoor"] = new ToRender();
}
rebuildIfNeeded(filterIndoor, elements["indoor"]);
rebuildIfNeeded(filterOutdoor, elements["outdoor"]);
rebuildIfNeeded(filterIndoor, outlineIndoor, tempIndoor);
rebuildIfNeeded(filterOutdoor, outlineOutdoor, tempOutdoor);
}
template <typename Filter> void rebuildIfNeeded(Filter include, ToRender* dst) {
template <typename Filter> void rebuildIfNeeded(Filter include, Outline& dst, Temp& tmp) {
const std::vector<Floorplan::FloorOutlinePolygon*>& polys = *out;
@@ -148,25 +73,28 @@ protected:
}
// already up to date?
if (cacheSum == dst->cacheSum) {return;}
dst->cacheSum = cacheSum;
if (cacheSum == tmp.cacheSum) {return;}
tmp.cacheSum = cacheSum;
// rebuild
std::vector<gpc_polygon> add;
std::vector<gpc_polygon> rem;
if (dst->pol) {delete dst->pol;}
dst->pol = new Polygon();
if (tmp.pol) {delete tmp.pol;}
tmp.pol = new Polygon();
for (Floorplan::FloorOutlinePolygon* poly : polys) {
if (!include(poly)) {continue;}
switch (poly->method) {
case Floorplan::OutlineMethod::ADD: dst->pol->add(poly->poly); break;
case Floorplan::OutlineMethod::REMOVE: dst->pol->remove(poly->poly); break;
case Floorplan::OutlineMethod::ADD: tmp.pol->add(poly->poly); break;
case Floorplan::OutlineMethod::REMOVE: tmp.pol->remove(poly->poly); break;
default: throw 1;
}
}
dst->trias = dst->pol->get(f->atHeight);
//dst->trias = dst->pol->get(f->atHeight);
std::vector<std::vector<Point3>> trias = tmp.pol->get(f->atHeight);
dst.clear();
dst.add(trias);
}

View File

@@ -5,6 +5,7 @@
#include "misc/Cube.h"
#include "MV3DElement.h"
#include "misc/Shader.h"
class MV3DElementStair : public MV3DElement {
@@ -24,7 +25,54 @@ protected:
/** repaint me */
void render(const RenderSettings& rs) override {
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
std::vector<float> vertices;
std::vector<float> normals;
const std::vector<Floorplan::StairPart> parts = stair->getParts();
const std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(parts, floor);
for (int i = 0; i < (int) parts.size(); ++i) {
//const Floorplan::StairPart& part = parts[i];
const Floorplan::Quad3& quad = quads[i];
//const Floorplan::Quad3 quad = part.getQuad(floor);
const Point3 p1 = quad.p2-quad.p1;
const Point3 p2 = quad.p4-quad.p1;
Point3 n = Math::normal(p1,p2);
if (n.z < 0) {n = -n;}
vertices.insert(vertices.end(), {quad.p1.x, quad.p1.y, quad.p1.z});
vertices.insert(vertices.end(), {quad.p2.x, quad.p2.y, quad.p2.z});
vertices.insert(vertices.end(), {quad.p3.x, quad.p3.y, quad.p3.z});
vertices.insert(vertices.end(), {quad.p3.x, quad.p3.y, quad.p3.z});
vertices.insert(vertices.end(), {quad.p4.x, quad.p4.y, quad.p4.z});
vertices.insert(vertices.end(), {quad.p1.x, quad.p1.y, quad.p1.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
normals.insert(normals.end(), {n.x, n.y, n.z});
}
rs.shader->bind();
rs.shader->setModelMatrix(QMatrix4x4());
rs.shader->setColor(1.0, 0.55, 0.55);
rs.shader->setVertices(vertices.data());
rs.shader->setNormals(normals.data());
glDrawArrays(GL_TRIANGLES, 0, vertices.size()/3);
rs.shader->unsetVertices();
rs.shader->unsetNormals();
rs.shader->release();
/*
TODO_GL

View File

@@ -11,6 +11,8 @@
#include "../3DNavMesh/NavMeshModel.h"
#include "../3DNavMesh/NavMeshRenderer.h"
#include <QPushButton>
MapView3D::MapView3D(QWidget *parent) : QOpenGLWidget(parent) {
rot.x = 0;
@@ -21,12 +23,51 @@ MapView3D::MapView3D(QWidget *parent) : QOpenGLWidget(parent) {
center.y = 0;
center.z = 0;
scale.x = 0.05f;
scale.y = 0.05f;
scale.z = 0.05f;
scale.x = 1.0f;
scale.y = 1.0f;
scale.z = 1.0f;
gridRenderer = new GridRenderer();
QString style = "QPushButton:checked{\
background-color: rgb(200, 200, 230);\
border: none; \
}";
QPushButton* btnFloorplan = new QPushButton(UIHelper::getIcon("floorplan"), "", this);
btnFloorplan->setGeometry(16, 16, 32, 32);
btnFloorplan->setCheckable(true);
btnFloorplan->setChecked(true);
btnFloorplan->setStyleSheet(style);
connect(btnFloorplan, &QPushButton::toggled, [btnFloorplan,this] () {
emit onShow3DFloorplan(btnFloorplan->isChecked());
});
QPushButton* btnPerspective = new QPushButton(UIHelper::getIcon("perspective"), "", this);
btnPerspective->setGeometry(16, 16+8+32, 32, 32);
connect(btnPerspective, &QPushButton::clicked, [this] () {
usePerspectiveProjection = !usePerspectiveProjection;
emit update();
});
QPushButton* btnGrid = new QPushButton(UIHelper::getIcon("grid"), "", this);
btnGrid->setCheckable(true);
btnGrid->setChecked(false);
btnGrid->setGeometry(16+16+32, 16, 32, 32);
btnGrid->setStyleSheet(style);
connect(btnGrid, &QPushButton::toggled, [btnGrid, this] () {
emit onShow3DGrid(btnGrid->isChecked());
});
QPushButton* btnNavMesh = new QPushButton(UIHelper::getIcon("mesh"), "", this);
btnNavMesh->setCheckable(true);
btnNavMesh->setChecked(false);
btnNavMesh->setGeometry(16+16+32+16+32, 16, 32, 32);
btnNavMesh->setStyleSheet(style);
connect(btnNavMesh, &QPushButton::toggled, [btnNavMesh, this] () {
emit onShow3DNavMesh(btnNavMesh->isChecked());
});
}
@@ -36,53 +77,13 @@ void MapView3D::initializeGL() {
QOpenGLWidget::initializeGL();
glCullFace(GL_FRONT);
// this should be the default!!
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
//glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
// culling, lighting, depth-test, ...
// additional settings
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);
}
@@ -91,71 +92,13 @@ 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);
*/
glViewport(0, 0, width, height);
}
@@ -175,9 +118,9 @@ void MapView3D::mouseMoveEvent(QMouseEvent* e) {
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 / width() * 2 * viewport.size.x, +dy / height() * 2 * viewport.size.y, 0);
//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 = vec.rot(-rot.x/180*M_PI, -rot.y/180*M_PI, -rot.z/180*M_PI);
vec /= scale;
center += vec;
}
@@ -256,45 +199,44 @@ 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.translate(0,0,-30);
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.translate(center.x, center.y, center.z);
// 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);
if (usePerspectiveProjection) {
float w = width() / 30;
float h = height() / 30;
viewport.size.x = w;
viewport.size.y = h;
P.perspective(45.0f, aspect, 0.01, 100);
} else {
// default size: 50 * 50/aspect meters
float w = 50.0f;
float h = 50.0f * height() / width();
viewport.size.x = w;
viewport.size.y = h;
P.ortho(-w, +w, -h, +h, 0.1f, +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) {
@@ -305,12 +247,12 @@ void MapView3D::draw() {
}
if (showGrid && gridModel) {
gridRenderer->paintGL(gridModel->getGrid());
}
// if (showGrid && gridModel) {
// gridRenderer->paintGL(gridModel->getGrid());
// }
if (showNavMesh && navMeshModel) {
navMeshRenderer->paintGL(navMeshModel->getNavMesh(), this);
navMeshRenderer->render(rs, navMeshModel->getNavMesh(), this);
}
// transparant floorplan parts
@@ -322,7 +264,7 @@ void MapView3D::draw() {
}
}
*/
}

View File

@@ -18,6 +18,8 @@ class MapView3D : public QOpenGLWidget {
Q_OBJECT
bool usePerspectiveProjection = false;
public:
MapView3D(QWidget* parent = 0);
@@ -102,6 +104,12 @@ protected:
void mouseReleaseEvent(QMouseEvent* e);
void wheelEvent(QWheelEvent* e);
signals:
void onShow3DFloorplan(bool show);
void onShow3DGrid(bool show);
void onShow3DNavMesh(bool show);
private:
void draw();

View File

@@ -2,217 +2,52 @@
#include "Shader.h"
#include <QtOpenGL>
//static float cube_vertices[] = {
//1 -1.0000, -1.0000, -1.0000,
//2 -1.0000, 1.0000, -1.0000,
//3 1.0000, 1.0000, -1.0000,
//4 1.0000, -1.0000, -1.0000,
//5 -1.0000, -1.0000, 1.0000,
//6 1.0000, -1.0000, 1.0000,
//7 1.0000, 1.0000, 1.0000,
//8 -1.0000, 1.0000, 1.0000,
//};
//static int cube_vertex_indices[] = {
// 1, 2, 3,
// 3, 4, 1,
// 5, 6, 7,
// 7, 8, 5,
// 1, 4, 6,
// 6, 5, 1,
// 4, 3, 7,
// 7, 6, 4,
// 3, 2, 8,
// 8, 7, 3,
// 2, 1, 5,
// 5, 8, 2,
//};
static float cube_vertices[] = {
-1, -1, -1, -1, +1, -1, +1, +1, -1,
+1, +1, -1, +1, -1, -1, -1, -1, -1,
-1, -1, 0,
+1, -1, 0,
0, +1, 0,
-1, -1, +1, +1, -1, +1, +1, +1, +1,
+1, +1, +1, -1, +1, +1, -1, -1, +1,
// -1.0000, -1.0000, -1.0000, -1.0000, 1.0000, -1.0000, 1.0000, 1.0000, -1.0000,
// 1.0000, 1.0000, -1.0000, 1.0000, -1.0000, -1.0000, -1.0000, -1.0000, -1.0000,
-1, -1, -1, +1, -1, -1, +1, -1, +1,
+1, -1, +1, -1, -1, +1, -1, -1, -1,
// -1.0000, -1.0000, 1.0000, 1.0000, -1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
// 1.0000, 1.0000, 1.0000, -1.0000, 1.0000, 1.0000, -1.0000, -1.0000, 1.0000,
+1, -1, -1, +1, +1, -1, +1, +1, +1,
+1, +1, +1, +1, -1, +1, +1, -1, -1,
// -1.0000, -1.0000, -1.0000, 1.0000, -1.0000, -1.0000, 1.0000, -1.0000, 1.0000,
// 1.0000, -1.0000, 1.0000, -1.0000, -1.0000, 1.0000, -1.0000, -1.0000, -1.0000,
+1, +1, -1, -1, +1, -1, -1, +1, +1,
-1, +1, +1, +1, +1, +1, +1, +1, -1,
// 1.0000, -1.0000, -1.0000, 1.0000, 1.0000, -1.0000, 1.0000, 1.0000, 1.0000,
// 1.0000, 1.0000, 1.0000, 1.0000, -1.0000, 1.0000, 1.0000, -1.0000, -1.0000,
// 1.0000, 1.0000, -1.0000, -1.0000, 1.0000, -1.0000, -1.0000, 1.0000, 1.0000,
// -1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, -1.0000,
// -1.0000, 1.0000, -1.0000, -1.0000, -1.0000, -1.0000, -1.0000, -1.0000, 1.0000,
// -1.0000, -1.0000, 1.0000, -1.0000, 1.0000, 1.0000, -1.0000, 1.0000, -1.0000,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1, -1, +1, -1, +1, +1, -1, +1, -1,
};
//static float cube_normals[] = {
// 0.0000, 0.0000, -1.0000,
// 0.0000, 0.0000, 1.0000,
// 0.0000, -1.0000, 0.0000,
// 1.0000, 0.0000, 0.0000,
// 0.0000, 1.0000, 0.0000,
// -1.0000, 0.0000, 0.0000,
//};
static float cube_normals[] = {
0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000,
0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000,
0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000,
0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000,
0, 0, -1, 0, 0, -1, 0, 0, -1,
0, 0, -1, 0, 0, -1, 0, 0, -1,
0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000,
0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000,
0, 0, +1, 0, 0, +1, 0, 0, +1,
0, 0, +1, 0, 0, +1, 0, 0, +1,
1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000,
1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000, 1.0000, 0.0000, 0.0000,
0, -1, 0, 0, -1, 0, 0, -1, 0,
0, -1, 0, 0, -1, 0, 0, -1, 0,
0.0000, 1.0000, 0.0000,0.0000, 1.0000, 0.0000,0.0000, 1.0000, 0.0000,
0.0000, 1.0000, 0.0000,0.0000, 1.0000, 0.0000,0.0000, 1.0000, 0.0000,
1, 0, 0, 1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0, 1, 0, 0,
0, +1, 0, 0, +1, 0, 0, +1, 0,
0, +1, 0, 0, +1, 0, 0, +1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0,
-1.0000, 0.0000, 0.0000,-1.0000, 0.0000, 0.0000,-1.0000, 0.0000, 0.0000,
-1.0000, 0.0000, 0.0000,-1.0000, 0.0000, 0.0000,-1.0000, 0.0000, 0.0000,
};
//static int cube_normal_indices[] = {
// 1, 1, 1,
// 1, 1, 1,
// 2, 2, 2,
// 2, 2, 2,
// 3, 3, 3,
// 3, 3, 3,
// 4, 4, 4,
// 4, 4, 4,
// 5, 5, 5,
// 5, 5, 5,
// 6, 6, 6,
// 6, 6, 6,
//};
//static float cube_vertices[] = {
// // bottom
// +1, -1, -1,
// +1, -1, +1,
// -1, -1, +1,
// -1, -1, +1,
// -1, -1, -1,
// +1, -1, -1,
// // top
// -1, +1, -1,
// -1, +1, +1,
// +1, +1, +1,
// +1, +1, +1,
// +1, +1, -1,
// -1, +1, -1,
// // left
// -1, -1, -1,
// -1, -1, +1,
// -1, +1, +1,
// -1, +1, +1,
// -1, +1, -1,
// -1, -1, -1,
// // right
// +1, +1, -1,
// +1, +1, +1,
// +1, -1, +1,
// +1, -1, +1,
// +1, -1, -1,
// +1, +1, -1,
// // front
// +1, +1, +1,
// -1, +1, +1,
// -1, -1, +1,
// -1, -1, +1,
// +1, -1, +1,
// +1, +1, +1,
// // rear
// +1, -1, -1,
// -1, -1, -1,
// -1, +1, -1,
// -1, +1, -1,
// +1, +1, -1,
// +1, -1, -1,
//};
//static float cube_normals[] = {
// // bottom
// 0,-1,0,
// 0,-1,0,
// 0,-1,0,
// 0,-1,0,
// 0,-1,0,
// 0,-1,0,
// // top
// 0,+1,0,
// 0,+1,0,
// 0,+1,0,
// 0,+1,0,
// 0,+1,0,
// 0,+1,0,
// // left
// -1,0,0,
// -1,0,0,
// -1,0,0,
// -1,0,0,
// -1,0,0,
// -1,0,0,
// // right
// +1,0,0,
// +1,0,0,
// +1,0,0,
// +1,0,0,
// +1,0,0,
// +1,0,0,
// // front
// 0,0,+1,
// 0,0,+1,
// 0,0,+1,
// 0,0,+1,
// 0,0,+1,
// 0,0,+1,
// // rear
// 0,0,-1,
// 0,0,-1,
// 0,0,-1,
// 0,0,-1,
// 0,0,-1,
// 0,0,-1,
//};
static Shader* shader = nullptr;
//static Shader* shader = nullptr;
Cube::Cube(Point3 pos, float size) : pos(pos), size(size,size,size), rot(0,0,0) {
@@ -228,29 +63,23 @@ void Cube::setColor(float r, float g, float b) {
void Cube::render(const RenderSettings& rs) {
rs.shader->bind();
QMatrix4x4 mat;
mat.translate(pos.x, pos.y, pos.z);
mat.rotate(rot.x, 1, 0, 0);
mat.rotate(rot.y, 0, 1, 0);
mat.rotate(rot.z, 0, 0, 1);
mat.rotate(rot.x, +1, 0, 0);
mat.rotate(rot.y, 0, +1, 0);
mat.rotate(rot.z, 0, 0, +1);
mat.scale(size.x, size.y, size.z);
// mat.scale(0.1, 0.1, 0.1);
rs.shader->setModelMatrix(mat);
// shader->setViewMatrix(V);
// shader->setProjectionMatrix(P);
rs.shader->setColor(color.x, color.y, color.z);
rs.shader->setVertices(cube_vertices);
rs.shader->setNormals(cube_normals);
glDrawArrays(GL_TRIANGLES, 0, 1*3);
//glDrawElements(GL_TRIANGLES, 12, GL_INT, cube_vertex_indices);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
//glDrawElements(GL_TRIANGLES, +12, GL_INT, cube_vertex_indices);
rs.shader->unsetVertices();
rs.shader->unsetNormals();

View File

@@ -0,0 +1,101 @@
#include "Handrail.h"
#include <Indoor/geo/Point3.h>
#include "Shader.h"
Handrail::Handrail(const Point2 from, const Point2 to, float atHeight, float height) :
from(from), to(to), atHeight(atHeight), height(height) {
;
}
void Handrail::render(const RenderSettings& rs) {
rs.shader->bind();
rs.shader->setColor(0.8, 0.8, 0.8);
rs.shader->setModelMatrix(QMatrix4x4());
const float z1 = atHeight;
const float z2 = atHeight + height;
// polygon edges
Point3 p1 = Point3(from.x, from.y, z1);
Point3 p2 = Point3(to.x, to.y, z1);
Point3 p3 = Point3(from.x, from.y, z2);
Point3 p4 = Point3(to.x, to.y, z2);
std::vector<float> vertices;
// top
vertices.insert( vertices.end(), {p3.x, p3.y, p3.z} );
vertices.insert( vertices.end(), {p4.x, p4.y, p4.z} );
// start bar
vertices.insert( vertices.end(), {p1.x, p1.y, p1.z} );
vertices.insert( vertices.end(), {p3.x, p3.y, p3.z} );
// end bar
vertices.insert( vertices.end(), {p2.x, p2.y, p2.z} );
vertices.insert( vertices.end(), {p4.x, p4.y, p4.z} );
// 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;
vertices.insert( vertices.end(), {s.x, s.y, s.z} );
vertices.insert( vertices.end(), {e.x, e.y, e.z} );
}
rs.shader->setVertices(vertices.data());
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
rs.shader->unsetVertices();
rs.shader->release();
/*
TODO_GL
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);
*/
}

View File

@@ -0,0 +1,25 @@
#ifndef HANDRAIL_H
#define HANDRAIL_H
#include "Renderable3D.h"
#include <Indoor/geo/Point2.h>
class Handrail : public Renderable3D {
private:
Point2 from;
Point2 to;
float atHeight;
float height;
public:
Handrail(const Point2 from, const Point2 to, float atHeight, float height);
void render(const RenderSettings& rs) override;
};
#endif // HANDRAIL_H

View File

@@ -0,0 +1,73 @@
#include "Outline.h"
#include <QMatrix4x4>
#include <Indoor/geo/Point3.h>
#include <QOpenGLWidget>
#include "Shader.h"
Outline::Outline() {
}
void Outline::render(const RenderSettings& rs) {
rs.shader->bind();
// identity
QMatrix4x4 mat;
rs.shader->setModelMatrix(mat);
// show both sides
//glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
rs.shader->setColor(color.x, color.y, color.z);
rs.shader->setVertices(vertices.data());
rs.shader->setNormals(normals.data());
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
rs.shader->unsetVertices();
rs.shader->unsetNormals();
rs.shader->release();
}
void Outline::setColor(float r, float g, float b) {
color = Point3(r,g,b);
}
void Outline::clear() {
normals.clear();
vertices.clear();
}
void Outline::add(std::vector<std::vector<Point3>>& triangles) {
for (const std::vector<Point3>& tria : triangles) {
for (size_t i = 2; i < tria.size(); ++i) {
const Point3 p1 = tria[i-2];
const Point3 p2 = tria[i-1];
const Point3 p3 = tria[i-0];
const Point3 n = cross(p2-p1, p3-p1);
if (n.z < 0) {
vertices.push_back(p1.x); vertices.push_back(p1.y); vertices.push_back(p1.z);
vertices.push_back(p3.x); vertices.push_back(p3.y); vertices.push_back(p3.z);
vertices.push_back(p2.x); vertices.push_back(p2.y); vertices.push_back(p2.z);
} else {
vertices.push_back(p1.x); vertices.push_back(p1.y); vertices.push_back(p1.z);
vertices.push_back(p2.x); vertices.push_back(p2.y); vertices.push_back(p2.z);
vertices.push_back(p3.x); vertices.push_back(p3.y); vertices.push_back(p3.z);
}
normals.push_back(0); normals.push_back(0); normals.push_back(1);
normals.push_back(0); normals.push_back(0); normals.push_back(1);
normals.push_back(0); normals.push_back(0); normals.push_back(1);
}
}
}

33
mapview/3D/misc/Outline.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef OUTLINE_H
#define OUTLINE_H
#include "Renderable3D.h"
#include <vector>
#include <Indoor/geo/Point3.h>
class Outline : public Renderable3D {
private:
std::vector<float> vertices;
std::vector<float> normals;
Point3 color;
public:
Outline();
virtual void render(const RenderSettings& rs) override;
void setColor(float r, float g, float b);
void clear();
void add(std::vector<std::vector<Point3>>&);
};
#endif // OUTLINE_H

View File

@@ -6,27 +6,41 @@ Shader::Shader() {
addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, R"(
attribute highp vec3 a_vertex;
attribute highp vec3 a_normal;
attribute lowp vec4 a_color;
uniform highp mat4 M;
uniform highp mat4 V;
uniform highp mat4 P;
varying highp vec3 normal;
varying highp vec3 v_normal;
varying lowp vec4 v_color;
varying lowp vec4 v_vertex;
void main() {
gl_Position = vec4(a_vertex, 1.0);
normal = normalize( V*M*vec4(a_normal, 0.0) );
gl_Position = P * V * M * vec4(a_vertex, 1.0);
v_normal = (V * M * vec4(a_normal, 0.0)).xyz;
v_color = a_color;
v_vertex = V * M * vec4(a_vertex, 1.0);
}
)");
addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, R"(
uniform vec4 color;
varying highp vec3 normal;
uniform bool useNormal;
uniform bool useVertexColor;
varying highp vec3 v_normal;
varying lowp vec4 v_color;
varying lowp vec4 v_vertex;
void main() {
float intensity = dot( normal, normalize(vec3(-1,-1,-3)) );
gl_FragColor.rgb = color.rgb * intensity;
gl_FragColor.a = color.a;
vec3 lightPos = vec3(0,0,0); // camera
//vec3 lightVec = normalize(vec3(0,0,1));
vec3 lightVec = normalize(lightPos - v_vertex.xyz);
float intensity = useNormal ? 0.3 + 0.7 * dot( normalize(v_normal), lightVec ) : 1.0; // light at camera pos
vec4 col = useVertexColor ? v_color : color;
gl_FragColor.rgb = col.rgb * intensity;
gl_FragColor.a = col.a;
}
)");
//bindAttributeLocation("vertices", 0);
if (!link()) {
std::cout << log().toStdString() << std::endl;
throw std::runtime_error("shader link error");
@@ -36,15 +50,25 @@ Shader::Shader() {
void Shader::setModelMatrix(const QMatrix4x4& m) {
//setUniformValue(getUniform("M"), m);
setUniformValue(getUniform("M"), m);
}
void Shader::setViewMatrix(const QMatrix4x4& m) {
//setUniformValue(getUniform("V"), m);
setUniformValue(getUniform("V"), m);
}
void Shader::setProjectionMatrix(const QMatrix4x4& m) {
//setUniformValue(getUniform("P"), m);
setUniformValue(getUniform("P"), m);
}
void Shader::setUseNormals(bool use) {
int loc = getUniform("useNormal");
setUniformValue(loc, use);
}
void Shader::setUseVertexColor(bool use) {
int loc = getUniform("useVertexColor");
setUniformValue(loc, use);
}
int Shader::getUniform(const char* name) {
@@ -52,7 +76,6 @@ int Shader::getUniform(const char* name) {
if (loc == -1) {throw std::runtime_error("error");}
return loc;
}
int Shader::getAttribute(const char* name) {
int loc = attributeLocation(name);
if (loc == -1) {throw std::runtime_error("error");}
@@ -78,11 +101,25 @@ void Shader::unsetVertices() {
}
void Shader::setNormals(const float* values) {
setUseNormals(true);
const int loc = getAttribute("a_normal");
enableAttributeArray(loc);
setAttributeArray(loc, GL_FLOAT, values, 3);
}
void Shader::unsetNormals() {
setUseNormals(false);
const int loc = getAttribute("a_normal");
disableAttributeArray(loc);
}
void Shader::setVertexColor(const float* values) {
setUseVertexColor(true);
const int loc = getAttribute("a_color");
enableAttributeArray(loc);
setAttributeArray(loc, GL_FLOAT, values, 4); // RGBA!!!
}
void Shader::unsetVertexColor() {
setUseVertexColor(false);
const int loc = getAttribute("a_color");
disableAttributeArray(loc);
}

View File

@@ -21,9 +21,14 @@ public:
void setVertices(const float*);
void unsetVertices();
void setUseNormals(bool use);
void setNormals(const float*);
void unsetNormals();
void setVertexColor(const float*);
void unsetVertexColor();
void setUseVertexColor(bool use);
int getUniform(const char*);
int getAttribute(const char*);

View File

@@ -9,12 +9,10 @@
#include <Indoor/navMesh/NavMeshType.h>
#include <QPainter>
#include <QGLWidget>
#include <QOpenGLWidget>
//enum class GridRendererColorMode {
// SHOW_NODE_TYPE,
// SHOW_NODE_IMPORTANCE,
//};
#include "../3D/misc/Renderable3D.h"
#include "../3D/misc/Shader.h"
class NavMeshRenderer {
@@ -53,10 +51,88 @@ public:
/** render the given grid using GL commands */
void paintGL(NM::NavMesh<NM::NavMeshTriangle>* navMesh, QGLWidget* dst) {
void render(const RenderSettings& rs, NM::NavMesh<NM::NavMeshTriangle>* navMesh, QOpenGLWidget* dst) {
if (navMesh == nullptr) {return;}
rs.shader->bind();
rs.shader->setModelMatrix(QMatrix4x4());
std::vector<float> vertices;
std::vector<float> colors;
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;
}
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(vertices.data());
rs.shader->setVertexColor(colors.data());
glDrawArrays(GL_TRIANGLES, 0, vertices.size()/3);
rs.shader->unsetVertices();
rs.shader->unsetVertexColor();
vertices.clear();
colors.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;
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(vertices.data());
rs.shader->setVertexColor(colors.data());
glDrawArrays(GL_LINES, 0, vertices.size()/3);
rs.shader->unsetVertices();
rs.shader->unsetVertexColor();
rs.shader->release();
/*
TODO_GL
@@ -68,21 +144,7 @@ public:
glBegin(GL_TRIANGLES);
for (const NM::NavMeshTriangle* tria : *navMesh) {
// // 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;
// }
// }
switch (tria->getType()) {
case (int) NM::NavMeshType::FLOOR_INDOOR: glColor3f(0.8, 0.8, 0.8); break;