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.c830
1 files changed, 421 insertions, 409 deletions
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 937bf8b1ae6..1afcf83bf73 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -231,9 +231,8 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float
if (c_len > FLT_EPSILON) {
return dot_v3v3(a, b) / c_len;
}
- else {
- return 0.0f;
- }
+
+ return 0.0f;
}
/********************************* Planes **********************************/
@@ -589,9 +588,8 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3],
if (flip) {
return min_ff(dist_a, dist_b);
}
- else {
- return max_ff(dist_a, dist_b);
- }
+
+ return max_ff(dist_a, dist_b);
}
/**
@@ -1146,9 +1144,8 @@ int isect_line_line_v2_point(
return ISECT_LINE_LINE_CROSS;
}
- else {
- return ISECT_LINE_LINE_COLINEAR;
- }
+
+ return ISECT_LINE_LINE_COLINEAR;
}
/* intersect Line-Line, floats */
@@ -1304,55 +1301,54 @@ int isect_seg_seg_v2_point_ex(const float v0[2],
/* out of segment intersection */
return -1;
}
- else {
- if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
- /* equal lines */
- float s20[2];
- float u_a, u_b;
-
- if (equals_v2v2(v0, v1)) {
- if (len_squared_v2v2(v2, v3) > square_f(eps)) {
- /* use non-point segment as basis */
- SWAP(const float *, v0, v2);
- SWAP(const float *, v1, v3);
-
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s30, v3, v0);
- }
- else { /* both of segments are points */
- if (equals_v2v2(v0, v2)) { /* points are equal */
- copy_v2_v2(r_vi, v0);
- return 1;
- }
- /* two different points */
- return -1;
- }
- }
+ if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
+ /* equal lines */
+ float s20[2];
+ float u_a, u_b;
- sub_v2_v2v2(s20, v2, v0);
+ if (equals_v2v2(v0, v1)) {
+ if (len_squared_v2v2(v2, v3) > square_f(eps)) {
+ /* use non-point segment as basis */
+ SWAP(const float *, v0, v2);
+ SWAP(const float *, v1, v3);
- u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
- u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
-
- if (u_a > u_b) {
- SWAP(float, u_a, u_b);
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s30, v3, v0);
}
+ else { /* both of segments are points */
+ if (equals_v2v2(v0, v2)) { /* points are equal */
+ copy_v2_v2(r_vi, v0);
+ return 1;
+ }
- if (u_a > endpoint_max || u_b < endpoint_min) {
- /* non-overlapping segments */
+ /* two different points */
return -1;
}
- else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
- /* one common point: can return result */
- madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
- return 1;
- }
}
- /* lines are collinear */
- return -1;
+ sub_v2_v2v2(s20, v2, v0);
+
+ u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
+ u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
+
+ if (u_a > u_b) {
+ SWAP(float, u_a, u_b);
+ }
+
+ if (u_a > endpoint_max || u_b < endpoint_min) {
+ /* non-overlapping segments */
+ return -1;
+ }
+ if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
+ /* one common point: can return result */
+ madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
+ return 1;
+ }
}
+
+ /* lines are collinear */
+ return -1;
}
int isect_seg_seg_v2_point(
@@ -1472,13 +1468,13 @@ int isect_line_sphere_v3(const float l1[3],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v3_v3v3fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1490,10 +1486,9 @@ int isect_line_sphere_v3(const float l1[3],
madd_v3_v3v3fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* keep in sync with isect_line_sphere_v3 */
@@ -1520,13 +1515,13 @@ int isect_line_sphere_v2(const float l1[2],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v2_v2v2fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1538,10 +1533,9 @@ int isect_line_sphere_v2(const float l1[2],
madd_v2_v2v2fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* point in polygon (keep float and int versions in sync) */
@@ -1957,34 +1951,32 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3],
if (UNLIKELY(det == 0.0f || !isfinite(det))) {
return false;
}
- else {
- /* Calculate scaled z-coordinates of vertices and use them to calculate
- * the hit distance.
- */
- const int sign_det = (float_as_int(det) & (int)0x80000000);
- const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
- const float sign_t = xor_fl(t, sign_det);
- if ((sign_t < 0.0f)
- /* Differ from Cycles, don't read r_lambda's original value
- * otherwise we won't match any of the other intersect functions here...
- * which would be confusing. */
+
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const int sign_det = (float_as_int(det) & (int)0x80000000);
+ const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
+ const float sign_t = xor_fl(t, sign_det);
+ if ((sign_t < 0.0f)
+ /* Differ from Cycles, don't read r_lambda's original value
+ * otherwise we won't match any of the other intersect functions here...
+ * which would be confusing. */
#if 0
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
- ) {
- return false;
- }
- else {
- /* Normalize u, v and t. */
- const float inv_det = 1.0f / det;
- if (r_uv) {
- r_uv[0] = u * inv_det;
- r_uv[1] = v * inv_det;
- }
- *r_lambda = t * inv_det;
- return true;
- }
+ ) {
+ return false;
}
+
+ /* Normalize u, v and t. */
+ const float inv_det = 1.0f / det;
+ if (r_uv) {
+ r_uv[0] = u * inv_det;
+ r_uv[1] = v * inv_det;
+ }
+ *r_lambda = t * inv_det;
+ return true;
}
bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3],
@@ -2102,7 +2094,7 @@ bool isect_ray_seg_v2(const float ray_origin[2],
det = cross_v2v2(ray_direction, s10);
if (det != 0.0f) {
const float v = cross_v2v2(v0_local, v1_local);
- float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
+ const float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
const float t = (dot_v2v2(p, ray_direction) / dot_v2v2(ray_direction, ray_direction));
if ((t >= 0.0f) == 0) {
@@ -2215,10 +2207,9 @@ bool isect_line_plane_v3(float r_isect_co[3],
madd_v3_v3v3fl(r_isect_co, l1, u, lambda);
return true;
}
- else {
- /* The segment is parallel to plane */
- return false;
- }
+
+ /* The segment is parallel to plane */
+ return false;
}
/**
@@ -2257,9 +2248,8 @@ bool isect_plane_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -2303,117 +2293,178 @@ bool isect_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
* Intersect two triangles.
*
- * \param r_i1, r_i2: Optional arguments to retrieve the overlapping edge between the 2 triangles.
+ * \param r_i1, r_i2: Retrieve the overlapping edge between the 2 triangles.
+ * \param r_tri_a_edge_isect_count: Indicates how many edges in the first triangle are intersected.
* \return true when the triangles intersect.
*
+ * \note If it exists, \a r_i1 will be a point on the edge of the 1st triangle.
* \note intersections between coplanar triangles are currently undetected.
*/
-bool isect_tri_tri_epsilon_v3(const float t_a0[3],
- const float t_a1[3],
- const float t_a2[3],
- const float t_b0[3],
- const float t_b1[3],
- const float t_b2[3],
- float r_i1[3],
- float r_i2[3],
- const float epsilon)
-{
- const float *tri_pair[2][3] = {{t_a0, t_a1, t_a2}, {t_b0, t_b1, t_b2}};
- float plane_a[4], plane_b[4];
- float plane_co[3], plane_no[3];
-
- BLI_assert((r_i1 != NULL) == (r_i2 != NULL));
-
- /* normalizing is needed for small triangles T46007 */
- normal_tri_v3(plane_a, UNPACK3(tri_pair[0]));
- normal_tri_v3(plane_b, UNPACK3(tri_pair[1]));
-
- plane_a[3] = -dot_v3v3(plane_a, t_a0);
- plane_b[3] = -dot_v3v3(plane_b, t_b0);
-
- if (isect_plane_plane_v3(plane_a, plane_b, plane_co, plane_no) &&
- (normalize_v3(plane_no) > epsilon)) {
- /**
- * Implementation note: its simpler to project the triangles onto the intersection plane
- * before intersecting their edges with the ray, defined by 'isect_plane_plane_v3'.
- * This way we can use 'line_point_factor_v3_ex' to see if an edge crosses 'co_proj',
- * then use the factor to calculate the world-space point.
- */
- struct {
- float min, max;
- } range[2] = {{FLT_MAX, -FLT_MAX}, {FLT_MAX, -FLT_MAX}};
- int t;
- float co_proj[3];
-
- closest_to_plane3_normalized_v3(co_proj, plane_no, plane_co);
-
- /* For both triangles, find the overlap with the line defined by the ray [co_proj, plane_no].
- * When the ranges overlap we know the triangles do too. */
- for (t = 0; t < 2; t++) {
- int j, j_prev;
- float tri_proj[3][3];
-
- closest_to_plane3_normalized_v3(tri_proj[0], plane_no, tri_pair[t][0]);
- closest_to_plane3_normalized_v3(tri_proj[1], plane_no, tri_pair[t][1]);
- closest_to_plane3_normalized_v3(tri_proj[2], plane_no, tri_pair[t][2]);
-
- for (j = 0, j_prev = 2; j < 3; j_prev = j++) {
- /* note that its important to have a very small nonzero epsilon here
- * otherwise this fails for very small faces.
- * However if its too small, large adjacent faces will count as intersecting */
- const float edge_fac = line_point_factor_v3_ex(
- co_proj, tri_proj[j_prev], tri_proj[j], 1e-10f, -1.0f);
- /* ignore collinear lines, they are either an edge shared between 2 tri's
- * (which runs along [co_proj, plane_no], but can be safely ignored).
- *
- * or a collinear edge placed away from the ray -
- * which we don't intersect with & can ignore. */
- if (UNLIKELY(edge_fac == -1.0f)) {
- /* pass */
- }
- /* Important to include 0.0f and 1.0f as one of the triangles vertices may be placed
- * exactly on the plane. In this case both it's edges will have a factor of 0 or 1,
- * but not be going through the plane. See T73566. */
- else if (edge_fac >= 0.0f && edge_fac <= 1.0f) {
- float ix_tri[3];
- float span_fac;
-
- interp_v3_v3v3(ix_tri, tri_pair[t][j_prev], tri_pair[t][j], edge_fac);
- /* the actual distance, since 'plane_no' is normalized */
- span_fac = dot_v3v3(plane_no, ix_tri);
-
- range[t].min = min_ff(range[t].min, span_fac);
- range[t].max = max_ff(range[t].max, span_fac);
- }
- }
+bool isect_tri_tri_v3_ex(const float tri_a[3][3],
+ const float tri_b[3][3],
+ float r_i1[3],
+ float r_i2[3],
+ int *r_tri_a_edge_isect_count)
+{
+ struct {
+ /* Factor that indicates the position of the intersection point on the line
+ * that intersects the planes of the triangles. */
+ float min, max;
+ /* Intersection point location. */
+ float loc[2][3];
+ } range[2];
+
+ float side[2][3];
+ float ba[3], bc[3], plane_a[4], plane_b[4];
+ *r_tri_a_edge_isect_count = 0;
+
+ sub_v3_v3v3(ba, tri_a[0], tri_a[1]);
+ sub_v3_v3v3(bc, tri_a[2], tri_a[1]);
+ cross_v3_v3v3(plane_a, ba, bc);
+ plane_a[3] = -dot_v3v3(tri_a[1], plane_a);
+ side[1][0] = plane_point_side_v3(plane_a, tri_b[0]);
+ side[1][1] = plane_point_side_v3(plane_a, tri_b[1]);
+ side[1][2] = plane_point_side_v3(plane_a, tri_b[2]);
+
+ if (!side[1][0] && !side[1][1] && !side[1][2]) {
+ /* Coplanar case is not supported. */
+ return false;
+ }
- if (range[t].min == FLT_MAX) {
- return false;
+ if ((side[1][0] && side[1][1] && side[1][2]) && (side[1][0] < 0.0f) == (side[1][1] < 0.0f) &&
+ (side[1][0] < 0.0f) == (side[1][2] < 0.0f)) {
+ /* All vertices of the 2nd triangle are positioned on the same side to the
+ * plane defined by the 1st triangle. */
+ return false;
+ }
+
+ sub_v3_v3v3(ba, tri_b[0], tri_b[1]);
+ sub_v3_v3v3(bc, tri_b[2], tri_b[1]);
+ cross_v3_v3v3(plane_b, ba, bc);
+ plane_b[3] = -dot_v3v3(tri_b[1], plane_b);
+ side[0][0] = plane_point_side_v3(plane_b, tri_a[0]);
+ side[0][1] = plane_point_side_v3(plane_b, tri_a[1]);
+ side[0][2] = plane_point_side_v3(plane_b, tri_a[2]);
+ if ((side[0][0] && side[0][1] && side[0][2]) && (side[0][0] < 0.0f) == (side[0][1] < 0.0f) &&
+ (side[0][0] < 0.0f) == (side[0][2] < 0.0f)) {
+ /* All vertices of the 1st triangle are positioned on the same side to the
+ * plane defined by the 2nd triangle. */
+ return false;
+ }
+
+ /* Direction of the line that intersects the planes of the triangles. */
+ float isect_dir[3];
+ cross_v3_v3v3(isect_dir, plane_a, plane_b);
+ for (int i = 0; i < 2; i++) {
+ const float(*tri)[3] = i == 0 ? tri_a : tri_b;
+ /* Rearrange the triangle so that the vertex that is alone on one side
+ * of the plane is located at index 1. */
+ int tri_i[3];
+ if ((side[i][0] && side[i][1]) && (side[i][0] < 0.0f) == (side[i][1] < 0.0f)) {
+ tri_i[0] = 1;
+ tri_i[1] = 2;
+ tri_i[2] = 0;
+ }
+ else if ((side[i][1] && side[i][2]) && (side[i][1] < 0.0f) == (side[i][2] < 0.0f)) {
+ tri_i[0] = 2;
+ tri_i[1] = 0;
+ tri_i[2] = 1;
+ }
+ else {
+ tri_i[0] = 0;
+ tri_i[1] = 1;
+ tri_i[2] = 2;
+ }
+
+ float dot_b = dot_v3v3(isect_dir, tri[tri_i[1]]);
+ range[i].min = dot_b;
+ range[i].max = dot_b;
+
+ float sidec = side[i][tri_i[1]];
+ if (sidec) {
+ float dot_a = dot_v3v3(isect_dir, tri[tri_i[0]]);
+ float dot_c = dot_v3v3(isect_dir, tri[tri_i[2]]);
+ float fac0 = sidec / (sidec - side[i][tri_i[0]]);
+ float fac1 = sidec / (sidec - side[i][tri_i[2]]);
+ float offset0 = fac0 * (dot_a - dot_b);
+ float offset1 = fac1 * (dot_c - dot_b);
+ if (offset0 > offset1) {
+ /* Sort min max. */
+ SWAP(float, offset0, offset1);
+ SWAP(float, fac0, fac1);
+ SWAP(int, tri_i[0], tri_i[2]);
}
+
+ range[i].min += offset0;
+ range[i].max += offset1;
+ interp_v3_v3v3(range[i].loc[0], tri[tri_i[1]], tri[tri_i[0]], fac0);
+ interp_v3_v3v3(range[i].loc[1], tri[tri_i[1]], tri[tri_i[2]], fac1);
+ }
+ else {
+ copy_v3_v3(range[i].loc[0], tri[tri_i[1]]);
+ copy_v3_v3(range[i].loc[1], tri[tri_i[1]]);
}
+ }
- if (((range[0].min > range[1].max) || (range[0].max < range[1].min)) == 0) {
- if (r_i1 && r_i2) {
- project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no);
- madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min));
- madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max));
+ if ((range[0].max >= range[1].min) && (range[0].min <= range[1].max)) {
+ /* The triangles intersect because they overlap on the intersection line.
+ * Now identify the two points of intersection that are in the middle to get the actual
+ * intersection between the triangles. (B--C from A--B--C--D) */
+ if (range[0].min >= range[1].min) {
+ copy_v3_v3(r_i1, range[0].loc[0]);
+ if (range[0].max <= range[1].max) {
+ copy_v3_v3(r_i2, range[0].loc[1]);
+ *r_tri_a_edge_isect_count = 2;
+ }
+ else {
+ copy_v3_v3(r_i2, range[1].loc[1]);
+ *r_tri_a_edge_isect_count = 1;
+ }
+ }
+ else {
+ if (range[0].max <= range[1].max) {
+ copy_v3_v3(r_i1, range[0].loc[1]);
+ copy_v3_v3(r_i2, range[1].loc[0]);
+ *r_tri_a_edge_isect_count = 1;
+ }
+ else {
+ copy_v3_v3(r_i1, range[1].loc[0]);
+ copy_v3_v3(r_i2, range[1].loc[1]);
}
-
- return true;
}
+ return true;
}
return false;
}
+bool isect_tri_tri_v3(const float t_a0[3],
+ const float t_a1[3],
+ const float t_a2[3],
+ const float t_b0[3],
+ const float t_b1[3],
+ const float t_b2[3],
+ float r_i1[3],
+ float r_i2[3])
+{
+ float tri_a[3][3], tri_b[3][3];
+ int dummy;
+ copy_v3_v3(tri_a[0], t_a0);
+ copy_v3_v3(tri_a[1], t_a1);
+ copy_v3_v3(tri_a[2], t_a2);
+ copy_v3_v3(tri_b[0], t_b0);
+ copy_v3_v3(tri_b[1], t_b1);
+ copy_v3_v3(tri_b[2], t_b2);
+ return isect_tri_tri_v3_ex(tri_a, tri_b, r_i1, r_i2, &dummy);
+}
+
/* -------------------------------------------------------------------- */
/** \name Tri-Tri Intersect 2D
*
@@ -2436,65 +2487,54 @@ static bool isect_tri_tri_v2_impl_vert(const float t_a0[2],
if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
if (line_point_side_v2(t_b2, t_b1, t_a2) <= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
if (line_point_side_v2(t_b2, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
@@ -2511,47 +2551,38 @@ static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
if (line_point_side_v2(t_a0, t_a1, t_b2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
+
+ return 0;
}
static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
@@ -2566,32 +2597,26 @@ static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
return 1;
}
- else {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
+
+ if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
bool isect_tri_tri_v2(const float t_a0[2],
@@ -2605,18 +2630,15 @@ bool isect_tri_tri_v2(const float t_a0[2],
if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b2, t_b1);
}
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
- }
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
}
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
/** \} */
@@ -2682,8 +2704,7 @@ int isect_aabb_planes_v3(const float (*planes)[4],
if (plane_point_side_v3(planes[i], bb_far) < 0.0f) {
return ISECT_AABB_PLANE_BEHIND_ANY;
}
- else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) &&
- (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
+ if ((ret != ISECT_AABB_PLANE_CROSS_ANY) && (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
ret = ISECT_AABB_PLANE_CROSS_ANY;
}
}
@@ -2967,7 +2988,7 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 0;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) <= epsilon)) {
+ if (UNLIKELY(fabsf(d) <= epsilon)) {
cross_v3_v3v3(cb, c, b);
mul_v3_fl(a, dot_v3v3(cb, ab) / div);
@@ -2977,34 +2998,33 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 1; /* one intersection only */
}
/* if not */
- else {
- float n[3], t[3];
- float v3t[3], v4t[3];
- sub_v3_v3v3(t, v1, v3);
- /* offset between both plane where the lines lies */
- cross_v3_v3v3(n, a, b);
- project_v3_v3v3(t, t, n);
+ float n[3], t[3];
+ float v3t[3], v4t[3];
+ sub_v3_v3v3(t, v1, v3);
- /* for the first line, offset the second line until it is coplanar */
- add_v3_v3v3(v3t, v3, t);
- add_v3_v3v3(v4t, v4, t);
+ /* offset between both plane where the lines lies */
+ cross_v3_v3v3(n, a, b);
+ project_v3_v3v3(t, t, n);
- sub_v3_v3v3(c, v3t, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4t, v3t);
+ /* for the first line, offset the second line until it is coplanar */
+ add_v3_v3v3(v3t, v3, t);
+ add_v3_v3v3(v4t, v4, t);
- cross_v3_v3v3(ab, a, b);
- cross_v3_v3v3(cb, c, b);
+ sub_v3_v3v3(c, v3t, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4t, v3t);
- mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
- add_v3_v3v3(r_i1, v1, a);
+ cross_v3_v3v3(ab, a, b);
+ cross_v3_v3v3(cb, c, b);
- /* for the second line, just substract the offset from the first intersection point */
- sub_v3_v3v3(r_i2, r_i1, t);
+ mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
+ add_v3_v3v3(r_i1, v1, a);
- return 2; /* two nearest points */
- }
+ /* for the second line, just subtract the offset from the first intersection point */
+ sub_v3_v3v3(r_i2, r_i1, t);
+
+ return 2; /* two nearest points */
}
int isect_line_line_v3(const float v1[3],
@@ -3047,31 +3067,29 @@ bool isect_line_line_strict_v3(const float v1[3],
return false;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) < epsilon)) {
+ if (UNLIKELY(fabsf(d) < epsilon)) {
return false;
}
- else {
- float f1, f2;
- cross_v3_v3v3(cb, c, b);
- cross_v3_v3v3(ca, c, a);
- f1 = dot_v3v3(cb, ab) / div;
- f2 = dot_v3v3(ca, ab) / div;
+ float f1, f2;
+ cross_v3_v3v3(cb, c, b);
+ cross_v3_v3v3(ca, c, a);
- if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
- mul_v3_fl(a, f1);
- add_v3_v3v3(vi, v1, a);
+ f1 = dot_v3v3(cb, ab) / div;
+ f2 = dot_v3v3(ca, ab) / div;
- if (r_lambda) {
- *r_lambda = f1;
- }
+ if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
+ mul_v3_fl(a, f1);
+ add_v3_v3v3(vi, v1, a);
- return true; /* intersection found */
- }
- else {
- return false;
+ if (r_lambda) {
+ *r_lambda = f1;
}
+
+ return true; /* intersection found */
}
+
+ return false;
}
/**
@@ -3237,15 +3255,14 @@ bool isect_ray_aabb_v3_simple(const float orig[3],
if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
return false;
}
- else {
- if (tmin) {
- *tmin = hit_dist[0];
- }
- if (tmax) {
- *tmax = hit_dist[1];
- }
- return true;
+
+ if (tmin) {
+ *tmin = hit_dist[0];
}
+ if (tmax) {
+ *tmax = hit_dist[1];
+ }
+ return true;
}
float closest_to_ray_v3(float r_close[3],
@@ -3463,7 +3480,7 @@ static bool point_in_slice(const float p[3],
/* adult sister defining the slice planes by the origin and the normal
* NOTE |normal| may not be 1 but defining the thickness of the slice */
-static bool point_in_slice_as(float p[3], float origin[3], float normal[3])
+static bool point_in_slice_as(const float p[3], const float origin[3], const float normal[3])
{
float h, rp[3];
sub_v3_v3v3(rp, p, origin);
@@ -3522,9 +3539,8 @@ bool isect_point_tri_v3(
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool clip_segment_v3_plane(
@@ -3547,7 +3563,7 @@ bool clip_segment_v3_plane(
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p2, p2);
madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div);
@@ -3559,7 +3575,7 @@ bool clip_segment_v3_plane(
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p1, p1);
madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div);
@@ -3598,7 +3614,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
t /= div;
if (t > p1_fac) {
p1_fac = t;
@@ -3613,7 +3629,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
t /= div;
if (t < p2_fac) {
p2_fac = t;
@@ -3797,8 +3813,8 @@ int barycentric_inside_triangle_v2(const float w[3])
if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
return 1;
}
- else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
- IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
+ if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
+ IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
return 2;
}
@@ -4095,68 +4111,67 @@ int interp_sparse_array(float *array, const int list_size, const float skipval)
if (found_valid == 0) {
return -1;
}
- else if (found_invalid == 0) {
+ if (found_invalid == 0) {
return 0;
}
- else {
- /* found invalid depths, interpolate */
- float valid_last = skipval;
- int valid_ofs = 0;
- float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ /* found invalid depths, interpolate */
+ float valid_last = skipval;
+ int valid_ofs = 0;
- int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
- int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+ float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- array_up[i] = valid_last;
- ofs_tot_up[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
+ int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ array_up[i] = valid_last;
+ ofs_tot_up[i] = ++valid_ofs;
}
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
+ }
+ }
- valid_last = skipval;
- valid_ofs = 0;
+ valid_last = skipval;
+ valid_ofs = 0;
- for (i = list_size - 1; i >= 0; i--) {
- if (array[i] == skipval) {
- array_down[i] = valid_last;
- ofs_tot_down[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ for (i = list_size - 1; i >= 0; i--) {
+ if (array[i] == skipval) {
+ array_down[i] = valid_last;
+ ofs_tot_down[i] = ++valid_ofs;
}
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
+ }
+ }
- /* now blend */
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- if (array_up[i] != skipval && array_down[i] != skipval) {
- array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
- (array_down[i] * (float)ofs_tot_up[i])) /
- (float)(ofs_tot_down[i] + ofs_tot_up[i]);
- }
- else if (array_up[i] != skipval) {
- array[i] = array_up[i];
- }
- else if (array_down[i] != skipval) {
- array[i] = array_down[i];
- }
+ /* now blend */
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ if (array_up[i] != skipval && array_down[i] != skipval) {
+ array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
+ (array_down[i] * (float)ofs_tot_up[i])) /
+ (float)(ofs_tot_down[i] + ofs_tot_up[i]);
+ }
+ else if (array_up[i] != skipval) {
+ array[i] = array_up[i];
+ }
+ else if (array_down[i] != skipval) {
+ array[i] = array_down[i];
}
}
+ }
- MEM_freeN(array_up);
- MEM_freeN(array_down);
+ MEM_freeN(array_up);
+ MEM_freeN(array_down);
- MEM_freeN(ofs_tot_up);
- MEM_freeN(ofs_tot_down);
- }
+ MEM_freeN(ofs_tot_up);
+ MEM_freeN(ofs_tot_down);
return 1;
}
@@ -4279,7 +4294,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
@@ -4364,7 +4379,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
@@ -4647,17 +4662,15 @@ float resolve_quad_u_v2(const float st[2],
if (IS_ZERO(fDen) == 0) {
return (float)(a / fDen);
}
- else {
- return 0.0f;
- }
- }
- else {
- const double desc_sq = b * b - a * fC;
- const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
- const double s = signed_area > 0 ? (-1.0) : 1.0;
- return (float)(((a - b) + s * desc) / denom);
+ return 0.0f;
}
+
+ const double desc_sq = b * b - a * fC;
+ const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
+ const double s = signed_area > 0 ? (-1.0) : 1.0;
+
+ return (float)(((a - b) + s * desc) / denom);
}
#undef IS_ZERO
@@ -4959,7 +4972,7 @@ void projmat_from_subregion(const float projmat[4][4],
}
}
-static void i_multmatrix(float icand[4][4], float Vm[4][4])
+static void i_multmatrix(const float icand[4][4], float Vm[4][4])
{
int row, col;
float temp[4][4];
@@ -5155,7 +5168,7 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3])
{
- float target[3] = {0.0f, 0.0f, 1.0f};
+ const float target[3] = {0.0f, 0.0f, 1.0f};
float axis[3];
cross_v3_v3v3(axis, no, target);
@@ -6139,17 +6152,16 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
/* no angle difference (use fallback, length wont make any difference) */
return (1.0f / 3.0f) * 0.75f;
}
- else if (tan_dot < -1.0f + eps) {
+ if (tan_dot < -1.0f + eps) {
/* parallele tangents (half-circle) */
return (1.0f / 2.0f);
}
- else {
- /* non-aligned tangents, calculate handle length */
- const float angle = acosf(tan_dot) / 2.0f;
- /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
- const float angle_sin = sinf(angle);
- const float angle_cos = cosf(angle);
- return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
- }
+ /* non-aligned tangents, calculate handle length */
+ const float angle = acosf(tan_dot) / 2.0f;
+
+ /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
+ const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
}