diff --git a/common/mathlib.cc b/common/mathlib.cc index 94cd7c57..5f53e10a 100644 --- a/common/mathlib.cc +++ b/common/mathlib.cc @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -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> &faces) +{ + // FIXME: this is ugly + using pos_t = tuple; + + int nextVert = 0; + map posToVertIndex; + + vector> facesWithIndices; + for (const auto &face : faces) { + vector 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 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> meshToFaces(const mesh_t &mesh) +{ + std::vector> res; + for (const auto &meshFace : mesh.faces) { + std::vector 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 &face = mesh.faces.at(facenum); + +} + +void cleanupMesh(mesh_t &mesh) +{ + using facenum_t = int; + + std::vector> faces; + + octree_node_t octree = makeOctree(faces); + +} diff --git a/include/common/mathlib.hh b/include/common/mathlib.hh index dd864820..40ed2b83 100644 --- a/include/common/mathlib.hh +++ b/include/common/mathlib.hh @@ -452,4 +452,19 @@ std::vector PointsAlongLine(const V &start, const V &end, const float step) return result; } +class mesh_t { +public: + std::vector verts; + std::vector> faces; +}; + +// Welds vertices at exactly the same position +mesh_t buildMesh(const std::vector> &faces); +std::vector> 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__ */ diff --git a/light/test_light.cc b/light/test_light.cc index 1ed9f36b..90ef4fb7 100644 --- a/light/test_light.cc +++ b/light/test_light.cc @@ -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 poly1 { + { 0,0,0 }, + { 0,64,0 }, + { 64,64,0 }, + { 64,0,0 } + }; + const vector poly2 { + { 64,0,0 }, + { 64,64,0 }, + { 128,64,0 }, + { 128,0,0 } + }; + const vector> 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 poly1 { + { 0,0,0 }, + { 0,64,0 }, + { 64,64,0 }, + { 64,0,0 } + }; + const vector poly2 { + { 64,32,0 }, + { 64,64,0 }, + { 128,64,0 }, + { 128,32,0 } + }; + const vector poly3 { + { 64,0,0 }, + { 64,32,0 }, + { 128,32,0 }, + { 128,0,0 } + }; + + const vector> 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)); +}