struct meshopt_Meshlet
{
/* offsets within meshlet_vertices and meshlet_triangles arrays with meshlet data */
unsigned int vertex_offset;
unsigned int triangle_offset;
/* number of vertices and triangles used in the meshlet; data is stored in consecutive range defined by offset and count */
unsigned int vertex_count;
unsigned int triangle_count;
};
The function meshopt_buildMeshlets outputs an array of meshopt_meshlet 's and the buffers that each meshopt_meshlet indexes into (meshlet_triangles and meshlet_vertices). I would like to know, given this structure, how would I merge two meshletsand then use the method meshopt_simplify to simplify their geometry. All this indexing process is quite complicated for me, I’m trying to think in a way that makes sense and works for me.
Consider that Cluster has a meshopt_meshlet field.
Could anyone demonstrate to me how do Merge two meshopt_meshlets and simplify their geomtry using meshopt_simplify, I’m not sure about how to properly index the the final vertex/index buffer. This question may be a bit hard for me to properly explain myself, so please let me know what details you need.
to use the meshopt_simplify on the merged meshlet, you need to set the offset correctly.
below is my code,it can merge meshlets and simplify it.Hope it will help!
static void merge(std::vector<meshopt_Meshlet>& meshlets, std::vector<uint32_t>& index, std::vector<meshopt_Bounds>& meshletBounds, std::vector<uint8_t>vertices, int stride)
{
std::vector<uint32_t>new_index;
std::vector<meshopt_Meshlet>new_meshlets;
std::vector<meshopt_Bounds>new_bound;
std::vector<bool>is_merged(meshlets.size(), false);
auto offset = 0;
for (int cnt = 0; cnt + 1 < meshlets.size(); cnt = cnt + 2)
{
meshopt_Meshlet mt1, mt2;
{
.....
//find mt1,mt2
}
for (int i = 0; i < mt1.triangle_count * 3; i++)
{
new_index.emplace_back(index[mt1.triangle_offset + i]);
}
for (int i = 0; i < mt2.triangle_count * 3; i++)
{
new_index.emplace_back(index[mt2.triangle_offset + i]);
}
meshopt_Meshlet tmp;
tmp.triangle_count = mt1.triangle_count + mt2.triangle_count;
tmp.triangle_offset = offset;
new_meshlets.emplace_back(tmp);
offset = new_index.size();
//
auto p = meshopt_computeClusterBounds(&new_index[tmp.triangle_offset], tmp.triangle_count * 3, (float*)vertices.data(), vertices.size() / stride, stride);
new_bound.emplace_back(p);
//
}
//odd size
if (meshlets.size() % 2 != 0)
{
meshopt_Meshlet last;
for (int id = 0; id < is_merged.size(); id++)
{
if (is_merged[id] == false)
{
last = meshlets[id];
}
}
for (int i = 0; i < last.triangle_count * 3; i++)
{
new_index.emplace_back(index[last.triangle_offset + i]);
}
meshopt_Meshlet tmp;
tmp.triangle_count = last.triangle_count;
tmp.triangle_offset = offset;
new_meshlets.emplace_back(tmp);
offset = new_index.size();
}
meshlets.assign(new_meshlets.begin(), new_meshlets.end());
index.assign(new_index.begin(), new_index.end());
//simplify meshlets
for (int i = 0; i < meshlets.size(); i++)
{
auto& mt = meshlets[i];
float target_error = 0.9;
float lod_error = 0.f;
auto n = meshopt_simplify(&index[mt.triangle_offset], &index[mt.triangle_offset], mt.triangle_count * 3, (float*)vertices.data(), vertices.size() / stride, stride,
6, target_error, 1, &lod_error);
mt.triangle_count = n / 3;
}
//recalculate the bounds
for (int i = 0; i < meshlets.size(); i++)
{
auto tmp = meshlets[i];
auto p = meshopt_computeClusterBounds(&new_index[tmp.triangle_offset], tmp.triangle_count * 3, (float*)vertices.data(), vertices.size() / stride, stride);
new_bound.emplace_back(p);
}
meshletBounds.assign(new_bound.begin(), new_bound.end());