diff options
Diffstat (limited to 'scene/resources/surface_tool.cpp')
-rw-r--r-- | scene/resources/surface_tool.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 0677d9c1a8..8ff1fde2cf 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -37,6 +37,44 @@ SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr; SurfaceTool::SimplifyWithAttribFunc SurfaceTool::simplify_with_attrib_func = nullptr; SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr; SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr; +SurfaceTool::GenerateRemapFunc SurfaceTool::generate_remap_func = nullptr; +SurfaceTool::RemapVertexFunc SurfaceTool::remap_vertex_func = nullptr; +SurfaceTool::RemapIndexFunc SurfaceTool::remap_index_func = nullptr; + +void SurfaceTool::strip_mesh_arrays(PackedVector3Array &r_vertices, PackedInt32Array &r_indices) { + ERR_FAIL_COND_MSG(!generate_remap_func || !remap_vertex_func || !remap_index_func, "Meshoptimizer library is not initialized."); + + Vector<uint32_t> remap; + remap.resize(r_vertices.size()); + uint32_t new_vertex_count = generate_remap_func(remap.ptrw(), (unsigned int *)r_indices.ptr(), r_indices.size(), (float *)r_vertices.ptr(), r_vertices.size(), sizeof(Vector3)); + remap_vertex_func(r_vertices.ptrw(), r_vertices.ptr(), r_vertices.size(), sizeof(Vector3), remap.ptr()); + r_vertices.resize(new_vertex_count); + remap_index_func((unsigned int *)r_indices.ptrw(), (unsigned int *)r_indices.ptr(), r_indices.size(), remap.ptr()); + + HashMap<const int *, bool, TriangleHasher, TriangleHasher> found_triangles; + int *idx_ptr = r_indices.ptrw(); + + int filtered_indices_count = 0; + for (int i = 0; i < r_indices.size() / 3; i++) { + const int *tri = idx_ptr + (i * 3); + + if (tri[0] == tri[1] || tri[1] == tri[2] || tri[2] == tri[0]) { + continue; + } + + if (found_triangles.has(tri)) { + continue; + } + + if (i != filtered_indices_count) { + memcpy(idx_ptr + (filtered_indices_count * 3), tri, sizeof(int) * 3); + } + + found_triangles[tri] = true; + filtered_indices_count++; + } + r_indices.resize(filtered_indices_count * 3); +} bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { if (vertex != p_vertex.vertex) { @@ -107,6 +145,56 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { return h; } +uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) { + int t0 = p_triangle[0]; + int t1 = p_triangle[1]; + int t2 = p_triangle[2]; + + if (t0 > t1) { + SWAP(t0, t1); + } + if (t1 > t2) { + SWAP(t1, t2); + } + if (t0 > t1) { + SWAP(t0, t1); + } + + return (t0 * 73856093) ^ (t1 * 19349663) ^ (t2 * 83492791); +} + +bool SurfaceTool::TriangleHasher::compare(const int *p_lhs, const int *p_rhs) { + int r0 = p_rhs[0]; + int r1 = p_rhs[1]; + int r2 = p_rhs[2]; + + if (r0 > r1) { + SWAP(r0, r1); + } + if (r1 > r2) { + SWAP(r1, r2); + } + if (r0 > r1) { + SWAP(r0, r1); + } + + int l0 = p_lhs[0]; + int l1 = p_lhs[1]; + int l2 = p_lhs[2]; + + if (l0 > l1) { + SWAP(l0, l1); + } + if (l1 > l2) { + SWAP(l1, l2); + } + if (l0 > l1) { + SWAP(l0, l1); + } + + return l0 == r0 && l1 == r1 && l2 == r2; +} + void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) { clear(); |