BLI_math_geom: Separate the `isect_ray_seg_v3` from `dist_squared_ray_to_seg_v3`.
authorGermano <germano.costa@ig.com.br>
Thu, 17 May 2018 00:36:41 +0000 (21:36 -0300)
committerGermano <germano.costa@ig.com.br>
Thu, 17 May 2018 00:36:41 +0000 (21:36 -0300)
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/intern/math_geom.c

index 111450b64028b299d1314daf38cbc39aed47a918..f12ee2b3c69aa39951bdb4d2a4404fb7ba6adebf 100644 (file)
@@ -315,6 +315,11 @@ bool isect_ray_seg_v2(
         const float v0[2], const float v1[2],
         float *r_lambda, float *r_u);
 
+bool isect_ray_seg_v3(
+        const float ray_origin[3], const float ray_direction[3],
+        const float v0[3], const float v1[3],
+        float *r_lambda);
+
 /* point in polygon */
 bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_holes);
 bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_holes);
index 0e7358aa426548db9f932eafc8f0b378c7860512..a72cbb67883a810e74bf397a6237da282cdfd1eb 100644 (file)
@@ -570,6 +570,8 @@ float dist_squared_to_ray_v3(
        *r_depth = dot_v3v3(dvec, ray_direction);
        return len_squared_v3(dvec) - SQUARE(*r_depth);
 }
+
+
 /**
  * Find the closest point in a seg to a ray and return the distance squared.
  * \param r_point: Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel).
@@ -580,45 +582,38 @@ float dist_squared_ray_to_seg_v3(
         const float v0[3], const float v1[3],
         float r_point[3], float *r_depth)
 {
-       float a[3], t[3], n[3], lambda;
-       sub_v3_v3v3(a, v1, v0);
-       sub_v3_v3v3(t, v0, ray_origin);
-       cross_v3_v3v3(n, a, ray_direction);
-       const float nlen = len_squared_v3(n);
-
-       /* if (nlen == 0.0f) the lines are parallel,
-        * has no nearest point, only distance squared.*/
-       if (nlen == 0.0f) {
-               /* Calculate the distance to the point v0 then */
-               copy_v3_v3(r_point, v0);
-               *r_depth = dot_v3v3(t, ray_direction);
-       }
-       else {
-               float c[3], cray[3];
-               sub_v3_v3v3(c, n, t);
-               cross_v3_v3v3(cray, c, ray_direction);
-               lambda = dot_v3v3(cray, n) / nlen;
-               if (lambda <= 0) {
+       float lambda, depth;
+       if (isect_ray_seg_v3(
+               ray_origin, ray_direction, v0, v1, &lambda))
+       {
+               if (lambda <= 0.0f) {
                        copy_v3_v3(r_point, v0);
-
-                       *r_depth = dot_v3v3(t, ray_direction);
                }
-               else if (lambda >= 1) {
+               else if (lambda >= 1.0f) {
                        copy_v3_v3(r_point, v1);
-
-                       sub_v3_v3v3(t, v1, ray_origin);
-                       *r_depth = dot_v3v3(t, ray_direction);
                }
                else {
-                       madd_v3_v3v3fl(r_point, v0, a, lambda);
-
-                       sub_v3_v3v3(t, r_point, ray_origin);
-                       *r_depth = dot_v3v3(t, ray_direction);
+                       interp_v3_v3v3(r_point, v0, v1, lambda);
                }
        }
-       return len_squared_v3(t) - SQUARE(*r_depth);
+       else {
+               /* has no nearest point, only distance squared. */
+               /* Calculate the distance to the point v0 then */
+               copy_v3_v3(r_point, v0);
+       }
+
+       float dvec[3];
+       sub_v3_v3v3(dvec, r_point, ray_origin);
+       depth = dot_v3v3(dvec, ray_direction);
+
+       if (r_depth) {
+               *r_depth = depth;
+       }
+
+       return len_squared_v3(dvec) - SQUARE(depth);
 }
 
+
 /* Returns the coordinates of the nearest vertex and
  * the farthest vertex from a plane (or normal). */
 void aabb_get_near_far_from_plane(
@@ -1986,6 +1981,33 @@ bool isect_ray_seg_v2(
        return false;
 }
 
+
+bool isect_ray_seg_v3(
+        const float ray_origin[3], const float ray_direction[3],
+        const float v0[3], const float v1[3],
+        float *r_lambda)
+{
+       float a[3], t[3], n[3];
+       sub_v3_v3v3(a, v1, v0);
+       sub_v3_v3v3(t, v0, ray_origin);
+       cross_v3_v3v3(n, a, ray_direction);
+       const float nlen = len_squared_v3(n);
+
+       if (nlen == 0.0f) {
+               /* the lines are parallel.*/
+               return false;
+       }
+
+       float c[3], cray[3];
+       sub_v3_v3v3(c, n, t);
+       cross_v3_v3v3(cray, c, ray_direction);
+
+       *r_lambda = dot_v3v3(cray, n) / nlen;
+
+       return true;
+}
+
+
 /**
  * Check if a point is behind all planes.
  */