started working on walling, dooring and windowing

refactoring
This commit is contained in:
k-a-z-u
2018-07-25 16:21:47 +02:00
parent f7e4323d58
commit 0d22d91470
9 changed files with 368 additions and 48 deletions

View File

@@ -36,7 +36,7 @@ namespace Floorplan3D {
bool exportObjects = true; bool exportObjects = true;
bool exportPillars = true; bool exportPillars = true;
bool exportWallTops = false; bool exportWallTops = false;
bool center = true; bool center = false;
//Walls* walls = new WallsViaCubes(); //Walls* walls = new WallsViaCubes();
//Walls* walls = new WallsViaCuttedQuads(); //Walls* walls = new WallsViaCuttedQuads();
@@ -92,6 +92,11 @@ namespace Floorplan3D {
// process each obstacle within the floor // process each obstacle within the floor
if (f->obstacles.enabled) { if (f->obstacles.enabled) {
if (1 == 1) {
const std::vector<Obstacle3D> tmp = getLines(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
if (1 == 1) { if (1 == 1) {
const std::vector<Obstacle3D> tmp = getWalls(f); const std::vector<Obstacle3D> tmp = getWalls(f);
res.insert(res.end(), tmp.begin(), tmp.end()); res.insert(res.end(), tmp.begin(), tmp.end());
@@ -140,6 +145,20 @@ namespace Floorplan3D {
WallsViaCuttedQuads walls; WallsViaCuttedQuads walls;
for (const Floorplan::FloorObstacle* obs : f->obstacles) {
const Floorplan::FloorObstacleWall* wall = dynamic_cast<const Floorplan::FloorObstacleWall*>(obs);
if (wall) {walls.add(f, wall);}
}
return walls.get();
}
/** get all old walls (lines) */
std::vector<Obstacle3D> getLines(const Floorplan::Floor* f) {
WallsViaCubes walls;
for (const Floorplan::FloorObstacle* obs : f->obstacles) { for (const Floorplan::FloorObstacle* obs : f->obstacles) {
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs); const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs);
if (line) {walls.add(f, line, nullptr);} if (line) {walls.add(f, line, nullptr);}

69
floorplan/3D/Lines.h Normal file
View File

@@ -0,0 +1,69 @@
#ifndef FLOORPLAN_3D_LINES_H
#define FLOORPLAN_3D_LINES_H
#include "Walls.h"
#include "misc.h"
#include "primitives/Cube.h"
namespace Floorplan3D {
/**
* simply use one 3D cube per wall
* if walls intersect in the 2D view, cubes will also intersect
*/
class LinesViaCubes : public Walls {
Cube::Part cubeParts = (Cube::Part) 63; // leftright,topbottom,rearfront
std::vector<Obstacle3D> vec;
public:
void clear() override {
vec.clear();
}
void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol, const Floorplan::FloorObstacleDoor* aboveDoor) override {
FloorPos fpos(f);
const float thickness_m = fol->thickness_m;
const Point2 from = (!aboveDoor) ? (fol->from) : (aboveDoor->from);
const Point2 to = (!aboveDoor) ? (fol->to) : (aboveDoor->to);
const Point2 cen2 = (from+to)/2;
const float rad = std::atan2(to.y - from.y, to.x - from.x);
const float deg = rad * 180 / M_PI;
// cube's destination center
const float _height = (fol->height_m > 0) ? (fol->height_m) : (fpos.height); // use either floor's height or user height
const double height = (!aboveDoor) ? (_height) : (fpos.height - aboveDoor->height);
const double cenZ = (!aboveDoor) ? (fpos.z1 + height/2) : (fpos.z1 + aboveDoor->height + height/2);// (fpos.z2 - (fpos.height - aboveDoor->height) / 2);
const Point3 pos(cen2.x, cen2.y, cenZ);
// div by 2.01 to prevent overlapps and z-fighting
const float sx = from.getDistance(to) / 2;
const float sy = thickness_m / 2;
const float sz = height / 2.01f; // prevent overlaps
const Point3 size(sx, sy, sz);
const Point3 rot(0,0,deg);
// build
Cube cube(pos, size, rot, cubeParts);
// done
Obstacle3D res(getType(fol), fol->material);
res.triangles = cube.getTriangles();
vec.push_back(res);
}
const std::vector<Obstacle3D>& get() override {
return vec;
}
};
}
#endif // FLOORPLAN_3D_LINES_H

View File

@@ -5,7 +5,7 @@
#include "../../geo/Polygon2.h" #include "../../geo/Polygon2.h"
#include "../../geo/GPCPolygon2.h" #include "../../geo/GPCPolygon2.h"
#include "Walls.h" //#include "Walls.h"
#include "misc.h" #include "misc.h"
#include <functional> #include <functional>
@@ -17,7 +17,7 @@ namespace Floorplan3D {
* interpret walls als quads (polygons) * interpret walls als quads (polygons)
* intersect them with each other to prevent overlaps * intersect them with each other to prevent overlaps
*/ */
class WallsViaCuttedQuads : public Walls { class WallsViaCuttedQuads {
private: private:
@@ -27,13 +27,13 @@ namespace Floorplan3D {
bool error = false; bool error = false;
/** original line from floorplan */ /** original line from floorplan */
const Floorplan::FloorObstacleLine* line; const Floorplan::FloorObstacleWall* line;
/** outlines after applying thickness */ /** outlines after applying thickness */
Line2 l1; Line2 l1;
Line2 l2; Line2 l2;
Wall(const Floorplan::FloorObstacleLine* line) : line(line) { Wall(const Floorplan::FloorObstacleWall* line) : line(line) {
const Point2 from = line->from; const Point2 from = line->from;
const Point2 to = line->to; const Point2 to = line->to;
@@ -137,18 +137,17 @@ namespace Floorplan3D {
public: public:
void clear() override { void clear() {
walls.clear(); walls.clear();
} }
void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol, const Floorplan::FloorObstacleDoor* aboveDoor) override { void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleWall* fow) {
if (fol->type != Floorplan::ObstacleType::WALL) {return;} if (fow->type != Floorplan::ObstacleType::WALL) {return;}
if (aboveDoor) {return;}
this->floor = f; this->floor = f;
walls.push_back(Wall(fol)); walls.push_back(Wall(fow));
} }
virtual const std::vector<Obstacle3D>& get() override { virtual const std::vector<Obstacle3D>& get() {
std::vector<Wall> tmp = walls; std::vector<Wall> tmp = walls;
tmp = cutConnected(tmp); tmp = cutConnected(tmp);
tmp = cutProtruding(tmp); tmp = cutProtruding(tmp);
@@ -226,6 +225,9 @@ namespace Floorplan3D {
auto unFlattenFront = [o,t,a] (const Point3 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;}; auto unFlattenFront = [o,t,a] (const Point3 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;};
auto unFlattenBack = [o,t,a] (const Point3 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;}; auto unFlattenBack = [o,t,a] (const Point3 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;};
auto unFlattenFront2 = [o,t,a] (const Point2 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;};
auto unFlattenBack2 = [o,t,a] (const Point2 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;};
const Point2 fp1 = flatten(p1); const Point2 fp1 = flatten(p1);
const Point2 fp2 = flatten(p2); const Point2 fp2 = flatten(p2);
const Point2 fp3 = flatten(p3); const Point2 fp3 = flatten(p3);
@@ -248,7 +250,20 @@ namespace Floorplan3D {
GPCPolygon2 gpBack; GPCPolygon2 gpBack;
gpBack.add(back); gpBack.add(back);
for (const Floorplan::FloorObstacleWallDoor* door : wall.line->doors) { // sort doors by their position within the wall (first comes first)
std::vector<Floorplan::FloorObstacleWallDoor*> doors = wall.line->doors;
auto compDoors = [] (const Floorplan::FloorObstacleWallDoor* d1, Floorplan::FloorObstacleWallDoor* d2) {
return d1->atLinePos < d2->atLinePos;
};
std::sort(doors.begin(), doors.end(), compDoors);
TriangleStrip strip;
strip.add(p1);
strip.add(p4);
for (const Floorplan::FloorObstacleWallDoor* door : doors) {
Polygon2 pDoor; Polygon2 pDoor;
const Point2 pds = door->getStart(wall.line); const Point2 pds = door->getStart(wall.line);
@@ -270,8 +285,41 @@ namespace Floorplan3D {
gpFront.remove(pDoor); gpFront.remove(pDoor);
gpBack.remove(pDoor); gpBack.remove(pDoor);
strip.add(unFlattenFront2(pDoor[0]));
strip.add(unFlattenBack2(pDoor[0]));
strip.add(unFlattenFront2(pDoor[3]));
strip.add(unFlattenBack2(pDoor[3]));
strip.add(unFlattenFront2(pDoor[2]));
strip.add(unFlattenBack2(pDoor[2]));
strip.add(unFlattenFront2(pDoor[1]));
strip.add(unFlattenBack2(pDoor[1]));
} }
strip.add(p2);
strip.add(p3);
strip.add(p2u);
strip.add(p3u);
strip.add(p1u);
strip.add(p4u);
strip.add(p1);
strip.add(p4);
for (Triangle3 t : strip.toTriangles()) {
t.reverse();
obs.triangles.push_back(t);
}
// std::vector<Point3> ptsToConnect3;
// for (const Point2 p2 : ptsToConnect) {
// const Point3 p3 = unf
// }
// Frontseite triangulieren
std::vector<Triangle3> triasFront = gpFront.getTriangles(); std::vector<Triangle3> triasFront = gpFront.getTriangles();
for (Triangle3 tria : triasFront) { for (Triangle3 tria : triasFront) {
@@ -280,6 +328,7 @@ namespace Floorplan3D {
obs.triangles.push_back(tria); obs.triangles.push_back(tria);
} }
// Rückseite triangulieren
std::vector<Triangle3> triasBack = gpBack.getTriangles(); std::vector<Triangle3> triasBack = gpBack.getTriangles();
for (Triangle3 tria : triasBack) { for (Triangle3 tria : triasBack) {

View File

@@ -23,6 +23,15 @@ namespace Floorplan3D {
} }
} }
static Obstacle3D::Type getType(const Floorplan::FloorObstacleWall* l) {
switch (l->type) {
case Floorplan::ObstacleType::WALL: return Obstacle3D::Type::WALL;
case Floorplan::ObstacleType::WINDOW: return Obstacle3D::Type::WINDOW;
case Floorplan::ObstacleType::HANDRAIL: return Obstacle3D::Type::HANDRAIL;
default: return Obstacle3D::Type::UNKNOWN;
}
}
static Obstacle3D::Type getType(const Floorplan::FloorObstacleCircle* c) { static Obstacle3D::Type getType(const Floorplan::FloorObstacleCircle* c) {
(void) c; (void) c;
return Obstacle3D::Type::WALL; return Obstacle3D::Type::WALL;

View File

@@ -157,6 +157,12 @@ namespace Floorplan {
_END, _END,
}; };
/** available window types */
enum class WindowType {
UNKNOWN,
_END,
};
/** all supported material types */ /** all supported material types */
enum class Material { enum class Material {
UNKNOWN, UNKNOWN,
@@ -193,6 +199,7 @@ namespace Floorplan {
struct Elevator; struct Elevator;
struct GroundTruthPoint; struct GroundTruthPoint;
struct FloorObstacleWallDoor; struct FloorObstacleWallDoor;
struct FloorObstacleWallWindow;
struct FloorOutline : public std::vector<FloorOutlinePolygon*> { struct FloorOutline : public std::vector<FloorOutlinePolygon*> {
bool enabled = true; bool enabled = true;
@@ -351,7 +358,6 @@ namespace Floorplan {
Point2 to; Point2 to;
float thickness_m; float thickness_m;
float height_m = 0; // 0 = floor's height float height_m = 0; // 0 = floor's height
std::vector<FloorObstacleWallDoor*> doors;
FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;} FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;}
FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;} FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;}
}; };
@@ -378,7 +384,21 @@ namespace Floorplan {
float getSize() const {return (to-from).length();} float getSize() const {return (to-from).length();}
}; };
/** door obstacle */
/** wall obstacle */
struct FloorObstacleWall: public FloorObstacle {
ObstacleType type;
Point2 from;
Point2 to;
float thickness_m;
float height_m = 0; // 0 = floor's height
std::vector<FloorObstacleWallDoor*> doors;
std::vector<FloorObstacleWallWindow*> windows;
FloorObstacleWall(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;}
FloorObstacleWall(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;}
};
/** wall->door obstacle */
struct FloorObstacleWallDoor : public FloorObstacle { struct FloorObstacleWallDoor : public FloorObstacle {
DoorType type; DoorType type;
float atLinePos; float atLinePos;
@@ -386,17 +406,40 @@ namespace Floorplan {
float height; float height;
bool leftRight = false; bool leftRight = false;
bool inOut = false; bool inOut = false;
FloorObstacleWallDoor(const DoorType type, const Material material, const float atLinePos, const float width, const float height) : FloorObstacle(material), type(type), atLinePos(atLinePos), width(width), height(height) {;} FloorObstacleWallDoor(const DoorType type, const Material material, const float atLinePos, const float width, const float height, const bool lr = false, const bool io = false) : FloorObstacle(material), type(type), atLinePos(atLinePos), width(width), height(height), leftRight(lr), inOut(io) {;}
Point2 getStart(const FloorObstacleLine* wall) const { Point2 getStart(const FloorObstacleWall* wall) const {
const Point2 dir = wall->to - wall->from; const Point2 dir = wall->to - wall->from;
return wall->from + dir * atLinePos; return wall->from + dir * atLinePos;
} }
Point2 getEnd(const FloorObstacleLine* wall) const { Point2 getEnd(const FloorObstacleWall* wall) const {
const Point2 dir = wall->to - wall->from; const Point2 dir = wall->to - wall->from;
return getStart(wall) + dir.normalized() * (leftRight ? -width : +width); return getStart(wall) + dir.normalized() * (leftRight ? -width : +width);
} }
}; };
/** wall->window obstacle */
struct FloorObstacleWallWindow : public FloorObstacle {
WindowType type;
float atLinePos;
float startsAtHeight;
float width;
float height;
bool leftRight = false;
bool inOut = false;
FloorObstacleWallWindow(const WindowType type, const Material material, const float atLinePos, const float startsAtHeight, const float width, const float height, const bool lr = false, const bool io = false) : FloorObstacle(material), type(type), atLinePos(atLinePos), startsAtHeight(startsAtHeight), width(width), height(height), leftRight(lr), inOut(io) {;}
Point2 getStart(const FloorObstacleWall* wall) const {
const Point2 dir = wall->to - wall->from;
const Point2 cen = wall->from + dir * atLinePos;
return cen - dir.normalized() * width/2;
}
Point2 getEnd(const FloorObstacleWall* wall) const {
const Point2 dir = wall->to - wall->from;
const Point2 cen = wall->from + dir * atLinePos;
return cen + dir.normalized() * width/2;
}
};
/** 3D obstacle */ /** 3D obstacle */
struct FloorObstacleObject : public FloorObstacle { struct FloorObstacleObject : public FloorObstacle {
std::string file; std::string file;

View File

@@ -388,6 +388,7 @@ namespace Floorplan {
// if (std::string("window") == n->Name()) {obstacles.push_back(parseFloorObstacleWindow(n));} // if (std::string("window") == n->Name()) {obstacles.push_back(parseFloorObstacleWindow(n));}
// if (std::string("pillar") == n->Name()) {obstacles.push_back(parseFloorObstaclePillar(n));} // if (std::string("pillar") == n->Name()) {obstacles.push_back(parseFloorObstaclePillar(n));}
//if (std::string("obstacle") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} // OLD //if (std::string("obstacle") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} // OLD
if (std::string("wall") == n->Name()) {obstacles.push_back(parseFloorObstacleWall(n));}
if (std::string("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} if (std::string("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));}
if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));} if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));}
if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));} if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
@@ -396,6 +397,38 @@ namespace Floorplan {
return obstacles; return obstacles;
} }
/** parse one wall */
static FloorObstacleWall* parseFloorObstacleWall(const XMLElem* el) {
FloorObstacleWall* wall = new FloorObstacleWall(
parseObstacleType(el->Attribute("type")),
parseMaterial(el->Attribute("material")),
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
el->FloatAttribute("x2"), el->FloatAttribute("y2"),
(el->FloatAttribute("thickness") > 0) ? (el->FloatAttribute("thickness")) : (0.15), // default wall thickness in m
el->FloatAttribute("height")
);
// doors
FOREACH_NODE(n, el) {
if (std::string("door") == n->Name()) {
FloorObstacleWallDoor* door = new FloorObstacleWallDoor(
parseDoorType(n->Attribute("type")),
parseMaterial(n->Attribute("material")),
n->FloatAttribute("at"),
n->FloatAttribute("width"),
n->FloatAttribute("height"),
n->BoolAttribute("lr"),
n->BoolAttribute("io")
);
wall->doors.push_back(door);
}
}
return wall;
}
/** parse one line */ /** parse one line */
static FloorObstacleLine* parseFloorObstacleLine(const XMLElem* el) { static FloorObstacleLine* parseFloorObstacleLine(const XMLElem* el) {
return new FloorObstacleLine( return new FloorObstacleLine(

View File

@@ -311,6 +311,8 @@ namespace Floorplan {
for (FloorObstacle* fo : mf->obstacles) { for (FloorObstacle* fo : mf->obstacles) {
if (dynamic_cast<FloorObstacleLine*>(fo)) { if (dynamic_cast<FloorObstacleLine*>(fo)) {
addFloorObstacleLine(doc, obstacles, (FloorObstacleLine*)fo); addFloorObstacleLine(doc, obstacles, (FloorObstacleLine*)fo);
} else if (dynamic_cast<FloorObstacleWall*>(fo)) {
addFloorObstacleWall(doc, obstacles, (FloorObstacleWall*)fo);
} else if (dynamic_cast<FloorObstacleCircle*>(fo)) { } else if (dynamic_cast<FloorObstacleCircle*>(fo)) {
addFloorObstacleCircle(doc, obstacles, (FloorObstacleCircle*)fo); addFloorObstacleCircle(doc, obstacles, (FloorObstacleCircle*)fo);
} else if (dynamic_cast<FloorObstacleDoor*>(fo)) { } else if (dynamic_cast<FloorObstacleDoor*>(fo)) {
@@ -324,7 +326,40 @@ namespace Floorplan {
} }
/** write a line obstacle (wall, handrail, ..) */ /** write a wall obstacle (wall) */
static void addFloorObstacleWall(XMLDoc& doc, XMLElem* obstacles, FloorObstacleWall* wall) {
XMLElem* oWall = doc.NewElement("wall");
obstacles->InsertEndChild(oWall);
oWall->SetAttribute("material", toString(wall->material).c_str());
oWall->SetAttribute("type", toString(wall->type).c_str());
oWall->SetAttribute("x1", wall->from.x);
oWall->SetAttribute("y1", wall->from.y);
oWall->SetAttribute("x2", wall->to.x);
oWall->SetAttribute("y2", wall->to.y);
oWall->SetAttribute("thickness", wall->thickness_m);
if (wall->height_m != 0) {oWall->SetAttribute("height", wall->height_m);}
// doors?
for (const FloorObstacleWallDoor* door : wall->doors) {
XMLElem* oDoor = doc.NewElement("door");
oWall->InsertEndChild(oDoor);
oDoor->SetAttribute("type", toString(door->type).c_str());
oDoor->SetAttribute("material", toString(door->material).c_str());
oDoor->SetAttribute("at", door->atLinePos);
oDoor->SetAttribute("width", door->width);
oDoor->SetAttribute("height", door->height);
oDoor->SetAttribute("io", door->inOut);
oDoor->SetAttribute("lr", door->leftRight);
}
}
/** write a line obstacle (old walls, handrail, ..) */
static void addFloorObstacleLine(XMLDoc& doc, XMLElem* obstacles, FloorObstacleLine* line) { static void addFloorObstacleLine(XMLDoc& doc, XMLElem* obstacles, FloorObstacleLine* line) {
XMLElem* obstacle = doc.NewElement("line"); XMLElem* obstacle = doc.NewElement("line");
obstacle->SetAttribute("material", toString(line->material).c_str()); obstacle->SetAttribute("material", toString(line->material).c_str());

View File

@@ -5,6 +5,60 @@
#include "Polygon2.h" #include "Polygon2.h"
#include "Triangle3.h" #include "Triangle3.h"
class TriangleStrip {
private:
std::vector<Point3> pts;
public:
void add(const Point3 p) {
pts.push_back(p);
}
void set(const std::vector<Point3>& pts) {
this->pts = pts;
}
void toTriangles(std::vector<Triangle3>& trias) const {
// https://en.wikipedia.org/wiki/Triangle_strip
// GL_TRIANGLE_STRIP
// Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
// For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
for (size_t j = 2; j < pts.size(); ++j) {
if (j % 2 == 0) {
Triangle3 tria(
pts[j-2],
pts[j-1],
pts[j]
);
trias.push_back(tria);
} else {
Triangle3 tria(
pts[j-1],
pts[j-2],
pts[j]
);
trias.push_back(tria);
}
}
}
std::vector<Triangle3> toTriangles() const {
std::vector<Triangle3> trias;
toTriangles(trias);
return trias;
}
};
class GPCPolygon2 { class GPCPolygon2 {
struct GPCPolygon : gpc_polygon { struct GPCPolygon : gpc_polygon {
@@ -113,35 +167,43 @@ public:
for (int i = 0; i < res.num_strips; ++i) { for (int i = 0; i < res.num_strips; ++i) {
gpc_vertex_list lst = res.strip[i]; gpc_vertex_list lst = res.strip[i];
for (int j = 2; j < lst.num_vertices; ++j) {
gpc_vertex& v1 = lst.vertex[j - 2];
gpc_vertex& v2 = lst.vertex[j - 1];
gpc_vertex& v3 = lst.vertex[j];
// https://en.wikipedia.org/wiki/Triangle_strip
// GL_TRIANGLE_STRIP
// Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
// For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
if (j % 2 == 0) {
Triangle3 tria(
Point3(v1.x, v1.y, z),
Point3(v2.x, v2.y, z),
Point3(v3.x, v3.y, z)
);
trias.push_back(tria);
} else {
Triangle3 tria(
Point3(v2.x, v2.y, z),
Point3(v1.x, v1.y, z),
Point3(v3.x, v3.y, z)
);
trias.push_back(tria);
}
TriangleStrip strip;
for (int j = 0; j < lst.num_vertices; ++j) {
gpc_vertex& v = lst.vertex[j];
strip.add(Point3(v.x, v.y, z));
} }
strip.toTriangles(trias);
// for (int j = 2; j < lst.num_vertices; ++j) {
// gpc_vertex& v1 = lst.vertex[j - 2];
// gpc_vertex& v2 = lst.vertex[j - 1];
// gpc_vertex& v3 = lst.vertex[j];
// // https://en.wikipedia.org/wiki/Triangle_strip
// // GL_TRIANGLE_STRIP
// // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
// // For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
// if (j % 2 == 0) {
// Triangle3 tria(
// Point3(v1.x, v1.y, z),
// Point3(v2.x, v2.y, z),
// Point3(v3.x, v3.y, z)
// );
// trias.push_back(tria);
// } else {
// Triangle3 tria(
// Point3(v2.x, v2.y, z),
// Point3(v1.x, v1.y, z),
// Point3(v3.x, v3.y, z)
// );
// trias.push_back(tria);
// }
//}
} }

View File

@@ -14,8 +14,8 @@
#include "DataMap3.h" #include "DataMap3.h"
#include "../../../geo/Ray3.h" #include "../../../geo/Ray3.h"
#include "MaterialOptions.h" #include "MaterialOptions.h"
#include "Obstacle3.h" #include "../../../floorplan/3D/Obstacle3.h"
#include "ModelFactory.h" #include "../../../floorplan/3D/Builder.h"
//#include "ObstacleTree.h" //#include "ObstacleTree.h"
@@ -33,6 +33,7 @@
// 3D // 3D
// http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf // http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf
using namespace Floorplan3D;
namespace Ray3D { namespace Ray3D {
@@ -199,7 +200,7 @@ namespace Ray3D {
// allocate // allocate
dm.resize(bbox, gs); dm.resize(bbox, gs);
ModelFactory fac(map); Builder fac(map);
std::vector<Obstacle3D> obstacles = fac.getMesh().elements; std::vector<Obstacle3D> obstacles = fac.getMesh().elements;
// build bounding volumes // build bounding volumes