[Bf-blender-cvs] [80ed76cb66] cloth-improvements: New self collision implementation (needs some cleanup)
Luca Rood
noreply at git.blender.org
Fri Jan 20 05:38:37 CET 2017
Commit: 80ed76cb6674e2782c2c763ca7907eea00870aae
Author: Luca Rood
Date: Thu Jan 19 02:13:01 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rB80ed76cb6674e2782c2c763ca7907eea00870aae
New self collision implementation (needs some cleanup)
===================================================================
M source/blender/blenkernel/BKE_cloth.h
M source/blender/blenkernel/intern/cloth.c
M source/blender/blenkernel/intern/collision.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 9e2b98a7ae..f7cca99be6 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -237,7 +237,7 @@ void clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, stru
int cloth_uses_vgroup(struct ClothModifierData *clmd);
// needed for collision.c
-void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
+void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving, bool self);
void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
// needed for button_object.c
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f2d96f3588..2eef11376a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -233,14 +233,21 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
return bvhtree;
}
-void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving)
+void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self)
{
unsigned int i = 0;
Cloth *cloth = clmd->clothObject;
- BVHTree *bvhtree = cloth->bvhtree;
+ BVHTree *bvhtree;
ClothVertex *verts = cloth->verts;
const MVertTri *vt;
-
+
+ if (self) {
+ bvhtree = cloth->bvhselftree;
+ }
+ else {
+ bvhtree = cloth->bvhtree;
+ }
+
if (!bvhtree)
return;
@@ -907,7 +914,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0f));
}
- clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist );
+ clmd->clothObject->bvhselftree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
return 1;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 3d612a0c74..6f4e635a7b 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -312,7 +312,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
/*impulse = magtangent / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); 2.0 * */
- /* Impulse shoud be uniform throughout polygon, the scaling used above was wrong */
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
impulse = magtangent / 1.5;
VECADDMUL ( i1, vrel_t_pre, w1 * impulse );
@@ -325,7 +325,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
* no 2.0 * magrelVel normally, but looks nicer DG */
/*impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );*/
- /* Impulse shoud be uniform throughout polygon, the scaling used above was wrong */
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
impulse = magrelVel / 1.5f;
if (backside) {
@@ -385,7 +385,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
/*impulse = repulse / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); original 2.0 / 0.25 */
- /* Impulse shoud be uniform throughout polygon, the scaling used above was wrong */
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
impulse = repulse / 1.5f;
VECADDMUL ( i1, collider_norm, impulse );
@@ -417,7 +417,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
/*float impulse = repulse / ( 3.0f * ( 1.0f + w1*w1 + w2*w2 + w3*w3 )); original 2.0 / 0.25 */
- /* Impulse shoud be uniform throughout polygon, the scaling used above was wrong */
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
float impulse = repulse / 4.5f;
if (backside) {
@@ -457,6 +457,184 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
return result;
}
+static int cloth_selfcollision_response_static (ClothModifierData *clmd, CollPair *collpair, CollPair *collision_end)
+{
+ int result = 0;
+ Cloth *cloth1;
+ float w1, w2, w3, u1, u2, u3;
+ float v1[3], v2[3], relativeVelocity[3];
+ float magrelVel;
+
+ cloth1 = clmd->clothObject;
+
+ for ( ; collpair != collision_end; collpair++ ) {
+ float i1[3], i2[3], i3[3], j1[3], j2[3], j3[3]; /* i are impulses for ap and j are impulses for bp */
+
+ zero_v3(i1);
+ zero_v3(i2);
+ zero_v3(i3);
+
+ /* only handle static collisions here */
+ if ( collpair->flag & COLLISION_IN_FUTURE )
+ continue;
+
+ /* compute barycentric coordinates for both collision points */
+ collision_compute_barycentric ( collpair->pa,
+ cloth1->verts[collpair->ap1].tx,
+ cloth1->verts[collpair->ap2].tx,
+ cloth1->verts[collpair->ap3].tx,
+ &w1, &w2, &w3 );
+
+ /* was: txold */
+ collision_compute_barycentric ( collpair->pb,
+ cloth1->verts[collpair->bp1].tx,
+ cloth1->verts[collpair->bp2].tx,
+ cloth1->verts[collpair->bp3].tx,
+ &u1, &u2, &u3 );
+
+ /* Calculate relative "velocity". */
+ collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 );
+
+ collision_interpolateOnTriangle ( v2, cloth1->verts[collpair->bp1].tv, cloth1->verts[collpair->bp2].tv, cloth1->verts[collpair->bp3].tv, u1, u2, u3 );
+
+ sub_v3_v3v3(relativeVelocity, v2, v1);
+
+ /* Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). */
+ magrelVel = dot_v3v3(relativeVelocity, collpair->normal);
+
+ /* printf("magrelVel: %f\n", magrelVel); */
+
+ /* TODO: Impulses should be weighed by mass as this is self col,
+ * this has to be done after voronoi mass distribution is implemented */
+
+ /* If v_n_mag < 0 the edges are approaching each other. */
+ if ( magrelVel > ALMOST_ZERO ) {
+ /* Calculate Impulse magnitude to stop all motion in normal direction. */
+ float magtangent = 0, repulse = 0, d = 0;
+ double impulse = 0.0;
+ float vrel_t_pre[3];
+ float temp[3], spf;
+
+ /* calculate tangential velocity */
+ copy_v3_v3 ( temp, collpair->normal );
+ mul_v3_fl(temp, magrelVel);
+ sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp);
+
+ /* Decrease in magnitude of relative tangential velocity due to coulomb friction
+ * in original formula "magrelVel" should be the "change of relative velocity in normal direction" */
+ magtangent = min_ff(clmd->coll_parms->friction * 0.01f * magrelVel, len_v3(vrel_t_pre));
+
+ /* Apply friction impulse. */
+ if ( magtangent > ALMOST_ZERO ) {
+ normalize_v3(vrel_t_pre);
+
+ /*impulse = magtangent / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); 2.0 * */
+
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
+ impulse = magtangent / 1.5;
+
+ VECADDMUL ( i1, vrel_t_pre, w1 * impulse );
+ VECADDMUL ( i2, vrel_t_pre, w2 * impulse );
+ VECADDMUL ( i3, vrel_t_pre, w3 * impulse );
+ }
+
+ /* Apply velocity stopping impulse
+ * I_c = m * v_N / 2.0
+ * no 2.0 * magrelVel normally, but looks nicer DG */
+ /*impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );*/
+
+ /* Impulse should be uniform throughout polygon, the scaling used above was wrong */
+ impulse = magrelVel / 1.5f / 2.0f;
+
+ VECADDMUL ( i1, collpair->normal, w1 * impulse );
+ cloth1->verts[collpair->ap1].impulse_count++;
+
+ VECADDMUL ( i2, collpair->normal, w2 * impulse );
+ cloth1->verts[collpair->ap2].impulse_count++;
+
+ VECADDMUL ( i3, collpair->normal, w3 * impulse );
+ cloth1->verts[collpair->ap3].impulse_count++;
+
+ /* Apply repulse impulse if distance too short
+ * I_r = -min(dt*kd, m(0, 1d/dt - v_n))
+ * DG: this formula ineeds to be changed for this code since we apply impulses/repulses like this:
+ * v += impulse; x_new = x + v;
+ * We don't use dt!!
+ * DG TODO: Fix usage of dt here! */
+ spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
+ d = clmd->coll_parms->epsilon*8.0f/9.0f * 2.0f - collpair->distance;
+
+ 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);
+
+ /*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) */
+
+ VECADDMUL ( i1, collpair->normal, w1 * impulse );
+ VECADDMUL ( i2, collpair->normal, w2 * impulse );
+ VECADDMUL ( i3, collpair->normal, w3 * impulse );
+ }
+
+ result = 1;
+ }
+ else {
+ /* Apply repulse impulse if distance too short
+ * I_r = -min(dt*kd, max(0, 1d/dt - v_n))
+ * DG: this formula ineeds to be changed for this code since we apply impulses/repulses like this:
+ * v += impulse; x_new = x + v;
+ * We don't use dt!! */
+ float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+ float d;
+
+ d = clmd->coll_parms->epsilon*8.0f/9.0f * 2.0f - (float)collpair->distance;
+
+ if ( d > ALMOST_ZERO) {
+ /* stay on the safe side and clamp repulse */
+ float repulse = d*1.0f/spf;
+
+ /*float impulse = repulse / ( 3.0f * ( 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 */
+ float impulse = repulse / 4.5f / 2.0f; /* 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 );
+ VECADDMUL ( i3, collpair->normal, w3 * impulse );
+
+ cloth1->verts[collpair->ap1].impulse_count++;
+ cloth1->verts[collpair->ap2].impulse_count++;
+ cloth1->verts[collpair->ap3].impulse_count++;
+
+ result = 1;
+ }
+ }
+
+ if (re
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list