From 1501c3adad13c3b0ae4f02a84f1be2c84f6f1db2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Nov 2020 17:07:04 +1100 Subject: Add Object Tool: support placing objects in orthographic axis views When an projecting onto a plane that is orthogonal to the views Z axis, project onto a view aligned axis then map it back to the original plane. see: ED_view3d_win_to_3d_on_plane_with_fallback Since the depth can't be properly visualized in 3D, display a 2D so it's possible to to tell the depth from the cursor motion. --- .../blender/editors/space_view3d/view3d_project.c | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source/blender/editors/space_view3d/view3d_project.c') diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index 0afa44b6f4f..58538fc3ecb 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -632,6 +632,48 @@ bool ED_view3d_win_to_3d_on_plane_int(const ARegion *region, return ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, do_clip, r_out); } +/** + * A wrapper for #ED_view3d_win_to_3d_on_plane that projects onto \a plane_fallback + * then maps this back to \a plane. + * + * This is intended to be used when \a plane is orthogonal to the views Z axis where + * projecting the \a mval doesn't work well (or fail completely when exactly aligned). + */ +bool ED_view3d_win_to_3d_on_plane_with_fallback(const ARegion *region, + const float plane[4], + const float mval[2], + const bool do_clip, + const float plane_fallback[4], + float r_out[3]) +{ + float isect_co[3], isect_no[3]; + if (!isect_plane_plane_v3(plane, plane_fallback, isect_co, isect_no)) { + return false; + } + normalize_v3(isect_no); + + /* Construct matrix to transform `plane_fallback` onto `plane`. */ + float mat4[4][4]; + { + float mat3[3][3]; + rotation_between_vecs_to_mat3(mat3, plane, plane_fallback); + copy_m4_m3(mat4, mat3); + transform_pivot_set_m4(mat4, isect_co); + } + + float co[3]; + if (!ED_view3d_win_to_3d_on_plane(region, plane_fallback, mval, do_clip, co)) { + return false; + } + mul_m4_v3(mat4, co); + + /* While the point is already on the plane, there may be some small in-precision + * so ensure the point is exactly on the plane. */ + closest_to_plane_v3(r_out, plane, co); + + return true; +} + /** * Calculate a 3d difference vector from 2d window offset. * note that #ED_view3d_calc_zfac() must be called first to determine -- cgit v1.2.3