diff options
author | Hans Goudey <h.goudey@me.com> | 2022-08-31 16:07:51 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-08-31 16:15:09 +0300 |
commit | 3ecb21346248014aff621ec3b97ccbc1e7774653 (patch) | |
tree | b571a51b93d61efc01bf8a75a74ecade8e463d16 /source/blender/geometry/intern/reverse_uv_sampler.cc | |
parent | b5af7f967e6d5d2e7432d6efa2f47050a5bfc576 (diff) | |
parent | 773241add9d876aa0b4ba011745208f61b53a4e2 (diff) |
Merge branch 'master' into refactor-mesh-material-index-genericrefactor-mesh-material-index-generic
Diffstat (limited to 'source/blender/geometry/intern/reverse_uv_sampler.cc')
-rw-r--r-- | source/blender/geometry/intern/reverse_uv_sampler.cc | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/source/blender/geometry/intern/reverse_uv_sampler.cc b/source/blender/geometry/intern/reverse_uv_sampler.cc index 39fec40333c..f66e4a3ac2e 100644 --- a/source/blender/geometry/intern/reverse_uv_sampler.cc +++ b/source/blender/geometry/intern/reverse_uv_sampler.cc @@ -50,6 +50,11 @@ ReverseUVSampler::Result ReverseUVSampler::sample(const float2 &query_uv) const float3 best_bary_weights; const MLoopTri *best_looptri; + /* The distance to an edge that is allowed to be inside or outside the triangle. Without this, + * the lookup can fail for floating point accuracy reasons when the uv is almost exact on an + * edge. */ + const float edge_epsilon = 0.00001f; + for (const int looptri_index : looptri_indices) { const MLoopTri &looptri = looptris_[looptri_index]; const float2 &uv_0 = uv_map_[looptri.tri[0]]; @@ -68,8 +73,12 @@ ReverseUVSampler::Result ReverseUVSampler::sample(const float2 &query_uv) const const float dist = MAX3(x_dist, y_dist, z_dist); if (dist <= 0.0f && best_dist <= 0.0f) { - /* The uv sample is in multiple triangles. */ - return Result{ResultType::Multiple}; + const float worse_dist = std::max(dist, best_dist); + /* Allow ignoring multiple triangle intersections if the uv is almost exactly on an edge. */ + if (worse_dist < -edge_epsilon) { + /* The uv sample is in multiple triangles. */ + return Result{ResultType::Multiple}; + } } if (dist < best_dist) { @@ -79,8 +88,9 @@ ReverseUVSampler::Result ReverseUVSampler::sample(const float2 &query_uv) const } } - /* Allow for a small epsilon in case the uv is on th edge. */ - if (best_dist < 0.00001f) { + /* Allow using the closest (but not intersecting) triangle if the uv is almost exactly on an + * edge. */ + if (best_dist < edge_epsilon) { return Result{ResultType::Ok, best_looptri, math::clamp(best_bary_weights, 0.0f, 1.0f)}; } |