light: start a mesh_t class
This commit is contained in:
parent
a0a7021707
commit
055b5061f1
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue