Fix #120443: Knife tool loses precision on edges with high clip distance range

The previous algorithm for interpolating the vertices of an edge using
a lambda in screen space was heavily dependent on the resolution of the
projection matrix, leading to precision loss when the clip distance
range was high.

The updated algorithm now adjusts the lambda according to the
perspective before performing the interpolation, which improves
precision regardless of the clip distance range.
This commit is contained in:
Germano Cavalcante
2024-04-09 20:55:52 -03:00
parent 7226b52728
commit c9fa73a379

View File

@@ -3263,22 +3263,17 @@ static void knife_interp_v3_v3v3(const KnifeTool_OpData *kcd,
float r_co[3],
const float v1[3],
const float v2[3],
float lambda_ss)
const float lambda_ss)
{
if (kcd->is_ortho) {
interp_v3_v3v3(r_co, v1, v2, lambda_ss);
float lambda = lambda_ss;
if (!kcd->is_ortho) {
/* Adjust the lambda according to the perspective. */
float w1 = mul_project_m4_v3_zfac(kcd->vc.rv3d->persmat, v1);
float w2 = mul_project_m4_v3_zfac(kcd->vc.rv3d->persmat, v2);
lambda = (lambda_ss * w1) / (w2 + (lambda_ss * (w1 - w2)));
}
else {
/* Transform into screen-space, interp, then transform back. */
float v1_ss[3], v2_ss[3];
mul_v3_project_m4_v3(v1_ss, (float(*)[4])kcd->vc.rv3d->persmat, v1);
mul_v3_project_m4_v3(v2_ss, (float(*)[4])kcd->vc.rv3d->persmat, v2);
interp_v3_v3v3(r_co, v1_ss, v2_ss, lambda_ss);
mul_project_m4_v3((float(*)[4])kcd->vc.rv3d->persinv, r_co);
}
interp_v3_v3v3(r_co, v1, v2, lambda);
}
/* p is closest point on edge to the mouse cursor. */