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:
authorGermano Cavalcante <germano.costa@ig.com.br>2020-08-10 18:05:37 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2020-08-10 18:05:37 +0300
commitc0340ec89393055bbb0ba0432b9edb5d70b3711c (patch)
tree5c08023d69cdc266a560acd349d354af1e2c2224 /source/blender/blenkernel/intern
parentab2dbafd8b6263d85c86c83279f9f3e067b4f7e5 (diff)
Fix T78113: Random explosions of cloth with self collision
The problem is caused by a lack of prediction in the `isect_line_segment_tri_v3` that incorrectly confirms some intersections of coplanar segments to the triangle. The solution is to use another algorithm to detect intersections. This also resulted in a slight improvement in the performance: - 1min 17sec to 1min 6sec in my test file Differential Revision: https://developer.blender.org/D8500
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/collision.c41
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c3
2 files changed, 12 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 31d49dd4508..f358355912b 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -212,7 +212,6 @@ static float compute_collision_point_tri_tri(const float a1[3],
float dist = FLT_MAX;
float tmp_co1[3], tmp_co2[3];
float isect_a[3], isect_b[3];
- int isect_count = 0;
float tmp, tmp_vec[3];
float normal[3], cent[3];
bool backside = false;
@@ -226,38 +225,16 @@ static float compute_collision_point_tri_tri(const float a1[3],
copy_v3_v3(b[2], b3);
/* Find intersections. */
- for (int i = 0; i < 3; i++) {
- if (isect_line_segment_tri_v3(a[i], a[next_ind(i)], b[0], b[1], b[2], &tmp, NULL)) {
- interp_v3_v3v3(isect_a, a[i], a[next_ind(i)], tmp);
- isect_count++;
- }
- }
-
- if (isect_count == 0) {
- for (int i = 0; i < 3; i++) {
- if (isect_line_segment_tri_v3(b[i], b[next_ind(i)], a[0], a[1], a[2], &tmp, NULL)) {
- isect_count++;
- }
- }
- }
- else if (isect_count == 1) {
- for (int i = 0; i < 3; i++) {
- if (isect_line_segment_tri_v3(b[i], b[next_ind(i)], a[0], a[1], a[2], &tmp, NULL)) {
- interp_v3_v3v3(isect_b, b[i], b[next_ind(i)], tmp);
- break;
- }
- }
- }
+ int tri_a_edge_isect_count;
+ const bool is_intersecting = isect_tri_tri_v3_ex(
+ a, b, isect_a, isect_b, &tri_a_edge_isect_count);
/* Determine collision side. */
if (culling) {
normal_tri_v3(normal, b[0], b[1], b[2]);
mid_v3_v3v3v3(cent, b[0], b[1], b[2]);
- if (isect_count == 2) {
- backside = true;
- }
- else if (isect_count == 0) {
+ if (!is_intersecting) {
for (int i = 0; i < 3; i++) {
sub_v3_v3v3(tmp_vec, a[i], cent);
if (dot_v3v3(tmp_vec, normal) < 0.0f) {
@@ -266,12 +243,16 @@ static float compute_collision_point_tri_tri(const float a1[3],
}
}
}
+ else if (tri_a_edge_isect_count != 1) {
+ /* It is not Edge intersection. */
+ backside = true;
+ }
}
else if (use_normal) {
normal_tri_v3(normal, b[0], b[1], b[2]);
}
- if (isect_count == 1) {
+ if (tri_a_edge_isect_count == 1) {
/* Edge intersection. */
copy_v3_v3(r_a, isect_a);
copy_v3_v3(r_b, isect_b);
@@ -383,7 +364,7 @@ static float compute_collision_point_tri_tri(const float a1[3],
}
/* Closest edge. */
- if (isect_count == 0) {
+ if (!is_intersecting) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
isect_seg_seg_v3(a[i], a[next_ind(i)], b[j], b[next_ind(j)], tmp_co1, tmp_co2);
@@ -398,7 +379,7 @@ static float compute_collision_point_tri_tri(const float a1[3],
}
}
- if (isect_count == 0) {
+ if (!is_intersecting) {
sub_v3_v3v3(r_vec, r_a, r_b);
dist = sqrtf(dist);
}
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 72793919570..dc194f0077c 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -563,8 +563,7 @@ static bool bmbvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSE
}
}
- return (isect_tri_tri_epsilon_v3(
- UNPACK3(tri_a_co), UNPACK3(tri_b_co), ix_pair[0], ix_pair[1], data->epsilon) &&
+ return (isect_tri_tri_v3(UNPACK3(tri_a_co), UNPACK3(tri_b_co), ix_pair[0], ix_pair[1]) &&
/* if we share a vertex, check the intersection isn't a 'point' */
((verts_shared == 0) || (len_squared_v3v3(ix_pair[0], ix_pair[1]) > data->epsilon)));
}