BLI_math_geom: Separate the isect_ray_seg_v3 from dist_squared_ray_to_seg_v3.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user