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:
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user