Fix #103499: View Pan not working for smaller clip start value

Changing the computation to be split in 2 steps (one for each matrix)
fixes the issue.

However, it seems this function is used in a lot of places which
I am not sure if this has the potential to slow down some other
operations. So I will simply add a precise version of the function
for now.

Pull Request: https://projects.blender.org/blender/blender/pulls/141327
This commit is contained in:
Clément Foucault
2025-07-02 10:59:12 +02:00
committed by Clément Foucault
parent 0df7b4daed
commit 06dff0151d
3 changed files with 20 additions and 9 deletions

View File

@@ -706,11 +706,13 @@ bool ED_view3d_win_to_3d_on_plane_int(
* \param zfac: The depth result typically calculated by #ED_view3d_calc_zfac
* (see its doc-string for details).
* \param r_out: The resulting world-space delta.
* \param precise: Use a more precise calculation but increases the cost of this function.
*/
void ED_view3d_win_to_delta(const ARegion *region,
const float xy_delta[2],
float zfac,
float r_out[3]);
float r_out[3],
bool precise = false);
/**
* Calculate a 3D origin from 2D window coordinates.
* \note Orthographic views have a less obvious origin,

View File

@@ -1034,7 +1034,7 @@ void viewmove_apply(ViewOpsData *vod, int x, int y)
else {
float dvec[3];
ED_view3d_win_to_delta(vod->region, event_ofs, vod->init.zfac, dvec);
ED_view3d_win_to_delta(vod->region, event_ofs, vod->init.zfac, dvec, true);
sub_v3_v3(vod->rv3d->ofs, dvec);

View File

@@ -671,10 +671,8 @@ bool ED_view3d_win_to_3d_on_plane_with_fallback(const ARegion *region,
return true;
}
void ED_view3d_win_to_delta(const ARegion *region,
const float xy_delta[2],
const float zfac,
float r_out[3])
void ED_view3d_win_to_delta(
const ARegion *region, const float xy_delta[2], const float zfac, float r_out[3], bool precise)
{
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
float dx, dy;
@@ -682,9 +680,20 @@ void ED_view3d_win_to_delta(const ARegion *region,
dx = 2.0f * xy_delta[0] * zfac / region->winx;
dy = 2.0f * xy_delta[1] * zfac / region->winy;
r_out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
r_out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
r_out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
if (precise) {
/* Fix for operators that needs more precision. (see #103499) */
float wininv[4][4];
invert_m4_m4(wininv, rv3d->winmat);
r_out[0] = (wininv[0][0] * dx + wininv[1][0] * dy);
r_out[1] = (wininv[0][1] * dx + wininv[1][1] * dy);
r_out[2] = (wininv[0][2] * dx + wininv[1][2] * dy);
mul_mat3_m4_v3(rv3d->viewinv, r_out);
}
else {
r_out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
r_out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
r_out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
}
}
void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float r_out[3])