added support for .obj objects within the floorplan
include objects within navmesh calculation include objects within 3d mesh generation minor changes/fixes
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#include "Tube.h"
|
||||
#include "FloorplanMesh.h"
|
||||
|
||||
#include "OBJPool.h"
|
||||
|
||||
namespace Ray3D {
|
||||
|
||||
/**
|
||||
@@ -25,6 +27,7 @@ namespace Ray3D {
|
||||
bool exportHandrails = true;
|
||||
bool exportDoors = true;
|
||||
bool doorsOpen = true;
|
||||
bool exportObjects = true;
|
||||
bool exportWallTops = false;
|
||||
std::vector<Floorplan::Floor*> exportFloors;
|
||||
|
||||
@@ -114,6 +117,8 @@ namespace Ray3D {
|
||||
/** convert a floor (floor/ceiling) into triangles */
|
||||
std::vector<Obstacle3D> getFloor(const Floorplan::Floor* f) {
|
||||
|
||||
FloorPos fpos(f);
|
||||
|
||||
std::vector<Obstacle3D> res;
|
||||
if (!f->enabled) {return res;}
|
||||
if (!f->outline.enabled) {return res;}
|
||||
@@ -157,20 +162,22 @@ namespace Ray3D {
|
||||
Obstacle3D obs(type, Floorplan::Material::CONCRETE);
|
||||
|
||||
// convert them into polygons
|
||||
std::vector<std::vector<Point3>> polys = it.second.get(f->getStartingZ());
|
||||
std::vector<std::vector<Point3>> polys = it.second.get(fpos.z1);
|
||||
|
||||
// convert polygons (GL_TRIANGLE_STRIP) to triangles
|
||||
for (const std::vector<Point3>& pts : polys) {
|
||||
for (int i = 0; i < (int)pts.size() - 2; ++i) {
|
||||
|
||||
// floor must be double-sided for reflection to work with the correct normals
|
||||
// floor must be double-sided
|
||||
Triangle3 tria1 (pts[i+0], pts[i+1], pts[i+2]);
|
||||
Triangle3 tria2 (pts[i+2], pts[i+1], pts[i+0]);
|
||||
|
||||
// ensure the triangle with the normal pointing downwards (towards bulding's cellar)
|
||||
// is below the triangle that points upwards (towards the sky)
|
||||
if (tria1.getNormal().z < 0) {tria1 = tria1 - Point3(0,0,0.02);}
|
||||
if (tria2.getNormal().z < 0) {tria2 = tria2 - Point3(0,0,0.02);}
|
||||
if (tria1.getNormal().z < 0) {std::swap(tria1, tria2);}
|
||||
|
||||
// tria2 = ceiling of previous floor
|
||||
tria2 -= Point3(0,0,fpos.fh);
|
||||
|
||||
// add both
|
||||
obs.triangles.push_back(tria1);
|
||||
@@ -208,6 +215,16 @@ namespace Ray3D {
|
||||
}
|
||||
}
|
||||
|
||||
// handle object obstacles
|
||||
const Floorplan::FloorObstacleObject* foo = dynamic_cast<const Floorplan::FloorObstacleObject*>(fo);
|
||||
if (foo) {
|
||||
if (exportObjects) {
|
||||
if (!foo->file.empty()) {
|
||||
res.push_back(getObject(f, foo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Floorplan::FloorObstacleDoor* door = dynamic_cast<const Floorplan::FloorObstacleDoor*>(fo);
|
||||
if (door) {
|
||||
if (exportObstacles) {
|
||||
@@ -246,6 +263,8 @@ namespace Ray3D {
|
||||
|
||||
Obstacle3D getWall(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol, const Floorplan::FloorObstacleDoor* aboveDoor) const {
|
||||
|
||||
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);
|
||||
@@ -255,8 +274,8 @@ namespace Ray3D {
|
||||
const float deg = rad * 180 / M_PI;
|
||||
|
||||
// cube's destination center
|
||||
const float cenZ = (!aboveDoor) ? (f->atHeight + f->height/2) : (f->getEndingZ() - (f->height - aboveDoor->height) / 2);
|
||||
const float height = (!aboveDoor) ? (f->height) : (f->height - aboveDoor->height);
|
||||
const float cenZ = (!aboveDoor) ? (fpos.z1 + fpos.height/2) : (fpos.z2 - (fpos.height - aboveDoor->height) / 2);
|
||||
const float height = (!aboveDoor) ? (fpos.height) : (fpos.height - aboveDoor->height);
|
||||
const Point3 pos(cen2.x, cen2.y, cenZ);
|
||||
|
||||
// div by 2.01 to prevent overlapps and z-fighting
|
||||
@@ -276,8 +295,44 @@ namespace Ray3D {
|
||||
|
||||
}
|
||||
|
||||
/** 3D Obstacle from .obj 3D mesh */
|
||||
Obstacle3D getObject(const Floorplan::Floor* f, const Floorplan::FloorObstacleObject* foo) const {
|
||||
|
||||
FloorPos fpos(f);
|
||||
|
||||
const std::string& name = foo->file;
|
||||
Obstacle3D obs = OBJPool::get().getObject(name);
|
||||
obs = obs.rotated_deg( Point3(foo->rot.x, foo->rot.y, foo->rot.z) );
|
||||
obs = obs.translated(foo->pos + Point3(0,0,fpos.z1));
|
||||
|
||||
// std::vector<Triangle3> trias;
|
||||
// for (const OBJReader::Face& face : reader.getData().faces) {
|
||||
// Point3 p1 = face.vnt[0].vertex;
|
||||
// Point3 p2 = face.vnt[1].vertex;
|
||||
// Point3 p3 = face.vnt[2].vertex;
|
||||
// p1 = p1.rot(foo->rot.x/180.0f*M_PI, foo->rot.y/180.0f*M_PI, foo->rot.z/180.0f*M_PI);
|
||||
// p2 = p2.rot(foo->rot.x/180.0f*M_PI, foo->rot.y/180.0f*M_PI, foo->rot.z/180.0f*M_PI);
|
||||
// p3 = p3.rot(foo->rot.x/180.0f*M_PI, foo->rot.y/180.0f*M_PI, foo->rot.z/180.0f*M_PI);
|
||||
// p1 += foo->pos; p1.z += fpos.z1;
|
||||
// p2 += foo->pos; p2.z += fpos.z1;
|
||||
// p3 += foo->pos; p3.z += fpos.z1;
|
||||
// const Triangle3 tria(p1, p2, p3);
|
||||
// trias.push_back(tria);
|
||||
// }
|
||||
|
||||
// // done
|
||||
// Obstacle3D res(Obstacle3D::Type::OBJECT, Floorplan::Material::WOOD);
|
||||
// res.triangles = trias;
|
||||
// return res;
|
||||
|
||||
return obs;
|
||||
|
||||
}
|
||||
|
||||
Obstacle3D getDoor(const Floorplan::Floor* f, const Floorplan::FloorObstacleDoor* door) const {
|
||||
|
||||
FloorPos fpos(f);
|
||||
|
||||
const float thickness_m = 0.10; // TODO??
|
||||
const Point2 from = door->from;
|
||||
const Point2 to = door->to;
|
||||
@@ -297,7 +352,7 @@ namespace Ray3D {
|
||||
|
||||
if (doorsOpen) {deg += (door->swap) ? (-90) : (+90);}
|
||||
mat = Matrix4::getTranslation(1,0,0); // cube's edge located at 0,0,0
|
||||
pos = Point3(from.x, from.y, f->atHeight + door->height/2);
|
||||
pos = Point3(from.x, from.y, fpos.z1 + door->height/2);
|
||||
|
||||
const float sx = from.getDistance(to) / 2;
|
||||
const float sy = thickness_m / 2;
|
||||
@@ -312,7 +367,7 @@ namespace Ray3D {
|
||||
} else if (Floorplan::DoorType::REVOLVING == door->type) {
|
||||
|
||||
const Point2 cen2 = (from+to)/2;
|
||||
const Point3 pos(cen2.x, cen2.y, f->atHeight + door->height/2);
|
||||
const Point3 pos(cen2.x, cen2.y, fpos.z1 + door->height/2);
|
||||
|
||||
// outer and inner radius
|
||||
const float rOuter = from.getDistance(to) / 2;
|
||||
@@ -350,11 +405,6 @@ namespace Ray3D {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
@@ -383,6 +433,8 @@ namespace Ray3D {
|
||||
|
||||
Obstacle3D getHandrail(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol) const {
|
||||
|
||||
FloorPos fpos(f);
|
||||
|
||||
// target
|
||||
Obstacle3D res(getType(fol), fol->material);
|
||||
if (!exportHandrails) {return res;}
|
||||
@@ -393,8 +445,8 @@ namespace Ray3D {
|
||||
const Point2 cen2 = (from+to)/2;
|
||||
|
||||
// edges
|
||||
const float z1 = f->atHeight;
|
||||
const float z2 = f->atHeight + 1.0;
|
||||
const float z1 = fpos.z1;
|
||||
const float z2 = fpos.z1 + 1.0;
|
||||
Point3 p1 = Point3(from.x, from.y, z1);
|
||||
Point3 p2 = Point3(to.x, to.y, z1);
|
||||
Point3 p3 = Point3(from.x, from.y, z2);
|
||||
@@ -576,6 +628,15 @@ namespace Ray3D {
|
||||
}
|
||||
}
|
||||
|
||||
/** used to model ceiling thickness */
|
||||
struct FloorPos {
|
||||
float fh;
|
||||
float z1;
|
||||
float z2;
|
||||
float height;
|
||||
FloorPos(const Floorplan::Floor* f) : fh(0.01), z1(f->getStartingZ()), z2(f->getEndingZ()-fh), height(z2-z1) {;}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user