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
YASMIN/ui/map/FloorRenderer.h
kazu 075d8bb633 a lot!!! of changes
added main menu
added debug display
many debug widgets for plotting live data
worked on android live sensors
added offline-data sensor feeding
some dummy data sensors
worked on the map display
added ui debug for grid-points, particles and weights
added a cool dude to display the estimation
added real filtering based on the Indoor components
c++11 fixes for android compilation
online and offline filtering support
new resampling technique for testing
map loading via dialog
2016-09-16 19:30:04 +02:00

223 lines
6.4 KiB
C++

#ifndef FLOORRENDERER_H
#define FLOORRENDERER_H
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <Indoor/floorplan/v2/Floorplan.h>
#include "GL.h"
class FloorRenderer : protected QOpenGLFunctions {
private:
Floorplan::Floor* floor;
QOpenGLBuffer arrayBuf;
QOpenGLBuffer indexBuf;
QOpenGLTexture* texture = nullptr;
std::vector<VertNormTex> vertices;
std::vector<GLushort> indices;
public:
/** ctor */
FloorRenderer(Floorplan::Floor* floor) : floor(floor), arrayBuf(QOpenGLBuffer::VertexBuffer), indexBuf(QOpenGLBuffer::IndexBuffer) {
;
}
/** dctor */
~FloorRenderer() {
arrayBuf.destroy();
indexBuf.destroy();
delete texture;
}
/** render the floor */
void render(QOpenGLShaderProgram *program) {
// Tell OpenGL which VBOs to use
arrayBuf.bind();
indexBuf.bind();
texture->bind();
// vertices
int vertLoc = program->attributeLocation("a_position");
program->enableAttributeArray(vertLoc);
program->setAttributeBuffer(vertLoc, GL_FLOAT, vertices[0].getVertOffset(), 3, sizeof(vertices[0]));
// Tell OpenGL programmable pipeline how to locate vertex texture coordinate data
int normLoc = program->attributeLocation("a_normal");
program->enableAttributeArray(normLoc);
program->setAttributeBuffer(normLoc, GL_FLOAT, vertices[0].getNormOffset(), 3, sizeof(vertices[0]));
int texcoordLocation = program->attributeLocation("a_texcoord");
program->enableAttributeArray(texcoordLocation);
program->setAttributeBuffer(texcoordLocation, GL_FLOAT, vertices[0].getTexOffset(), 2, sizeof(vertices[0]));
// texture
program->setUniformValue("texture", 0);
// Draw cube geometry using indices from VBO 1
glDrawElements(GL_QUADS, indices.size(), GL_UNSIGNED_SHORT, 0);
}
void initGL() {
initializeOpenGLFunctions();
build();
}
private:
void build() {
QImage img(":/res/gl/tex/wall1.jpg");
texture = new QOpenGLTexture(img);
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
texture->setWrapMode(QOpenGLTexture::Repeat);
// build array of vertices and indices
for (Floorplan::FloorObstacle* obstacle : floor->obstacles) {
add(floor, obstacle, vertices, indices);
}
// Transfer vertex data to VBO 0
arrayBuf.create();
arrayBuf.bind();
arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(vertices[0]));
// Transfer index data to VBO 1
indexBuf.create();
indexBuf.bind();
indexBuf.allocate(indices.data(), indices.size() * sizeof(indices[0]));
}
void add(Floorplan::Floor* floor, Floorplan::FloorObstacle* obstacle, std::vector<VertNormTex>& vertices, std::vector<GLushort>& indices) {
if (dynamic_cast<Floorplan::FloorObstacleLine*>(obstacle)) {
Floorplan::FloorObstacleLine* line = dynamic_cast<Floorplan::FloorObstacleLine*>(obstacle);
if (line->type != Floorplan::ObstacleType::WALL) {return;}
// QVector3D p1(line->from.x, floor->getStartingZ(), line->from.y);
// QVector3D p2(line->to.x, floor->getStartingZ(), line->to.y);
// QVector3D p3(line->to.x, floor->getEndingZ(), line->to.y);
// QVector3D p4(line->from.x, floor->getEndingZ(), line->from.y);
// addFace(p1,p2,p3,p4, vertices, indices);
addFace(line->from, line->to, floor->getStartingZ(), floor->getEndingZ(), vertices, indices);
addFace(line->to, line->from, floor->getStartingZ(), floor->getEndingZ(), vertices, indices);
}
}
void addFace(const Point2 from, const Point2 to, const float h1, const float h2, std::vector<VertNormTex>& vertices, std::vector<GLushort>& indices) {
// unit-face with unit normal (facing the camera)
QVector3D p1(-0.5, -0.0, 0);
QVector3D p2(+0.5, -0.0, 0);
QVector3D p3(+0.5, +1.0, 0);
QVector3D p4(-0.5, +1.0, 0);
QVector3D norm(0, 0, 1);
// how to scale the unit-face to match the wall
const float h = h2-h1;
const float s = from.getDistance(to);
QMatrix4x4 scale; scale.scale(s, h, 1);
// how to rotate the unit-face to match the wall
const float angle = std::atan2(to.y - from.y, to.x - from.x);
const float deg = angle * 180 / M_PI;
QMatrix4x4 rot; rot.rotate(deg, QVector3D(0,1,0));
// how to translate the unit-face to match the wall
const Point2 center = (from + to) / 2;
QMatrix4x4 move; move.translate(center.x, h1, center.y);
// final matrix
QMatrix4x4 mat = move * rot * scale;
// texture coordinates (scale only)
const QVector2D tex1 = (scale * p1).toVector2D() / 5;
const QVector2D tex2 = (scale * p2).toVector2D() / 5;
const QVector2D tex3 = (scale * p3).toVector2D() / 5;
const QVector2D tex4 = (scale * p4).toVector2D() / 5;
// modify vertices
p1 = mat * p1;
p2 = mat * p2;
p3 = mat * p3;
p4 = mat * p4;
norm = (rot * norm).normalized();
const int start = vertices.size();
vertices.push_back(VertNormTex(p1, norm, tex1));
vertices.push_back(VertNormTex(p2, norm, tex2));
vertices.push_back(VertNormTex(p3, norm, tex3));
vertices.push_back(VertNormTex(p4, norm, tex4));
indices.push_back(start+0);
indices.push_back(start+1);
indices.push_back(start+2);
indices.push_back(start+3);
}
// void addFace(QVector3D p1, QVector3D p2, QVector3D p3, QVector3D p4, std::vector<VertNorm>& vertices, std::vector<GLushort>& indices) {
// const float s = 50;
// // ensure camera facing (for culling)
// if (p1.x() != p2.x()) {
// if (p1.x() > p2.x()) {std::swap(p1, p2), std::swap(p3, p4);}
// } else {
// if (p1.z() > p2.z()) {std::swap(p1, p2), std::swap(p3, p4);}
// }
// // corresponding normal vector
// QVector3D norm = QVector3D::crossProduct((p2-p1), (p3-p1)).normalized();
// // orient towards the viewport
// const QVector3D view(-99,-99,-99);
// if ((view-norm).length() > (view+norm).length()) {norm = -norm;}
// const int start = vertices.size();
// indices.push_back(start+0);
// indices.push_back(start+1);
// indices.push_back(start+2);
// indices.push_back(start+3);
// vertices.push_back(VertNorm(p1/s, norm));
// vertices.push_back(VertNorm(p2/s, norm));
// vertices.push_back(VertNorm(p3/s, norm));
// vertices.push_back(VertNorm(p4/s, norm));
// // and the other side (clockwise, negated normal)
// indices.push_back(start+0);
// indices.push_back(start+3);
// indices.push_back(start+2);
// indices.push_back(start+1);
// vertices.push_back(VertNorm(p1/s, -norm));
// vertices.push_back(VertNorm(p2/s, -norm));
// vertices.push_back(VertNorm(p3/s, -norm));
// vertices.push_back(VertNorm(p4/s, -norm));
// }
};
#endif // FLOORRENDERER_H