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:
Diffstat (limited to 'source/blender/blenlib/intern/math_geom.c')
-rw-r--r--source/blender/blenlib/intern/math_geom.c77
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;