BLI_math_geom: Separate the isect_ray_seg_v3 from dist_squared_ray_to_seg_v3.

This commit is contained in:
Germano
2018-05-16 21:36:41 -03:00
parent d038f4651e
commit 4b18858660
2 changed files with 57 additions and 30 deletions

View 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);

View 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.
*/