Commit: d42a7bbd6ea57c69293d3bf978aae2c0e4241b57
Author: Luca Rood
Date:   Thu Jan 16 18:45:23 2020 +0100
Branches: master
https://developer.blender.org/rBd42a7bbd6ea57c69293d3bf978aae2c0e4241b57

Integrate hair collisions with cloth collision

This integrates hair collisions with the new cloth collision system,
greatly improving reliability, and reducing the amount of hair-specific
code paths in the cloth code.

The removes all the point constraint based collision stuff, instead
implementing segment impulse based collisions, using the same collision
response code as the normal cloth solver.

The hair system can now also collide with the emitter if it is a
collision object.

Reviewed By: mano-wii, Sebastian Parborg

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

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

M       source/blender/blenkernel/BKE_cloth.h
M       source/blender/blenkernel/intern/cloth.c
M       source/blender/blenkernel/intern/collision.c
M       source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/source/blender/blenkernel/BKE_cloth.h 
b/source/blender/blenkernel/BKE_cloth.h
index 17de53be42a..2862dda8ead 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -74,11 +74,11 @@ typedef struct ClothSolverResult {
  * own connectivity of the mesh based on the actual edges in the mesh.
  */
 typedef struct Cloth {
-  struct ClothVertex *verts; /* The vertices that represent this cloth. */
-  struct LinkNode *springs;  /* The springs connecting the mesh. */
-  unsigned int numsprings;   /* The count of springs. */
-  unsigned int mvert_num;    /* The number of verts == m * n. */
-  unsigned int tri_num;
+  struct ClothVertex *verts;     /* The vertices that represent this cloth. */
+  struct LinkNode *springs;      /* The springs connecting the mesh. */
+  unsigned int numsprings;       /* The count of springs. */
+  unsigned int mvert_num;        /* The number of verts == m * n. */
+  unsigned int primitive_num;    /* Number of triangles for cloth and edges 
for hair. */
   unsigned char old_solver_type; /* unused, only 1 solver here */
   unsigned char pad2;
   short pad3;
@@ -89,6 +89,7 @@ typedef struct Cloth {
   struct EdgeSet *edgeset;        /* used for selfcollisions */
   int last_frame;
   float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure 
*/
+  struct MEdge *edges;       /* Used for hair collisions. */
 } Cloth;
 
 /**
@@ -265,15 +266,6 @@ int cloth_bvh_collision(struct Depsgraph *depsgraph,
                         float step,
                         float dt);
 
-void cloth_find_point_contacts(struct Depsgraph *depsgraph,
-                               struct Object *ob,
-                               struct ClothModifierData *clmd,
-                               float step,
-                               float dt,
-                               ColliderContacts **r_collider_contacts,
-                               int *r_totcolliders);
-void cloth_free_contacts(ColliderContacts *collider_contacts, int 
totcolliders);
-
 ////////////////////////////////////////////////
 
 /////////////////////////////////////////////////
diff --git a/source/blender/blenkernel/intern/cloth.c 
b/source/blender/blenkernel/intern/cloth.c
index c26800aefba..7332c3e0d43 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -190,22 +190,36 @@ static BVHTree 
*bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
   vt = cloth->tri;
 
   /* in the moment, return zero if no faces there */
-  if (!cloth->tri_num) {
+  if (!cloth->primitive_num) {
     return NULL;
   }
 
   /* create quadtree with k=26 */
-  bvhtree = BLI_bvhtree_new(cloth->tri_num, epsilon, 4, 26);
+  bvhtree = BLI_bvhtree_new(cloth->primitive_num, epsilon, 4, 26);
 
   /* fill tree */
-  for (i = 0; i < cloth->tri_num; i++, vt++) {
-    float co[3][3];
+  if (clmd->hairdata == NULL) {
+    for (i = 0; i < cloth->primitive_num; i++, vt++) {
+      float co[3][3];
 
-    copy_v3_v3(co[0], verts[vt->tri[0]].xold);
-    copy_v3_v3(co[1], verts[vt->tri[1]].xold);
-    copy_v3_v3(co[2], verts[vt->tri[2]].xold);
+      copy_v3_v3(co[0], verts[vt->tri[0]].xold);
+      copy_v3_v3(co[1], verts[vt->tri[1]].xold);
+      copy_v3_v3(co[2], verts[vt->tri[2]].xold);
 
-    BLI_bvhtree_insert(bvhtree, i, co[0], 3);
+      BLI_bvhtree_insert(bvhtree, i, co[0], 3);
+    }
+  }
+  else {
+    MEdge *edges = cloth->edges;
+
+    for (i = 0; i < cloth->primitive_num; i++) {
+      float co[2][3];
+
+      copy_v3_v3(co[0], verts[edges[i].v1].xold);
+      copy_v3_v3(co[1], verts[edges[i].v2].xold);
+
+      BLI_bvhtree_insert(bvhtree, i, co[0], 2);
+    }
   }
 
   /* balance tree */
@@ -222,6 +236,8 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, 
bool moving, bool self)
   ClothVertex *verts = cloth->verts;
   const MVertTri *vt;
 
+  BLI_assert(!(clmd->hairdata != NULL && self));
+
   if (self) {
     bvhtree = cloth->bvhselftree;
   }
@@ -236,39 +252,59 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, 
bool moving, bool self)
   vt = cloth->tri;
 
   /* update vertex position in bvh tree */
-  if (verts && vt) {
-    for (i = 0; i < cloth->tri_num; i++, vt++) {
-      float co[3][3], co_moving[3][3];
-      bool ret;
-
-      /* copy new locations into array */
-      if (moving) {
-        copy_v3_v3(co[0], verts[vt->tri[0]].txold);
-        copy_v3_v3(co[1], verts[vt->tri[1]].txold);
-        copy_v3_v3(co[2], verts[vt->tri[2]].txold);
-
-        /* update moving positions */
-        copy_v3_v3(co_moving[0], verts[vt->tri[0]].tx);
-        copy_v3_v3(co_moving[1], verts[vt->tri[1]].tx);
-        copy_v3_v3(co_moving[2], verts[vt->tri[2]].tx);
-
-        ret = BLI_bvhtree_update_node(bvhtree, i, co[0], co_moving[0], 3);
-      }
-      else {
-        copy_v3_v3(co[0], verts[vt->tri[0]].tx);
-        copy_v3_v3(co[1], verts[vt->tri[1]].tx);
-        copy_v3_v3(co[2], verts[vt->tri[2]].tx);
+  if (clmd->hairdata == NULL) {
+    if (verts && vt) {
+      for (i = 0; i < cloth->primitive_num; i++, vt++) {
+        float co[3][3], co_moving[3][3];
+        bool ret;
+
+        /* copy new locations into array */
+        if (moving) {
+          copy_v3_v3(co[0], verts[vt->tri[0]].txold);
+          copy_v3_v3(co[1], verts[vt->tri[1]].txold);
+          copy_v3_v3(co[2], verts[vt->tri[2]].txold);
+
+          /* update moving positions */
+          copy_v3_v3(co_moving[0], verts[vt->tri[0]].tx);
+          copy_v3_v3(co_moving[1], verts[vt->tri[1]].tx);
+          copy_v3_v3(co_moving[2], verts[vt->tri[2]].tx);
+
+          ret = BLI_bvhtree_update_node(bvhtree, i, co[0], co_moving[0], 3);
+        }
+        else {
+          copy_v3_v3(co[0], verts[vt->tri[0]].tx);
+          copy_v3_v3(co[1], verts[vt->tri[1]].tx);
+          copy_v3_v3(co[2], verts[vt->tri[2]].tx);
 
-        ret = BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 3);
-      }
+          ret = BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 3);
+        }
 
-      /* check if tree is already full */
-      if (ret == false) {
-        break;
+        /* check if tree is already full */
+        if (ret == false) {
+          break;
+        }
       }
+
+      BLI_bvhtree_update_tree(bvhtree);
     }
+  }
+  else {
+    if (verts) {
+      MEdge *edges = cloth->edges;
+
+      for (i = 0; i < cloth->primitive_num; i++) {
+        float co[2][3];
 
-    BLI_bvhtree_update_tree(bvhtree);
+        copy_v3_v3(co[0], verts[edges[i].v1].tx);
+        copy_v3_v3(co[1], verts[edges[i].v2].tx);
+
+        if (!BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 2)) {
+          break;
+        }
+      }
+
+      BLI_bvhtree_update_tree(bvhtree);
+    }
   }
 }
 
@@ -900,7 +936,13 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh 
*mesh)
   }
 
   /* save face information */
-  clmd->clothObject->tri_num = looptri_num;
+  if (clmd->hairdata == NULL) {
+    clmd->clothObject->primitive_num = looptri_num;
+  }
+  else {
+    clmd->clothObject->primitive_num = mesh->totedge;
+  }
+
   clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, 
"clothLoopTris");
   if (clmd->clothObject->tri == NULL) {
     cloth_free_modifier(clmd);
@@ -910,6 +952,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh 
*mesh)
   }
   BKE_mesh_runtime_verttri_from_looptri(clmd->clothObject->tri, mloop, 
looptri, looptri_num);
 
+  clmd->clothObject->edges = mesh->medge;
+
   /* Free the springs since they can't be correct if the vertices
    * changed.
    */
diff --git a/source/blender/blenkernel/intern/collision.c 
b/source/blender/blenkernel/intern/collision.c
index 220b9417a6c..5db42618a9e 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -33,6 +33,7 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_blenlib.h"
+#include "BLI_linklist.h"
 #include "BLI_math.h"
 #include "BLI_task.h"
 #include "BLI_threads.h"
@@ -193,17 +194,17 @@ BLI_INLINE int next_ind(int i)
   return (++i < 3) ? i : 0;
 }
 
-static float compute_collision_point(float a1[3],
-                                     const float a2[3],
-                                     const float a3[3],
-                                     const float b1[3],
-                                     const float b2[3],
-                                     const float b3[3],
-                                     bool culling,
-                                     bool use_normal,
-                                     float r_a[3],
-                                     float r_b[3],
-                                     float r_vec[3])
+static float compute_collision_point_tri_tri(const float a1[3],
+                                             const float a2[3],
+                                             const float a3[3],
+                                             const float b1[3],
+                                             const float b2[3],
+                                             const float b3[3],
+                                             bool culling,
+                                             bool use_normal,
+                                             float r_a[3],
+                                             float r_b[3],
+                                             float r_vec[3])
 {
   float a[3][3];
   float b[3][3];
@@ -423,6 +424,179 @@ static float compute_collision_point(float a1[3],
   return dist;
 }
 
+static float compute_collision_point_edge_tri(const float a1[3],
+                                              const float a2[3],
+                                              const float b1[3],
+                                              const float b2[3],
+                                              const float b3[3],
+                                              bool culling,
+                                              bool use_normal,
+                                              float r_a[3],
+                                              float r_b[3],
+                                              float r_vec[3])
+{
+  float a[2][3];
+  float b[3][3];
+  float dist = FLT_MAX;
+  float tmp_co1[3], tmp_co2[3];
+ 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to