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:
2018-02-17 17:20:43 +01:00
parent 42a3a47317
commit 8358f45674
15 changed files with 770 additions and 114 deletions

View File

@@ -2,6 +2,7 @@
#define FLOORPLANMESH_H
#include "Obstacle3.h"
#include <fstream>
namespace Ray3D {
@@ -12,11 +13,35 @@ namespace Ray3D {
std::vector<Obstacle3D> elements;
/** export as OBJ file */
void exportOBJsimple(const std::string& file) {
std::ofstream out(file.c_str());
out << toOBJsimple();
out.close();
}
/** export as OBJ file */
void exportOBJcomplex(const std::string& file, const std::string& nameOnly) {
std::ofstream outOBJ((file+".obj").c_str());
std::ofstream outMTL((file+".mtl").c_str());
OBJData data = toOBJ(nameOnly);
outOBJ << data.obj;
outMTL << data.mtl;
outOBJ.close();
outMTL.close();
}
/** export as PLY file */
void exportPLY(const std::string& file) {
std::ofstream out(file.c_str());
out << toPLY();
out.close();
}
/** DEBUG: convert to .obj file code for exporting */
std::string toOBJ() {
std::string toOBJsimple() {
int nVerts = 1;
int nObjs = 0;
std::string res;
// write each obstacle
@@ -29,12 +54,87 @@ namespace Ray3D {
res += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.y) + " " + std::to_string(t.p3.z) + "\n";
}
}
// write each obstacle
for (const Obstacle3D& o : elements) {
// write the faces
for (size_t i = 0; i < o.triangles.size(); ++i) {
res += "f " + std::to_string(nVerts+0) + " " + std::to_string(nVerts+1) + " " + std::to_string(nVerts+2) + "\n";
nVerts += 3;
}
}
// done
return res;
}
struct OBJData {
std::string obj;
std::string mtl;
};
/** DEBUG: convert to .obj file code for exporting */
OBJData toOBJ(const std::string& name) {
bool swapYZ = true;
int nVerts = 1;
int nObjs = 0;
OBJData res;
// write material file
for (size_t idx = 0; idx < mats.size(); ++idx) {
const Material& mat = mats[idx];
res.mtl += "newmtl mat_" + std::to_string(idx) + "\n";
res.mtl += "Ka 0.000 0.000 0.000 \n"; // ambient
res.mtl += "Kd " + std::to_string(mat.r/255.0f) + " " + std::to_string(mat.g/255.0f) + " " + std::to_string(mat.b/255.0f) + "\n";
res.mtl += "Ks 0.000 0.000 0.000 \n";
res.mtl += "d " + std::to_string(mat.a/255.0f) + "\n"; // alpha
res.mtl += "Tr " + std::to_string(1.0f-mat.a/255.0f) + "\n"; // inv-alpha
res.mtl += "illum 2 \n";
res.mtl += "\n";
}
// use material file
res.obj += "mtllib " + name + ".mtl" + "\n";
// write each obstacle
for (const Obstacle3D& o : elements) {
// write the vertices
for (const Triangle3& t : o.triangles) {
if (!swapYZ) {
res.obj += "v " + std::to_string(t.p1.x) + " " + std::to_string(t.p1.y) + " " + std::to_string(t.p1.z) + "\n";
res.obj += "v " + std::to_string(t.p2.x) + " " + std::to_string(t.p2.y) + " " + std::to_string(t.p2.z) + "\n";
res.obj += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.y) + " " + std::to_string(t.p3.z) + "\n";
} else {
res.obj += "v " + std::to_string(t.p1.x) + " " + std::to_string(t.p1.z) + " " + std::to_string(t.p1.y) + "\n";
res.obj += "v " + std::to_string(t.p2.x) + " " + std::to_string(t.p2.z) + " " + std::to_string(t.p2.y) + "\n";
res.obj += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.z) + " " + std::to_string(t.p3.y) + "\n";
}
}
}
// write each obstacle
for (const Obstacle3D& o : elements) {
// create a new group
res += "g elem_" + std::to_string(++nObjs) + "\n";
//res.obj += "g elem_" + std::to_string(++nObjs) + "\n";
// create a new object
res.obj += "o elem_" + std::to_string(++nObjs) + "\n";
// group's material
res.obj += "usemtl mat_" + std::to_string(getMaterial(o)) + "\n";
// write the group's faces
for (size_t i = 0; i < o.triangles.size(); ++i) {
res += "f " + std::to_string(nVerts+0) + " " + std::to_string(nVerts+1) + " " + std::to_string(nVerts+2) + "\n";
res.obj += "f " + std::to_string(nVerts+0) + " " + std::to_string(nVerts+1) + " " + std::to_string(nVerts+2) + "\n";
nVerts += 3;
}
@@ -59,18 +159,6 @@ namespace Ray3D {
faces += obs.triangles.size();
}
// material
std::vector<Material> mats = {
Material(0,128,0,255), // ground outdoor
Material(64,64,64,255), // ground outdoor
Material(255,96,96,255), // stair
Material(128,128,128,255), // concrete
Material(64,128,255,64), // glass
Material(200,200,200,255), // default
};
res << "element material " << mats.size() << "\n";
res << "property uchar red\n";
@@ -85,11 +173,11 @@ namespace Ray3D {
res << "property float nx\n";
res << "property float ny\n";
res << "property float nz\n";
res << "property int material_index\n";
res << "property uchar red\n";
res << "property uchar green\n";
res << "property uchar blue\n";
res << "property uchar alpha\n";
res << "property int material_index\n";
res << "element face " << faces << "\n";
res << "property list uchar int vertex_indices\n";
@@ -107,9 +195,9 @@ namespace Ray3D {
const Material& mat = mats[matIdx];
for (const Triangle3& tria : obs.triangles) {
const Point3 n = cross(tria.p2-tria.p1, tria.p3-tria.p1).normalized();
res << tria.p1.x << " " << tria.p1.y << " " << tria.p1.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << "\n";
res << tria.p2.x << " " << tria.p2.y << " " << tria.p2.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a <<"\n";
res << tria.p3.x << " " << tria.p3.y << " " << tria.p3.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a <<"\n";
res << tria.p1.x << " " << tria.p1.y << " " << tria.p1.z << " " << n.x << " " << n.y << " " << n.z << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << " " << matIdx << "\n";
res << tria.p2.x << " " << tria.p2.y << " " << tria.p2.z << " " << n.x << " " << n.y << " " << n.z << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << " " << matIdx << "\n";
res << tria.p3.x << " " << tria.p3.y << " " << tria.p3.z << " " << n.x << " " << n.y << " " << n.z << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << " " << matIdx << "\n";
}
}
@@ -131,6 +219,20 @@ namespace Ray3D {
Material(int r, int g, int b, int a) : r(r), g(g), b(b), a(a) {;}
};
// material
std::vector<Material> mats = {
Material(0,128,0,255), // ground outdoor
Material(64,64,64,255), // ground outdoor
Material(255,96,96,255), // stair
Material(128,128,128,255), // concrete
Material(64,128,255,64), // glass
Material(200,200,200,255), // default
};
int getMaterial(const Obstacle3D& o) const {
if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return 0;}
if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return 1;}