Skip to content

Commit ccbece5

Browse files
committed
Enable component pruning during simplification
In addition to the regular edge collapse, we now allow the simplifier to remove small isolated components. Components that are removed are below the error threshold in size and as such should not noticeably contribute to the overall rendering of the object. This helps simplify topologically complex but small parts of larger meshes and more comfortably reach the LOD targets. In some cases, pruning can cause the last LOD to shrink to 0 triangles which may prevent a slightly larger LOD from being used at the maximum distance; in this case we retry simplification without pruning once.
1 parent 6e4e807 commit ccbece5

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

scene/resources/3d/importer_mesh.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
480480

481481
LocalVector<int> current_indices = merged_indices;
482482
float current_error = 0.0f;
483+
bool allow_prune = true;
483484

484485
while (current_indices.size() > min_target_indices * 2) {
485486
unsigned int current_index_count = current_indices.size();
@@ -493,6 +494,11 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
493494
// Lock geometric boundary in case the mesh is composed of multiple material subsets.
494495
simplify_options |= SurfaceTool::SIMPLIFY_LOCK_BORDER;
495496

497+
if (allow_prune) {
498+
// Remove small disconnected components.
499+
simplify_options |= SurfaceTool::SIMPLIFY_PRUNE;
500+
}
501+
496502
if (deformable) {
497503
// Improves appearance of deformable objects after deformation by using more regular tessellation.
498504
simplify_options |= SurfaceTool::SIMPLIFY_REGULARIZE;
@@ -513,6 +519,15 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
513519
simplify_options,
514520
&step_error);
515521

522+
if (new_index_count == 0 && allow_prune) {
523+
// If the best result the simplifier could arrive at with pruning enabled is 0 triangles, there might still be an opportunity
524+
// to reduce the number of triangles further *without* completely decimating the mesh. It will be impossible to reach the target
525+
// this way - if the target was reachable without going down to 0, the simplifier would have done it! - but we might still be able
526+
// to get one more slightly lower level if we retry without pruning.
527+
allow_prune = false;
528+
continue;
529+
}
530+
516531
// Accumulate error over iterations. Usually, it's correct to use step_error as is; however, on coarse LODs, we may start
517532
// getting *smaller* relative error compared to the previous LOD. To make sure the error is monotonic and strictly increasing,
518533
// and to limit the switching (pop) distance, we ensure the error grows by an arbitrary factor each iteration.

0 commit comments

Comments
 (0)