diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-09-12 16:34:14 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2015-01-20 11:30:00 +0300 |
commit | 3119d718f8b6394c54778ee6325248ddaf1df074 (patch) | |
tree | 07d06108509169f13a8a97dffab80a03ea1209f5 /source | |
parent | 2b06b899b05f5501afad05d19ea2aa41b3f68095 (diff) |
Moved collision response into the main cloth sim source file and fixed
some coordinate transform issues.
Collision response should be regarded as part of the dynamics system
instead of the basic collision detection.
Diffstat (limited to 'source')
-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) |