130 lines
2.7 KiB
C++
130 lines
2.7 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"
|
|
|
|
|
|
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 paintGL() override {
|
|
|
|
rebuildIfNeeded();
|
|
|
|
for (auto& it : elements) {
|
|
|
|
//Polygon& pol = it.second->pol;
|
|
std::vector<std::vector<Point3>>& trias = it.second->trias;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|