Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-01-23 05:44:20 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-01-23 05:48:31 +0300
commit90293a8da375b785fa58d3f56de1b286072107c1 (patch)
tree04d39cc37ce4881232370e4c83513a4949e61f90
parent456e7be9d2ed4f6534995ef6754376649a815ea4 (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.
-rw-r--r--source/blender/blenlib/BLI_math_geom.h8
-rw-r--r--source/blender/blenlib/intern/math_geom.c107
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c5
-rw-r--r--source/blender/editors/space_view3d/drawobject.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c5
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;