From 416064cd5b6d3df577e71e301599fba36264f19b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Apr 2016 11:45:37 +1000 Subject: Math Lib: ray_point_factor_v3 functions Gives a bit better precision than creating a line in some cases, use for ED_view3d_win_to_3d. --- source/blender/blenlib/BLI_math_geom.h | 6 +++++ source/blender/blenlib/intern/math_geom.c | 16 +++++++++++ .../blender/editors/space_view3d/view3d_project.c | 31 +++++++++++++--------- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 7836f12a03e..45edaca544d 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -127,6 +127,12 @@ void closest_to_plane3_v3(float r_close[3], const float plane[3], const float pt /* Set 'r' to the point in triangle (t1, t2, t3) closest to point 'p' */ void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3], const float t2[3], const float t3[3]); +float ray_point_factor_v3_ex( + const float p[3], const float ray_origin[3], const float ray_direction[3], + const float epsilon, const float fallback); +float ray_point_factor_v3( + const float p[3], const float ray_origin[3], const float ray_direction[3]); + float line_point_factor_v3_ex( const float p[3], const float l1[3], const float l2[3], const float epsilon, const float fallback); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 482709e572f..49b52690a5b 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2506,6 +2506,22 @@ float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], return lambda; } +float ray_point_factor_v3_ex( + const float p[3], const float ray_origin[3], const float ray_direction[3], + const float epsilon, const float fallback) +{ + float p_relative[3]; + sub_v3_v3v3(p_relative, p, ray_origin); + const float dot = dot_v3v3(ray_direction, ray_direction); + return (fabsf(dot) > epsilon) ? (dot_v3v3(ray_direction, p_relative) / dot) : fallback; +} + +float ray_point_factor_v3( + const float p[3], const float ray_origin[3], const float ray_direction[3]) +{ + return ray_point_factor_v3_ex(p, ray_origin, ray_direction, 0.0f, 0.0f); +} + /** * A simplified version of #closest_to_line_v3 * we only need to return the ``lambda`` diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index c364148c9f1..cbabc8e56de 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -481,19 +481,22 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float { RegionView3D *rv3d = ar->regiondata; - float line_sta[3]; - float line_end[3]; + float ray_origin[3]; + float ray_direction[3]; + float lambda; if (rv3d->is_persp) { - float mousevec[3], lambda; - copy_v3_v3(line_sta, rv3d->viewinv[3]); - ED_view3d_win_to_vector(ar, mval, mousevec); - add_v3_v3v3(line_end, line_sta, mousevec); + float plane[4]; + + copy_v3_v3(ray_origin, rv3d->viewinv[3]); + ED_view3d_win_to_vector(ar, mval, ray_direction); /* note, we could use isect_line_plane_v3() however we want the intersection to be infront of the * view no matter what, so apply the unsigned factor instead */ - lambda = line_plane_factor_v3(depth_pt, rv3d->viewinv[2], line_sta, line_end); - interp_v3_v3v3(out, line_sta, line_end, fabsf(lambda)); + plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]); + + isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false); + lambda = fabsf(lambda); } else { float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; @@ -504,13 +507,15 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float dx += rv3d->camdx * zoomfac; dy += rv3d->camdy * zoomfac; } - line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; - line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; - line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; + ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; + ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; + ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; - add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); - closest_to_line_v3(out, depth_pt, line_sta, line_end); + copy_v3_v3(ray_direction, rv3d->viewinv[2]); + lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction); } + + madd_v3_v3v3fl(out, ray_origin, ray_direction, lambda); } void ED_view3d_win_to_3d_int(const ARegion *ar, const float depth_pt[3], const int mval[2], float out[3]) -- cgit v1.2.3