added "outdoor" support to floorplan and grid-nodes

This commit is contained in:
2017-03-12 16:47:29 +01:00
parent e88f0b85a6
commit 7ec5fef697
5 changed files with 55 additions and 27 deletions

View File

@@ -52,6 +52,8 @@ public:
static const uint8_t TYPE_ELEVATOR = 2;
static const uint8_t TYPE_DOOR = 3;
static const uint8_t TYPE_OUTDOOR = 100;
public:
/** ctor */

View File

@@ -114,21 +114,38 @@ public:
return bb;
}
bool isPartOfFloorOutline(const int x_cm, const int y_cm, const Floorplan::FloorOutline& outline) {
enum class PartOfOutline {
NO,
INDOOR,
OUTDOOR,
};
bool add = false;
/** get the part of outline the given location belongs to. currently: none, indoor, outdoor */
PartOfOutline isPartOfFloorOutline(const int x_cm, const int y_cm, const Floorplan::FloorOutline& outline) {
// assume the point is not part of the outline
PartOfOutline res = PartOfOutline::NO;
// process every outline polygon
for (Floorplan::FloorOutlinePolygon* poly : outline) {
if (poly->method != Floorplan::OutlineMethod::ADD) {continue;}
HelperPoly pol(*poly);
if (pol.contains(Point2(x_cm, y_cm))) {add = true;}
if (pol.contains(Point2(x_cm, y_cm))) {
// belongs to a "remove" polygon? -> directly ignore this location!
if (poly->method == Floorplan::OutlineMethod::REMOVE) {
return PartOfOutline::NO;
}
// belongs to a "add" polygon? -> remember until all polygons were checked
// [might still belong to a "remove" polygon]
res = poly->outdoor ? PartOfOutline::OUTDOOR : PartOfOutline::INDOOR;
}
}
if (!add) {return false;}
for (Floorplan::FloorOutlinePolygon* poly : outline) {
if (poly->method != Floorplan::OutlineMethod::REMOVE) {continue;}
HelperPoly pol(*poly);
if (pol.contains(Point2(x_cm, y_cm))) {add = false;} // TODO
}
return add;
// done
return res;
}
@@ -155,7 +172,8 @@ public:
for (int y_cm = y1; y_cm < y2; y_cm += helper.gridSize()) {
// does the outline-polygon contain this position?
if (!isPartOfFloorOutline(x_cm, y_cm, floor->outline)) {continue;}
const PartOfOutline part = isPartOfFloorOutline(x_cm, y_cm, floor->outline);
if (part == PartOfOutline::NO) {continue;}
// check intersection with the floorplan
GridNodeBBox bbox(GridPoint(x_cm, y_cm, z_cm), helper.gridSize());
@@ -164,12 +182,13 @@ public:
bbox.grow(0.42345);
if (intersects(bbox, floor)) {continue;}
// add to the grid
// add to the grid [once]
T t(x_cm, y_cm, z_cm);
t.setType(getType(bbox, floor));
if (grid.hasNodeFor(t)) {continue;}
updateType(t, part, bbox, floor);
grid.add(t);
// debug
++numNodes;
@@ -487,23 +506,30 @@ private:
}
/** does the bbox intersect with any of the floor's walls? */
static inline int getType(const GridNodeBBox& bbox, const Floorplan::Floor* floor) {
/** adjust the given gridNode's type if needed [e.g. from "floor" to "door"] */
static inline void updateType(T& t, const PartOfOutline part, const GridNodeBBox& bbox, const Floorplan::Floor* floor) {
// process each obstacle
// first, assume the type of the outline polygon
switch (part) {
case PartOfOutline::OUTDOOR: t.setType(GridNode::TYPE_OUTDOOR); break;
case PartOfOutline::INDOOR: t.setType(GridNode::TYPE_FLOOR); break;
default: throw Exception("should not happen");
}
// hereafter, process each obstacle and mark doors
for (Floorplan::FloorObstacle* fo : floor->obstacles) {
if (dynamic_cast<Floorplan::FloorObstacleDoor*>(fo)) {
const Floorplan::FloorObstacleDoor* door = (Floorplan::FloorObstacleDoor*) fo;
const Line2 l2(door->from*100, door->to*100);
if (bbox.intersects(l2)) {return GridNode::TYPE_DOOR;}
if (bbox.intersects(l2)) {
t.setType(GridNode::TYPE_DOOR);
return; // done
}
}
}
return GridNode::TYPE_FLOOR;
}