mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
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.
This commit is contained in:
parent
6e4e8072e1
commit
ccbece58d8
1 changed files with 15 additions and 0 deletions
|
@ -480,6 +480,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
|
||||||
|
|
||||||
LocalVector<int> current_indices = merged_indices;
|
LocalVector<int> current_indices = merged_indices;
|
||||||
float current_error = 0.0f;
|
float current_error = 0.0f;
|
||||||
|
bool allow_prune = true;
|
||||||
|
|
||||||
while (current_indices.size() > min_target_indices * 2) {
|
while (current_indices.size() > min_target_indices * 2) {
|
||||||
unsigned int current_index_count = current_indices.size();
|
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
|
||||||
// Lock geometric boundary in case the mesh is composed of multiple material subsets.
|
// Lock geometric boundary in case the mesh is composed of multiple material subsets.
|
||||||
simplify_options |= SurfaceTool::SIMPLIFY_LOCK_BORDER;
|
simplify_options |= SurfaceTool::SIMPLIFY_LOCK_BORDER;
|
||||||
|
|
||||||
|
if (allow_prune) {
|
||||||
|
// Remove small disconnected components.
|
||||||
|
simplify_options |= SurfaceTool::SIMPLIFY_PRUNE;
|
||||||
|
}
|
||||||
|
|
||||||
if (deformable) {
|
if (deformable) {
|
||||||
// Improves appearance of deformable objects after deformation by using more regular tessellation.
|
// Improves appearance of deformable objects after deformation by using more regular tessellation.
|
||||||
simplify_options |= SurfaceTool::SIMPLIFY_REGULARIZE;
|
simplify_options |= SurfaceTool::SIMPLIFY_REGULARIZE;
|
||||||
|
@ -513,6 +519,15 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf
|
||||||
simplify_options,
|
simplify_options,
|
||||||
&step_error);
|
&step_error);
|
||||||
|
|
||||||
|
if (new_index_count == 0 && allow_prune) {
|
||||||
|
// If the best result the simplifier could arrive at with pruning enabled is 0 triangles, there might still be an opportunity
|
||||||
|
// to reduce the number of triangles further *without* completely decimating the mesh. It will be impossible to reach the target
|
||||||
|
// this way - if the target was reachable without going down to 0, the simplifier would have done it! - but we might still be able
|
||||||
|
// to get one more slightly lower level if we retry without pruning.
|
||||||
|
allow_prune = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulate error over iterations. Usually, it's correct to use step_error as is; however, on coarse LODs, we may start
|
// Accumulate error over iterations. Usually, it's correct to use step_error as is; however, on coarse LODs, we may start
|
||||||
// getting *smaller* relative error compared to the previous LOD. To make sure the error is monotonic and strictly increasing,
|
// getting *smaller* relative error compared to the previous LOD. To make sure the error is monotonic and strictly increasing,
|
||||||
// and to limit the switching (pop) distance, we ensure the error grows by an arbitrary factor each iteration.
|
// and to limit the switching (pop) distance, we ensure the error grows by an arbitrary factor each iteration.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue