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 /source/blender/blenlib
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.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_math_geom.h8
-rw-r--r--source/blender/blenlib/intern/math_geom.c107
2 files changed, 60 insertions, 55 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;
}