diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-04-22 23:39:10 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-04-22 23:39:10 +0400 |
commit | 556705f84efcb225ec1767e11167537a02553f2a (patch) | |
tree | 0bae9ac5ebb960b9845b7428b51a61cea28e4ca4 /source | |
parent | bf51e807991b004de079736dfaeae6b642eaae4a (diff) |
add clip_segment_v3_plane_n() to clip a line segment to planes (as used for view clipping).
use in ED_view3d_win_to_segment_clip() and fix error, was clipping by only 4 planes rather then 6.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 59 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_project.c | 16 |
3 files changed, 62 insertions, 16 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index d24d5fb8c38..ad846823669 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -170,7 +170,8 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo int isect_axial_line_tri_v3(const int axis, const float co1[3], const float co2[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda); -int clip_line_plane(float p1[3], float p2[3], const float plane[4]); +bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4]); +bool clip_segment_v3_plane_n(float p1[3], float p2[3], float plane_array[][4], const int plane_tot); void plot_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), void *userData); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 9cf83231f24..56921797659 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1963,7 +1963,7 @@ int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2 return 1; } -int clip_line_plane(float p1[3], float p2[3], const float plane[4]) +bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4]) { float dp[3], div, t, pc[3]; @@ -2011,6 +2011,63 @@ int clip_line_plane(float p1[3], float p2[3], const float plane[4]) } } +bool clip_segment_v3_plane_n(float r_p1[3], float r_p2[3], float plane_array[][4], const int plane_tot) +{ + /* intersect from both directions */ + float p1[3], p2[3], dp[3], dp_orig[3]; + int i; + copy_v3_v3(p1, r_p1); + copy_v3_v3(p2, r_p2); + + sub_v3_v3v3(dp, p2, p1); + copy_v3_v3(dp_orig, dp); + + for (i = 0; i < plane_tot; i++) { + const float *plane = plane_array[i]; + const float div = dot_v3v3(dp, plane); + + if (div != 0.0f) { + const float t = -(dot_v3v3(p1, plane) + plane[3]) / div; + if (div > 0.0f) { + /* clip a */ + if (t >= 1.0f) { + return false; + } + + /* intersect plane */ + if (t > 0.0f) { + madd_v3_v3v3fl(p1, p1, dp, t); + /* recalc direction and test for flipping */ + sub_v3_v3v3(dp, p2, p1); + if (dot_v3v3(dp, dp_orig) < 0.0f) { + return false; + } + } + } + else if (div < 0.0f) { + /* clip b */ + if (t <= 0.0f) { + return false; + } + + /* intersect plane */ + if (t < 1.0f) { + madd_v3_v3v3fl(p2, p1, dp, t); + /* recalc direction and test for flipping */ + sub_v3_v3v3(dp, p2, p1); + if (dot_v3v3(dp, dp_orig) < 0.0f) { + return false; + } + } + } + } + } + + copy_v3_v3(r_p1, p1); + copy_v3_v3(r_p2, p2); + return true; +} + void plot_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), void *userData) { int x1 = p1[0]; diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index ccfbf964d36..bb5e6802473 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -522,21 +522,9 @@ bool ED_view3d_win_to_segment_clip(const ARegion *ar, View3D *v3d, const float m /* clipping */ if (rv3d->rflag & RV3D_CLIPPING) { - /* if the ray is totally clipped, - * restore the original values but return false - * caller can choose what to do */ - float tray_start[3] = {UNPACK3(ray_start)}; - float tray_end[3] = {UNPACK3(ray_end)}; - int a; - for (a = 0; a < 4; a++) { - if (clip_line_plane(tray_start, tray_end, rv3d->clip[a]) == false) { - return false; - } + if (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6) == false) { + return false; } - - /* copy in clipped values */ - copy_v3_v3(ray_start, tray_start); - copy_v3_v3(ray_end, tray_end); } return true; |