diff options
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_collision.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 68 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/implicit.c | 89 |
4 files changed, 81 insertions, 81 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 10a336a075a..e0710ee7e63 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -207,9 +207,6 @@ void cloth_find_point_contacts(struct Object *ob, struct ClothModifierData *clmd ColliderContacts **r_collider_contacts, int *r_totcolliders); void cloth_free_contacts(ColliderContacts *collider_contacts, int totcolliders); -bool cloth_points_collpair_response(struct ClothModifierData *clmd, struct CollisionModifierData *collmd, struct PartDeflect *pd, - struct CollPair *collpair, float dt, float r_impulse[3]); - //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index c0ee5dcc63e..b81b8f04817 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -137,6 +137,8 @@ void bvhtree_update_from_mvert(BVHTree *bvhtree, struct MFace *faces, int numfac // defined in collisions.c void collision_move_object(struct CollisionModifierData *collmd, float step, float prevstep); +void collision_get_collider_velocity(float vel_old[3], float vel_new[3], struct CollisionModifierData *collmd, struct CollPair *collpair); + ///////////////////////////////////////////////// // used in effect.c ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index b13eb9d4574..a8273b502a1 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -958,80 +958,20 @@ BLI_INLINE void max_v3_v3v3(float r[3], const float a[3], const float b[3]) r[2] = max_ff(a[2], b[2]); } -bool cloth_points_collpair_response(ClothModifierData *clmd, CollisionModifierData *collmd, PartDeflect *pd, CollPair *collpair, float dt, float r_impulse[3]) +void collision_get_collider_velocity(float vel_old[3], float vel_new[3], CollisionModifierData *collmd, CollPair *collpair) { - bool result = false; - float restitution = (1.0f - clmd->coll_parms->damping) * (1.0f - pd->pdef_sbdamp); - Cloth *cloth1 = clmd->clothObject; - float u1, u2, u3; - float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3]; - float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); - - float margin_distance = collpair->distance - epsilon2; - float mag_v_rel; - - zero_v3(r_impulse); - - if (margin_distance > 0.0f) - return false; /* XXX tested before already? */ - - /* only handle static collisions here */ - if ( collpair->flag & COLLISION_IN_FUTURE ) - return false; /* compute barycentric coordinates */ collision_compute_barycentric(collpair->pb, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, - &u1, &u2, &u3 ); - - /* Calculate relative velocity */ - copy_v3_v3(v1, cloth1->verts[collpair->ap1].tv); + &u1, &u2, &u3); - collision_interpolateOnTriangle(v2_new, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3); + collision_interpolateOnTriangle(vel_new, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3); /* XXX assume constant velocity of the collider for now */ - copy_v3_v3(v2_old, v2_new); - - /* relative velocity = velocity of the cloth point relative to the collider */ - sub_v3_v3v3(v_rel_old, v1, v2_old); - sub_v3_v3v3(v_rel_new, v1, v2_new); - /* normal component of the relative velocity */ - mag_v_rel = dot_v3v3(v_rel_old, collpair->normal); - - /* only valid when moving toward the collider */ - if (mag_v_rel < -ALMOST_ZERO) { - float v_nor_old, v_nor_new; - float v_tan_old[3], v_tan_new[3]; - float bounce, repulse; - - /* Collision response based on - * "Simulating Complex Hair with Robust Collision Handling" (Choe, Choi, Ko, ACM SIGGRAPH 2005) - * http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf - */ - - v_nor_old = mag_v_rel; - v_nor_new = dot_v3v3(v_rel_new, collpair->normal); - - madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, -v_nor_old); - madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, -v_nor_new); - - repulse = -margin_distance / dt + dot_v3v3(v1, collpair->normal); - - if (margin_distance < -epsilon2) { - bounce = -(v_nor_new + v_nor_old * restitution); - mul_v3_v3fl(r_impulse, collpair->normal, max_ff(repulse, bounce)); - } - else { - bounce = 0.0f; - mul_v3_v3fl(r_impulse, collpair->normal, repulse); - } - - result = true; - } - - return result; + copy_v3_v3(vel_old, vel_new); } static bool cloth_points_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd, PartDeflect *pd, diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 68aaab09576..f60a0ccac82 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -2090,6 +2090,74 @@ bool implicit_hair_volume_get_texture_data(Object *UNUSED(ob), ClothModifierData /* ================================ */ +static bool collision_response(ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, float restitution, float r_impulse[3]) +{ + Cloth *cloth = clmd->clothObject; + int index = collpair->ap1; + bool result = false; + + float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3]; + float epsilon2 = BLI_bvhtree_getepsilon(collmd->bvhtree); + + float margin_distance = collpair->distance - epsilon2; + float mag_v_rel; + + zero_v3(r_impulse); + + if (margin_distance > 0.0f) + return false; /* XXX tested before already? */ + + /* only handle static collisions here */ + if ( collpair->flag & COLLISION_IN_FUTURE ) + return false; + + /* velocity */ + copy_v3_v3(v1, cloth->verts[index].v); + collision_get_collider_velocity(v2_old, v2_new, collmd, collpair); + /* relative velocity = velocity of the cloth point relative to the collider */ + sub_v3_v3v3(v_rel_old, v1, v2_old); + sub_v3_v3v3(v_rel_new, v1, v2_new); + /* normal component of the relative velocity */ + mag_v_rel = dot_v3v3(v_rel_old, collpair->normal); + + /* only valid when moving toward the collider */ + if (mag_v_rel < -ALMOST_ZERO) { + float v_nor_old, v_nor_new; + float v_tan_old[3], v_tan_new[3]; + float bounce, repulse; + + /* Collision response based on + * "Simulating Complex Hair with Robust Collision Handling" (Choe, Choi, Ko, ACM SIGGRAPH 2005) + * http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf + */ + + v_nor_old = mag_v_rel; + v_nor_new = dot_v3v3(v_rel_new, collpair->normal); + + madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, -v_nor_old); + madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, -v_nor_new); + + /* TODO repulsion forces can easily destabilize the system, + * have to clamp them or construct a linear spring instead + */ +// repulse = -margin_distance / dt + dot_v3v3(v1, collpair->normal); + repulse = 0.0f; + + if (margin_distance < -epsilon2) { + bounce = -(v_nor_new + v_nor_old * restitution); + mul_v3_v3fl(r_impulse, collpair->normal, max_ff(repulse, bounce)); + } + else { + bounce = 0.0f; + mul_v3_v3fl(r_impulse, collpair->normal, repulse); + } + + result = true; + } + + return result; +} + /* Init constraint matrix * This is part of the modified CG method suggested by Baraff/Witkin in * "Large Steps in Cloth Simulation" (Siggraph 1998) @@ -2120,8 +2188,9 @@ static void setup_constraint_matrix(ClothModifierData *clmd, ColliderContacts *c ColliderContacts *ct = &contacts[i]; for (j = 0; j < ct->totcollisions; ++j) { CollPair *collpair = &ct->collisions[j]; + float restitution = (1.0f - clmd->coll_parms->damping) * (1.0f - ct->ob->pd->pdef_sbdamp); int v = collpair->face1; - float cmat[3][3]; + float cnor[3], cmat[3][3]; float impulse[3]; /* pinned verts handled separately */ @@ -2129,13 +2198,16 @@ static void setup_constraint_matrix(ClothModifierData *clmd, ColliderContacts *c continue; /* calculate collision response */ - if (!cloth_points_collpair_response(clmd, ct->collmd, ct->ob->pd, collpair, dt, impulse)) + if (!collision_response(clmd, ct->collmd, collpair, restitution, impulse)) continue; + vel_world_to_root(impulse, X[v], impulse, &roots[v]); add_v3_v3(z[v], impulse); /* modify S to enforce velocity constraint in normal direction */ - mul_fvectorT_fvector(cmat, collpair->normal, collpair->normal); + copy_v3_v3(cnor, collpair->normal); + mul_transposed_m3_v3(roots[v].rot, cnor); + mul_fvectorT_fvector(cmat, cnor, cnor); sub_m3_m3m3(S[v].m, I, cmat); BKE_sim_debug_data_add_dot(clmd->debug_data, collpair->pa, 0, 1, 0, "collision", hash_collpair(936, collpair)); @@ -2151,17 +2223,6 @@ static void setup_constraint_matrix(ClothModifierData *clmd, ColliderContacts *c } } } - - /* transform to root space */ - for (v = 0; v < numverts; v++) { - float t[3][3]; - copy_m3_m3(t, roots[v].rot); - transpose_m3(t); - mul_m3_m3m3(S[v].m, S[v].m, roots[v].rot); - mul_m3_m3m3(S[v].m, t, S[v].m); - - vel_world_to_root(z[v], X[v], z[v], &roots[v]); - } } static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M) |