light: start a mesh_t class

This commit is contained in:
Eric Wasylishen 2017-04-04 13:39:19 -06:00
parent a0a7021707
commit 055b5061f1
3 changed files with 166 additions and 0 deletions

View File

@ -23,6 +23,7 @@
#include <assert.h>
#include <tuple>
#include <map>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
@ -654,3 +655,80 @@ float FractionOfLine(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p)
const float t = glm::dot(vp, vw) / l2;
return t;
}
// mesh_t
mesh_t buildMesh(const vector<vector<glm::vec3>> &faces)
{
// FIXME: this is ugly
using pos_t = tuple<float, float, float>;
int nextVert = 0;
map<pos_t, int> posToVertIndex;
vector<vector<int>> facesWithIndices;
for (const auto &face : faces) {
vector<int> vertIndices;
for (const auto &vert : face) {
const pos_t pos = make_tuple(vert[0], vert[1], vert[2]);
const auto it = posToVertIndex.find(pos);
if (it == posToVertIndex.end()) {
posToVertIndex[pos] = nextVert;
vertIndices.push_back(nextVert);
nextVert++;
} else {
int vertIndex = it->second;
vertIndices.push_back(vertIndex);
}
}
facesWithIndices.push_back(vertIndices);
}
// convert posToVertIndex to a vector
vector<glm::vec3> vertsVec;
vertsVec.resize(posToVertIndex.size());
for (const auto &posIndex : posToVertIndex) {
const pos_t &pos = posIndex.first;
vertsVec.at(posIndex.second) = glm::vec3(std::get<0>(pos), std::get<1>(pos), std::get<2>(pos));
}
mesh_t res;
res.verts = vertsVec;
res.faces = facesWithIndices;
return res;
}
std::vector<std::vector<glm::vec3>> meshToFaces(const mesh_t &mesh)
{
std::vector<std::vector<glm::vec3>> res;
for (const auto &meshFace : mesh.faces) {
std::vector<glm::vec3> points;
for (int vertIndex : meshFace) {
const glm::vec3 point = mesh.verts.at(vertIndex);
points.push_back(point);
}
res.push_back(points);
}
Q_assert(res.size() == mesh.faces.size());
return res;
}
static aabb3 mesh_face_bbox(const mesh_t &mesh, int facenum)
{
const std::vector<int> &face = mesh.faces.at(facenum);
}
void cleanupMesh(mesh_t &mesh)
{
using facenum_t = int;
std::vector<std::pair<aabb3, facenum_t>> faces;
octree_node_t<facenum_t> octree = makeOctree(faces);
}

View File

@ -452,4 +452,19 @@ std::vector<V> PointsAlongLine(const V &start, const V &end, const float step)
return result;
}
class mesh_t {
public:
std::vector<glm::vec3> verts;
std::vector<std::vector<int>> faces;
};
// Welds vertices at exactly the same position
mesh_t buildMesh(const std::vector<std::vector<glm::vec3>> &faces);
std::vector<std::vector<glm::vec3>> meshToFaces(const mesh_t &mesh);
// Preserves the number and order of faces.
// doesn't merge verts.
// adds verts to fix t-juncs
void cleanupMesh(mesh_t &mesh);
#endif /* __COMMON_MATHLIB_H__ */

View File

@ -519,3 +519,76 @@ TEST(mathlib, FractionOfLine) {
ASSERT_FLOAT_EQ(2, FractionOfLine(vec3(0,0,0), vec3(1,1,1), vec3(2,2,2)));
ASSERT_FLOAT_EQ(-1, FractionOfLine(vec3(0,0,0), vec3(1,1,1), vec3(-1,-1,-1)));
}
// mesh_t
TEST(mathlib, meshCreate) {
const vector<vec3> poly1 {
{ 0,0,0 },
{ 0,64,0 },
{ 64,64,0 },
{ 64,0,0 }
};
const vector<vec3> poly2 {
{ 64,0,0 },
{ 64,64,0 },
{ 128,64,0 },
{ 128,0,0 }
};
const vector<vector<vec3>> polys { poly1, poly2 };
const mesh_t m = buildMesh(polys);
ASSERT_EQ(6, m.verts.size());
ASSERT_EQ(2, m.faces.size());
ASSERT_EQ(polys, meshToFaces(m));
}
TEST(mathlib, meshFixTJuncs) {
/*
poly1
x=0 x=64 x=128
|---|--| y=64 poly2
| +--| y=32
|---|--| y=0 poly3
poly1 should get a vertex inserted at the +
*/
const vector<vec3> poly1 {
{ 0,0,0 },
{ 0,64,0 },
{ 64,64,0 },
{ 64,0,0 }
};
const vector<vec3> poly2 {
{ 64,32,0 },
{ 64,64,0 },
{ 128,64,0 },
{ 128,32,0 }
};
const vector<vec3> poly3 {
{ 64,0,0 },
{ 64,32,0 },
{ 128,32,0 },
{ 128,0,0 }
};
const vector<vector<vec3>> polys { poly1, poly2, poly3 };
mesh_t m = buildMesh(polys);
ASSERT_EQ(8, m.verts.size());
ASSERT_EQ(3, m.faces.size());
ASSERT_EQ(polys, meshToFaces(m));
cleanupMesh(m);
const auto newFaces = meshToFaces(m);
#if 0
EXPECT_NE(poly1, newFaces.at(0));
#endif
EXPECT_EQ(poly2, newFaces.at(1));
EXPECT_EQ(poly3, newFaces.at(2));
}