From cf6be711e2a00bb0836a33c07cf6cd383ee15c4f Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 8 Dec 2021 23:47:26 -0300 Subject: Fix T93869: snap cursor may fail in orthographic view Float precision issues cause the `ED_view3d_win_to_3d_on_plane` to return a value even when the view ray is parallel to the plane. A more general solution might be desired in this case, as other areas that use `ED_view3d_win_to_3d_on_plane` might have the same problem. For now, just work around the problem for the snap cursor. --- .../editors/space_view3d/view3d_cursor_snap.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source/blender/editors/space_view3d') diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 27a90e04175..f5abba2c674 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -103,6 +103,12 @@ static SnapCursorDataIntern g_data_intern = { .box_dimensions = {1.0f, 1.0f, 1.0f}, .draw_point = true}}; +/** + * Dot products below this will be considered view aligned. + * In this case we can't usefully project the mouse cursor onto the plane. + */ +static const float eps_view_align = 1e-2f; + /** * Calculate a 3x3 orientation matrix from the surface under the cursor. */ @@ -715,14 +721,18 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, snap_elem &= ~data_intern->snap_elem_hidden; if (snap_elem == 0) { RegionView3D *rv3d = region->regiondata; - float plane[4]; - if (state->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) { - const float *plane_normal = omat[state->plane_axis]; + const float *plane_normal = omat[state->plane_axis]; + bool do_plane_isect = (state->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) && + (rv3d->is_persp || + (fabsf(dot_v3v3(plane_normal, rv3d->viewinv[2])) > eps_view_align)); + + if (do_plane_isect) { + float plane[4]; plane_from_point_normal_v3(plane, co_depth, plane_normal); + do_plane_isect = ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, rv3d->is_persp, co); } - if ((state->plane_depth == V3D_PLACE_DEPTH_CURSOR_VIEW) || - !ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, rv3d->is_persp, co)) { + if (!do_plane_isect) { ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co); } -- cgit v1.2.3