[Bf-blender-cvs] [e1df731c91b] master: Cloth: precompute barycentric coordinates for collision points.

Alexander Gavrilov noreply at git.blender.org
Fri Jan 6 16:55:32 CET 2023


Commit: e1df731c91bc7b9b3349a87c4fcf18bc2f29d668
Author: Alexander Gavrilov
Date:   Fri Jan 6 13:48:36 2023 +0200
Branches: master
https://developer.blender.org/rBe1df731c91bc7b9b3349a87c4fcf18bc2f29d668

Cloth: precompute barycentric coordinates for collision points.

Profiling shows that this computation consumes a noticeable amount
of time, so it is worth moving it to an earlier part of the code
that is executed less frequently and is multithreaded.

Differential Revision: https://developer.blender.org/D16933

===================================================================

M	source/blender/blenkernel/BKE_collision.h
M	source/blender/blenkernel/intern/collision.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index c390d0a8802..d36758c9c4d 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -55,6 +55,8 @@ typedef struct CollPair {
 #else
   int ap1, ap2, ap3, bp1, bp2, bp3;
 #endif
+  /* Barycentric weights of the collision point. */
+  float aw1, aw2, aw3, bw1, bw2, bw3;
   int pointsb[4];
 } CollPair;
 
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index cf0af615b6f..095666e7eac 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -670,7 +670,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
   const bool is_hair = (clmd->hairdata != NULL);
   for (int i = 0; i < collision_count; i++, collpair++) {
     float i1[3], i2[3], i3[3];
-    float w1, w2, w3, u1, u2, u3;
     float v1[3], v2[3], relativeVelocity[3];
     zero_v3(i1);
     zero_v3(i2);
@@ -682,23 +681,13 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
     }
 
     /* Compute barycentric coordinates and relative "velocity" for both collision points. */
-    if (is_hair) {
-      w2 = line_point_factor_v3(
-          collpair->pa, cloth->verts[collpair->ap1].tx, cloth->verts[collpair->ap2].tx);
-
-      w1 = 1.0f - w2;
+    float w1 = collpair->aw1, w2 = collpair->aw2, w3 = collpair->aw3;
+    float u1 = collpair->bw1, u2 = collpair->bw2, u3 = collpair->bw3;
 
+    if (is_hair) {
       interp_v3_v3v3(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, w2);
     }
     else {
-      collision_compute_barycentric(collpair->pa,
-                                    cloth->verts[collpair->ap1].tx,
-                                    cloth->verts[collpair->ap2].tx,
-                                    cloth->verts[collpair->ap3].tx,
-                                    &w1,
-                                    &w2,
-                                    &w3);
-
       collision_interpolateOnTriangle(v1,
                                       cloth->verts[collpair->ap1].tv,
                                       cloth->verts[collpair->ap2].tv,
@@ -708,14 +697,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
                                       w3);
     }
 
-    collision_compute_barycentric(collpair->pb,
-                                  collmd->current_xnew[collpair->bp1].co,
-                                  collmd->current_xnew[collpair->bp2].co,
-                                  collmd->current_xnew[collpair->bp3].co,
-                                  &u1,
-                                  &u2,
-                                  &u3);
-
     collision_interpolateOnTriangle(v2,
                                     collmd->current_v[collpair->bp1].co,
                                     collmd->current_v[collpair->bp2].co,
@@ -834,7 +815,6 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
   for (int i = 0; i < collision_count; i++, collpair++) {
     float ia[3][3] = {{0.0f}};
     float ib[3][3] = {{0.0f}};
-    float w1, w2, w3, u1, u2, u3;
     float v1[3], v2[3], relativeVelocity[3];
 
     /* Only handle static collisions here. */
@@ -842,22 +822,9 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
       continue;
     }
 
-    /* Compute barycentric coordinates for both collision points. */
-    collision_compute_barycentric(collpair->pa,
-                                  cloth->verts[collpair->ap1].tx,
-                                  cloth->verts[collpair->ap2].tx,
-                                  cloth->verts[collpair->ap3].tx,
-                                  &w1,
-                                  &w2,
-                                  &w3);
-
-    collision_compute_barycentric(collpair->pb,
-                                  cloth->verts[collpair->bp1].tx,
-                                  cloth->verts[collpair->bp2].tx,
-                                  cloth->verts[collpair->bp3].tx,
-                                  &u1,
-                                  &u2,
-                                  &u3);
+    /* Retrieve barycentric coordinates for both collision points. */
+    float w1 = collpair->aw1, w2 = collpair->aw2, w3 = collpair->aw3;
+    float u1 = collpair->bw1, u2 = collpair->bw2, u3 = collpair->bw3;
 
     /* Calculate relative "velocity". */
     collision_interpolateOnTriangle(v1,
@@ -1053,6 +1020,23 @@ static void cloth_collision(void *__restrict userdata,
     collpair[index].flag = 0;
 
     data->collided = true;
+
+    /* Compute barycentric coordinates for both collision points. */
+    collision_compute_barycentric(pa,
+                                  verts1[tri_a->tri[0]].tx,
+                                  verts1[tri_a->tri[1]].tx,
+                                  verts1[tri_a->tri[2]].tx,
+                                  &collpair[index].aw1,
+                                  &collpair[index].aw2,
+                                  &collpair[index].aw3);
+
+    collision_compute_barycentric(pb,
+                                  collmd->current_xnew[tri_b->tri[0]].co,
+                                  collmd->current_xnew[tri_b->tri[1]].co,
+                                  collmd->current_xnew[tri_b->tri[2]].co,
+                                  &collpair[index].bw1,
+                                  &collpair[index].bw2,
+                                  &collpair[index].bw3);
   }
   else {
     collpair[index].flag = COLLISION_INACTIVE;
@@ -1159,6 +1143,23 @@ static void cloth_selfcollision(void *__restrict userdata,
     collpair[index].flag = 0;
 
     data->collided = true;
+
+    /* Compute barycentric coordinates for both collision points. */
+    collision_compute_barycentric(pa,
+                                  verts1[tri_a->tri[0]].tx,
+                                  verts1[tri_a->tri[1]].tx,
+                                  verts1[tri_a->tri[2]].tx,
+                                  &collpair[index].aw1,
+                                  &collpair[index].aw2,
+                                  &collpair[index].aw3);
+
+    collision_compute_barycentric(pb,
+                                  verts1[tri_b->tri[0]].tx,
+                                  verts1[tri_b->tri[1]].tx,
+                                  verts1[tri_b->tri[2]].tx,
+                                  &collpair[index].bw1,
+                                  &collpair[index].bw2,
+                                  &collpair[index].bw3);
   }
   else {
     collpair[index].flag = COLLISION_INACTIVE;
@@ -1217,6 +1218,20 @@ static void hair_collision(void *__restrict userdata,
     collpair[index].flag = 0;
 
     data->collided = true;
+
+    /* Compute barycentric coordinates for the collision points. */
+    collpair[index].aw2 = line_point_factor_v3(
+        pa, verts1[edge_coll->v1].tx, verts1[edge_coll->v2].tx);
+
+    collpair[index].aw1 = 1.0f - collpair[index].aw2;
+
+    collision_compute_barycentric(pb,
+                                  collmd->current_xnew[tri_coll->tri[0]].co,
+                                  collmd->current_xnew[tri_coll->tri[1]].co,
+                                  collmd->current_xnew[tri_coll->tri[2]].co,
+                                  &collpair[index].bw1,
+                                  &collpair[index].bw2,
+                                  &collpair[index].bw3);
   }
   else {
     collpair[index].flag = COLLISION_INACTIVE;



More information about the Bf-blender-cvs mailing list