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/3D/elements/Walls.h
2016-09-28 12:16:45 +02:00

164 lines
3.9 KiB
C++

#ifndef WALLS_H
#define WALLS_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "../gl/GLHelper.h"
#include "../gl/GLTriangles.h"
#include "../gl/GLLines.h"
#include "../Renderable.h"
#include "../gl/Shader.h"
class Walls : public Renderable {
private:
Floorplan::Floor* floor;
GLTriangles<VertNormTexTan> triangles;
GLLines outlines;
bool outlineOnly = false;
bool transparent = false;
public:
/** ctor */
Walls(Floorplan::Floor* floor) : floor(floor) {
setOutlineOnly(false);
}
void initGL() override {
build();
triangles.build();
triangles.setDiffuse(":/res/gl/tex/wall3.jpg");
triangles.setNormalMap(":/res/gl/tex/wall3_normal.jpg");
outlines.build();
}
/** render the floor */
void _render(const RenderParams& params) override {
// skip me?
if (params.clipAboveHeight_m < floor->atHeight) {return;}
if (transparent) {
program.setUniformValue("alpha", 0.5f);
glEnable(GL_BLEND);
} else {
program.setUniformValue("alpha", 1.0f);
glDisable(GL_BLEND);
}
if (outlineOnly) {
glLineWidth(1);
outlines.render(&program);
} else {
triangles.render(&program);
}
glDisable(GL_BLEND);
}
/** render only the outline? */
void setOutlineOnly(const bool outline) override {
this->outlineOnly = outline;
if (outlineOnly) {
loadShader(":/res/gl/vertex1.glsl", ":/res/gl/fragmentLine.glsl");
program.setUniformValue("color", QVector4D(0.9, 0.9, 0.9, 1.0));
} else {
loadShader(":/res/gl/vertex1.glsl", ":/res/gl/fragmentTex.glsl");
program.setUniformValue("texDiffuse", 0);
program.setUniformValue("texNormalMap", 1);
}
}
void setTransparent(const bool transparent) override {
this->transparent = transparent;
}
private:
void build() {
for (Floorplan::FloorObstacle* obstacle : floor->obstacles) {
if (dynamic_cast<Floorplan::FloorObstacleLine*>(obstacle)) {
Floorplan::FloorObstacleLine* line = dynamic_cast<Floorplan::FloorObstacleLine*>(obstacle);
if (line->type != Floorplan::ObstacleType::WALL) {continue;}
addFace(line->from, line->to, floor->getStartingZ(), floor->getEndingZ());
} else if (dynamic_cast<Floorplan::FloorObstacleDoor*>(obstacle)) {
Floorplan::FloorObstacleDoor* door = dynamic_cast<Floorplan::FloorObstacleDoor*>(obstacle);
addFace(door->from, door->to, floor->getStartingZ() + door->height, floor->getEndingZ());
}
}
}
void addFace(const Point2 from, const Point2 to, const float h1, const float h2) {
const QVector3D vert1(from.x, h1, from.y);
const QVector3D vert2(to.x, h1, to.y);
const QVector3D vert3(to.x, h2, to.y);
const QVector3D vert4(from.x, h2, from.y);
const QVector3D n1 = GLHelper::getNormal(vert1, vert2, vert3);
const QVector3D n2 = -n1;
QVector3D tan = (vert1-vert2).normalized();
tan = GLHelper::isCCW(vert1, vert2, vert3) ? (tan) : (-tan);
const float l = from.getDistance(to);
const float h = h2-h1;
const float o = std::min(from.length(), to.length());
const QVector2D tex1(o+0, h); // start texturing at the ceiling so above-door-sections and walls have the same textre
const QVector2D tex2(o+l, h);
const QVector2D tex3(o+l, 0);
const QVector2D tex4(o+0, 0);
const float s = 0.65;
{
const VertNormTexTan vnt1(vert1, n1, tex1*s, tan);
const VertNormTexTan vnt2(vert2, n1, tex2*s, tan);
const VertNormTexTan vnt3(vert3, n1, tex3*s, tan);
const VertNormTexTan vnt4(vert4, n1, tex4*s, tan);
triangles.addQuadCCW(vnt1, vnt2, vnt3, vnt4);
} {
const VertNormTexTan vnt1(vert1, n2, tex1*s, -tan);
const VertNormTexTan vnt2(vert2, n2, tex2*s, -tan);
const VertNormTexTan vnt3(vert3, n2, tex3*s, -tan);
const VertNormTexTan vnt4(vert4, n2, tex4*s, -tan);
triangles.addQuadCW(vnt1, vnt2, vnt3, vnt4);
}
outlines.addLine(vert1, vert2);
outlines.addLine(vert2, vert3);
outlines.addLine(vert3, vert4);
outlines.addLine(vert4, vert1);
}
//private:
//
// QVector2D tex(const QVector3D vert) {
// return QVector2D(vert.x(), vert.y());
// }
};
#endif // WALLS_H