[Bf-blender-cvs] [8d1b6b76a2] cloth-improvements: Use impulse clustering for self collisions
Luca Rood
noreply at git.blender.org
Wed Feb 1 07:11:52 CET 2017
Commit: 8d1b6b76a24dd6eda2ecbe0c87ffed4582670552
Author: Luca Rood
Date: Tue Jan 31 03:14:56 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rB8d1b6b76a24dd6eda2ecbe0c87ffed4582670552
Use impulse clustering for self collisions
Also adjust impulse scaling to work better with the new clustering.
===================================================================
M source/blender/blenkernel/intern/collision.c
===================================================================
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 8fd04fc64c..a41b176598 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -194,7 +194,7 @@ static void free_impulse_clusters(ImpulseCluster *clusters)
static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const float impulse[3], const float clustang)
{
ImpulseCluster **imp;
- ImpulseCluster **close;
+ ImpulseCluster **close = NULL;
float dir[3];
float mag;
float minang = FLT_MAX;
@@ -223,7 +223,9 @@ static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const flo
(*close)->dominant_mag = max_ff((*close)->dominant_mag, mag);
/* Interpolate direction */
- interp_v3_v3v3_slerp((*close)->dir, (*close)->dir, dir, mag / (*close)->totmag);
+ if(!interp_v3_v3v3_slerp((*close)->dir, (*close)->dir, dir, mag / (*close)->totmag)) {
+ BLI_assert(false);
+ }
}
else {
ImpulseCluster *tmp = MEM_mallocN(sizeof(*tmp), "cloth_collision_impulse_cluster");
@@ -617,7 +619,8 @@ static int cloth_collision_response_static (ClothModifierData *clmd, CollisionMo
return result;
}
-static int cloth_selfcollision_response_static (ClothModifierData *clmd, CollPair *collpair, CollPair *collision_end)
+static int cloth_selfcollision_response_static(ClothModifierData *clmd, CollPair *collpair, CollPair *collision_end,
+ ImpulseCluster **vert_imp_clusters)
{
int result = 0;
Cloth *cloth1;
@@ -728,15 +731,14 @@ static int cloth_selfcollision_response_static (ClothModifierData *clmd, CollPai
if ( ( magrelVel < 0.1f*d*spf ) && ( d > ALMOST_ZERO ) ) {
repulse = MIN2 ( d*1.0f/spf, 0.1f*d*spf - magrelVel );
- /* stay on the safe side and clamp repulse */
- /*if ( impulse > ALMOST_ZERO )
- repulse = min_ff( repulse, 2.0*impulse );*/
- repulse = min_ff(impulse, repulse);
+ if ( impulse > ALMOST_ZERO )
+ repulse = min_ff( repulse, 5.0*impulse );
+ repulse = max_ff(impulse, repulse);
/*impulse = repulse / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); original 2.0 / 0.25 */
/* Impulse should be uniform throughout polygon, the scaling used above was wrong */
- impulse = repulse; /* TODO: This might have to be divided by two for self col (to be evaluated) */
+ impulse = repulse / 1.5f; /* TODO: This might have to be divided by two for self col (to be evaluated) */
VECADDMUL ( i1, collpair->normal, w1 * impulse );
VECADDMUL ( i2, collpair->normal, w2 * impulse );
@@ -778,17 +780,16 @@ static int cloth_selfcollision_response_static (ClothModifierData *clmd, CollPai
}
if (result) {
- int i = 0;
-
- for (i = 0; i < 3; i++) {
- if (cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(i1[i]))
- cloth1->verts[collpair->ap1].impulse[i] = i1[i];
+ if (cloth1->verts[collpair->ap1].impulse_count > 0) {
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap1], i1, M_PI / 20);
+ }
- if (cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(i2[i]))
- cloth1->verts[collpair->ap2].impulse[i] = i2[i];
+ if (cloth1->verts[collpair->ap2].impulse_count > 0) {
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap2], i2, M_PI / 20);
+ }
- if (cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(i3[i]))
- cloth1->verts[collpair->ap3].impulse[i] = i3[i];
+ if (cloth1->verts[collpair->ap3].impulse_count > 0) {
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap3], i3, M_PI / 20);
}
}
}
@@ -1170,25 +1171,31 @@ static int cloth_bvh_selfcollisions_resolve (ClothModifierData * clmd, CollPair
Cloth *cloth = clmd->clothObject;
int i=0, j = 0, /*numfaces = 0, */ mvert_num = 0;
ClothVertex *verts = NULL;
+ ImpulseCluster **vert_imp_clusters;
int ret = 0;
int result = 0;
mvert_num = clmd->clothObject->mvert_num;
verts = cloth->verts;
+ vert_imp_clusters = MEM_callocN(sizeof(*vert_imp_clusters) * mvert_num, "vert_impulse_clusters");
+
for ( j = 0; j < 2; j++ ) { /* 5 is just a value that ensures convergence */
result = 0;
- result += cloth_selfcollision_response_static ( clmd, collisions, collisions_index );
+ result += cloth_selfcollision_response_static (clmd, collisions, collisions_index, vert_imp_clusters);
// apply impulses in parallel
if (result) {
for (i = 0; i < mvert_num; i++) {
// calculate "velocities" (just xnew = xold + v; no dt in v)
if (verts[i].impulse_count) {
- // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
- VECADD ( verts[i].tv, verts[i].tv, verts[i].impulse);
- VECADD ( verts[i].dcvel, verts[i].dcvel, verts[i].impulse);
+ compute_dominant_impulses(&vert_imp_clusters[i], verts[i].impulse);
+ free_impulse_clusters(vert_imp_clusters[i]);
+ vert_imp_clusters[i] = NULL;
+
+ madd_v3_v3v3fl(verts[i].tv, verts[i].tv, verts[i].impulse, 0.5f);
+ madd_v3_v3v3fl(verts[i].dcvel, verts[i].dcvel, verts[i].impulse, 0.5f);
zero_v3(verts[i].impulse);
verts[i].impulse_count = 0;
@@ -1201,6 +1208,9 @@ static int cloth_bvh_selfcollisions_resolve (ClothModifierData * clmd, CollPair
break;
}
}
+
+ MEM_freeN(vert_imp_clusters);
+
return ret;
}
@@ -1302,7 +1312,8 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) {
BVHTreeOverlap *overlap = NULL;
unsigned int result = 0;
- CollPair *collisions, *collisions_index;
+ CollPair *collisions = NULL;
+ CollPair *collisions_index;
// collisions = 1;
verts = cloth->verts; // needed for openMP
More information about the Bf-blender-cvs
mailing list