diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-01-23 05:44:20 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-01-23 05:48:31 +0300 |
commit | 90293a8da375b785fa58d3f56de1b286072107c1 (patch) | |
tree | 04d39cc37ce4881232370e4c83513a4949e61f90 /source | |
parent | 456e7be9d2ed4f6534995ef6754376649a815ea4 (diff) |
Math Lib: optimize segment-plane clipping
Calculate the clipped min/max factor along the segment,
only applying to the coordinates at the end (will give better precision too).
Also make split input/output args.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 8 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 107 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_project.c | 5 |
5 files changed, 70 insertions, 65 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index e3a8f975844..06412835936 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -288,8 +288,12 @@ bool isect_ray_aabb_v3( bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const float radius, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float ipoint[3]); -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); +bool clip_segment_v3_plane( + const float p1[3], const float p2[3], const float plane[4], + float r_p1[3], float r_p2[3]); +bool clip_segment_v3_plane_n( + const float p1[3], const float p2[3], const float plane_array[][4], const int plane_tot, + float r_p1[3], float r_p2[3]); void plot_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), void *userData); void fill_poly_v2i_n( diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 367cf74a8a2..a104487f8d1 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2476,9 +2476,12 @@ bool isect_point_tri_v3( } } -bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4]) +bool clip_segment_v3_plane( + const float p1[3], const float p2[3], + const float plane[4], + float r_p1[3], float r_p2[3]) { - float dp[3], div, t, pc[3]; + float dp[3], div; sub_v3_v3v3(dp, p2, p1); div = dot_v3v3(dp, plane); @@ -2486,98 +2489,96 @@ bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4]) if (div == 0.0f) /* parallel */ return true; - t = -plane_point_side_v3(plane, p1) / div; + float t = -plane_point_side_v3(plane, p1); if (div > 0.0f) { /* behind plane, completely clipped */ - if (t >= 1.0f) { - zero_v3(p1); - zero_v3(p2); + if (t >= div) { return false; } - - /* intersect plane */ - if (t > 0.0f) { - madd_v3_v3v3fl(pc, p1, dp, t); - copy_v3_v3(p1, pc); + else if (t > 0.0f) { + const float p1_copy[3] = {UNPACK3(p1)}; + copy_v3_v3(r_p2, p2); + madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div); return true; } - - return true; } else { /* behind plane, completely clipped */ - if (t <= 0.0f) { - zero_v3(p1); - zero_v3(p2); + if (t >= 0.0f) { return false; } - - /* intersect plane */ - if (t < 1.0f) { - madd_v3_v3v3fl(pc, p1, dp, t); - copy_v3_v3(p2, pc); + else if (t > div) { + const float p1_copy[3] = {UNPACK3(p1)}; + copy_v3_v3(r_p1, p1); + madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div); return true; } - - return true; } + + /* incase input/output values match (above also) */ + const float p1_copy[3] = {UNPACK3(p1)}; + copy_v3_v3(r_p2, p2); + copy_v3_v3(r_p1, p1_copy); + return true; } -bool clip_segment_v3_plane_n(float r_p1[3], float r_p2[3], float plane_array[][4], const int plane_tot) +bool clip_segment_v3_plane_n( + const float p1[3], const float p2[3], + const float plane_array[][4], const int plane_tot, + float r_p1[3], float r_p2[3]) { /* 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); + float p1_fac = 0.0f, p2_fac = 1.0f; + float dp[3]; sub_v3_v3v3(dp, p2, p1); - copy_v3_v3(dp_orig, dp); - for (i = 0; i < plane_tot; i++) { + for (int 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 = -plane_point_side_v3(plane, p1) / div; + float t = -plane_point_side_v3(plane, p1); if (div > 0.0f) { - /* clip a */ - if (t >= 1.0f) { + /* clip p1 lower bounds */ + if (t >= div) { 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 (t > 0.0f) { + t /= div; + if (t > p1_fac) { + p1_fac = t; + if (p1_fac > p2_fac) { + return false; + } } } } else if (div < 0.0f) { - /* clip b */ - if (t <= 0.0f) { + /* clip p2 upper bounds */ + 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; + else if (t > div) { + t /= div; + if (t < p2_fac) { + p2_fac = t; + if (p1_fac > p2_fac) { + return false; + } } } } } } - copy_v3_v3(r_p1, p1); - copy_v3_v3(r_p2, p2); + /* incase input/output values match */ + const float p1_copy[3] = {UNPACK3(p1)}; + + madd_v3_v3v3fl(r_p1, p1_copy, dp, p1_fac); + madd_v3_v3v3fl(r_p2, p1_copy, dp, p2_fac); + return true; } diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 3cef5478503..89d3cf7db05 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1439,7 +1439,10 @@ static bool point_is_visible( copy_v3_v3(view_clip[0], p_ofs); madd_v3_v3v3fl(view_clip[1], p_ofs, view, dist); - if (clip_segment_v3_plane_n(view_clip[0], view_clip[1], kcd->vc.rv3d->clip_local, 6)) { + if (clip_segment_v3_plane_n( + view_clip[0], view_clip[1], kcd->vc.rv3d->clip_local, 6, + view_clip[0], view_clip[1])) + { dist = len_v3v3(p_ofs, view_clip[1]); } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2a09b31c737..3f29f7772b9 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3311,10 +3311,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe copy_v3_v3(v2, eed->v2->co); } - copy_v3_v3(v1_clip, v1); - copy_v3_v3(v2_clip, v2); - - if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) { + if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { if (do_edge_textpair) { interp_v3_v3v3(vmid, v1, v2, edge_texpair_sep); @@ -3378,10 +3375,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe copy_v3_v3(v2, eed->v2->co); } - copy_v3_v3(v1_clip, v1); - copy_v3_v3(v2_clip, v2); - - if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) { + if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { float no_a[3], no_b[3]; float angle; diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index ba0626c58ea..c364148c9f1 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -348,7 +348,10 @@ static void view3d_win_to_ray_segment(const ARegion *ar, View3D *v3d, const floa BLI_INLINE bool view3d_clip_segment(RegionView3D *rv3d, float ray_start[3], float ray_end[3]) { - if ((rv3d->rflag & RV3D_CLIPPING) && !clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6)) { + if ((rv3d->rflag & RV3D_CLIPPING) && + (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6, + ray_start, ray_end) == false)) + { return false; } return true; |