diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_geom.c')
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index fc1d0e99a30..ac9534dac25 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -304,6 +304,15 @@ float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float return len_v3v3(closest, v1); } +float dist_to_line_v3(const float v1[3], const float v2[3], const float v3[3]) +{ + float closest[3]; + + closest_to_line_v3(closest, v1, v2, v3); + + return len_v3v3(closest, v1); +} + /* Adapted from "Real-Time Collision Detection" by Christer Ericson, * published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc. * @@ -1957,7 +1966,48 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, } } -/****************************** Interpolation ********************************/ +/****************************** Axis Utils ********************************/ + +/** + * \brief Normal to x,y matrix + * + * Creates a 3x3 matrix from a normal. + * This matrix can be applied to vectors so their 'z' axis runs along \a normal. + * In practice it means you can use x,y as 2d coords. \see + * + * \param r_mat The matrix to return. + * \param normal A unit length vector. + */ +bool axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]) +{ + float up[3] = {0.0f, 0.0f, 1.0f}; + float axis[3]; + float angle; + + /* double check they are normalized */ +#ifdef DEBUG + float test; + BLI_assert(fabsf((test = len_squared_v3(normal)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f); +#endif + + cross_v3_v3v3(axis, normal, up); + angle = saacos(dot_v3v3(normal, up)); + + if (angle >= FLT_EPSILON) { + if (len_squared_v3(axis) < FLT_EPSILON) { + axis[0] = 0.0f; + axis[1] = 1.0f; + axis[2] = 0.0f; + } + + axis_angle_to_mat3(r_mat, axis, angle); + return true; + } + else { + unit_m3(r_mat); + return false; + } +} /* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */ void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]) @@ -1983,6 +2033,9 @@ float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) else { *r_axis_a = 1; *r_axis_b = 2; return xn; } } + +/****************************** Interpolation ********************************/ + static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j) { return 0.5f * ((v1[i] - v2[i]) * (v2[j] - v3[j]) + (v1[j] - v2[j]) * (v3[i] - v2[i])); @@ -2378,7 +2431,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ t2 = mean_value_half_tan_v3(co, vmid, vnext); len = len_v3v3(co, vmid); - w[i] = (len != 0.0f)? (t1 + t2) / len: 0.0f; + w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f; totweight += w[i]; } @@ -2430,7 +2483,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ t2 = mean_value_half_tan_v2(co, vmid, vnext); len = len_v2v2(co, vmid); - w[i] = (len != 0.0f)? (t1 + t2) / len: 0.0f; + w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f; totweight += w[i]; } @@ -3526,7 +3579,7 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) { float nor[3], nor1[3], nor2[3], vec[4][2]; - int axis_a, axis_b; + float mat[3][3]; /* define projection, do both trias apart, quad is undefined! */ @@ -3543,18 +3596,14 @@ int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], c } add_v3_v3v3(nor, nor1, nor2); + normalize_v3(nor); - axis_dominant_v3(&axis_a, &axis_b, nor); - - vec[0][0] = v1[axis_a]; - vec[0][1] = v1[axis_b]; - vec[1][0] = v2[axis_a]; - vec[1][1] = v2[axis_b]; + axis_dominant_v3_to_m3(mat, nor); - vec[2][0] = v3[axis_a]; - vec[2][1] = v3[axis_b]; - vec[3][0] = v4[axis_a]; - vec[3][1] = v4[axis_b]; + mul_v2_m3v3(vec[0], mat, v1); + mul_v2_m3v3(vec[1], mat, v2); + mul_v2_m3v3(vec[2], mat, v3); + mul_v2_m3v3(vec[3], mat, v4); /* linetests, the 2 diagonals have to instersect to be convex */ return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE; |