light: start a mesh_t class
This commit is contained in:
parent
a0a7021707
commit
055b5061f1
|
|
@ -23,6 +23,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/ext.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;
|
const float t = glm::dot(vp, vw) / l2;
|
||||||
return t;
|
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;
|
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__ */
|
#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(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)));
|
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