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/MV3DElementFloorOutline.h
root e5e19779d5 worked on android port
opengl1 -> es
2018-01-31 17:15:11 +01:00

182 lines
3.9 KiB
C++

#ifndef MV3DELEMENTFLOOROUTLINE_H
#define MV3DELEMENTFLOOROUTLINE_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "misc/Cube.h"
#include "MV3DElement.h"
#include "../../lib/gpc/gpc.h"
#include "misc/Polygon.h"
#include "misc/Shader.h"
class MV3DElementFloorOutline : public MV3DElement {
Floorplan::Floor* f;
Floorplan::FloorOutline* out;
struct ToRender {
Point2 cacheSum;
Polygon* pol = nullptr;
std::vector<std::vector<Point3>> trias;
};
std::unordered_map<std::string, ToRender*> elements;
public:
/** ctor */
MV3DElementFloorOutline(Floorplan::Floor* f, Floorplan::FloorOutline* out) : f(f), out(out) {
;
}
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();
}
void rebuildIfNeeded() {
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"]);
}
template <typename Filter> void rebuildIfNeeded(Filter include, ToRender* dst) {
const std::vector<Floorplan::FloorOutlinePolygon*>& polys = *out;
// get number of points for rebuild-check
Point2 cacheSum(0,0);
for (Floorplan::FloorOutlinePolygon* poly : polys) {
if (!include(poly)) {continue;}
for (Point2 pt : poly->poly.points) {
cacheSum += pt;
}
}
// already up to date?
if (cacheSum == dst->cacheSum) {return;}
dst->cacheSum = cacheSum;
// rebuild
std::vector<gpc_polygon> add;
std::vector<gpc_polygon> rem;
if (dst->pol) {delete dst->pol;}
dst->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;
default: throw 1;
}
}
dst->trias = dst->pol->get(f->atHeight);
}
bool isTransparent() const override {
return false;
}
};
#endif // MV3DELEMENTFLOOROUTLINE_H