Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/collision.c
| Context not available. | |||||
| { | { | ||||
| int result = 0; | int result = 0; | ||||
| Cloth *cloth1; | Cloth *cloth1; | ||||
| float w1, w2, w3, u1, u2, u3; | float u1, u2, u3; | ||||
| float w[3]; | |||||
| float v1[3], v2[3], relativeVelocity[3]; | float v1[3], v2[3], relativeVelocity[3]; | ||||
| float magrelVel; | float magrelVel; | ||||
| float epsilon2 = BLI_bvhtree_get_epsilon ( collmd->bvhtree ); | float epsilon2 = BLI_bvhtree_get_epsilon ( collmd->bvhtree ); | ||||
| float frict_diff; | |||||
| int i; | |||||
| cloth1 = clmd->clothObject; | cloth1 = clmd->clothObject; | ||||
| frict_diff = fabsf(clmd->coll_parms->max_frict - clmd->coll_parms->friction); | |||||
| for ( ; collpair != collision_end; collpair++ ) { | for ( ; collpair != collision_end; collpair++ ) { | ||||
| float i1[3], i2[3], i3[3]; | float impuplses[3][3]; | ||||
| zero_v3(i1); | zero_v3(impuplses[0]); | ||||
| zero_v3(i2); | zero_v3(impuplses[1]); | ||||
| zero_v3(i3); | zero_v3(impuplses[2]); | ||||
| /* only handle static collisions here */ | /* only handle static collisions here */ | ||||
| if ( collpair->flag & COLLISION_IN_FUTURE ) | if ( collpair->flag & COLLISION_IN_FUTURE ) | ||||
| Context not available. | |||||
| cloth1->verts[collpair->ap1].txold, | cloth1->verts[collpair->ap1].txold, | ||||
| cloth1->verts[collpair->ap2].txold, | cloth1->verts[collpair->ap2].txold, | ||||
| cloth1->verts[collpair->ap3].txold, | cloth1->verts[collpair->ap3].txold, | ||||
| &w1, &w2, &w3 ); | &w[0], &w[1], &w[2] ); | ||||
| /* was: txold */ | /* was: txold */ | ||||
| collision_compute_barycentric ( collpair->pb, | collision_compute_barycentric ( collpair->pb, | ||||
| Context not available. | |||||
| &u1, &u2, &u3 ); | &u1, &u2, &u3 ); | ||||
| /* Calculate relative "velocity". */ | /* 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 ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w[0], w[1], w[2] ); | ||||
| collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 ); | collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 ); | ||||
| Context not available. | |||||
| double impulse = 0.0; | double impulse = 0.0; | ||||
| float vrel_t_pre[3]; | float vrel_t_pre[3]; | ||||
| float temp[3], spf; | float temp[3], spf; | ||||
| float frict_offset, vrel_t_pre_len; | |||||
| float frict_factor[3]; | |||||
| frict_factor[0] = cloth1->verts[collpair->ap1].frict_factor; | |||||
| frict_factor[1] = cloth1->verts[collpair->ap2].frict_factor; | |||||
| frict_factor[2] = cloth1->verts[collpair->ap3].frict_factor; | |||||
| /* calculate tangential velocity */ | /* calculate tangential velocity */ | ||||
| copy_v3_v3 ( temp, collpair->normal ); | copy_v3_v3 ( temp, collpair->normal ); | ||||
| mul_v3_fl(temp, magrelVel); | mul_v3_fl(temp, magrelVel); | ||||
| sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp); | sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp); | ||||
| /* Decrease in magnitude of relative tangential velocity due to coulomb friction | vrel_t_pre_len = len_v3(vrel_t_pre); | ||||
| * in original formula "magrelVel" should be the "change of relative velocity in normal direction" */ | normalize_v3(vrel_t_pre); | ||||
| magtangent = min_ff(clmd->coll_parms->friction * 0.01f * magrelVel, len_v3(vrel_t_pre)); | |||||
| /* Apply friction impulse. */ | for (i = 0; i < 3; i++) { | ||||
| if ( magtangent > ALMOST_ZERO ) { | frict_offset = frict_factor[i] * frict_diff; | ||||
| normalize_v3(vrel_t_pre); | |||||
| /* 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 + frict_offset) * 0.01f * magrelVel, vrel_t_pre_len); | |||||
| impulse = magtangent / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); /* 2.0 * */ | /* Apply friction impulse. */ | ||||
| VECADDMUL ( i1, vrel_t_pre, w1 * impulse ); | if ( magtangent > ALMOST_ZERO ) { | ||||
| VECADDMUL ( i2, vrel_t_pre, w2 * impulse ); | impulse = magtangent / ( 1.0f + w[0]*w[0] + w[1]*w[1] + w[2]*w[2] ); /* 2.0 * */ | ||||
| VECADDMUL ( i3, vrel_t_pre, w3 * impulse ); | VECADDMUL ( impuplses[i], vrel_t_pre, w[i] * impulse ); | ||||
| } | |||||
| } | } | ||||
| /* Apply velocity stopping impulse | /* Apply velocity stopping impulse | ||||
| * I_c = m * v_N / 2.0 | * I_c = m * v_N / 2.0 | ||||
| * no 2.0 * magrelVel normally, but looks nicer DG */ | * no 2.0 * magrelVel normally, but looks nicer DG */ | ||||
| impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); | impulse = magrelVel / ( 1.0 + w[0]*w[0] + w[1]*w[1] + w[2]*w[2] ); | ||||
| VECADDMUL ( i1, collpair->normal, w1 * impulse ); | VECADDMUL ( impuplses[0], collpair->normal, w[0] * impulse ); | ||||
| cloth1->verts[collpair->ap1].impulse_count++; | cloth1->verts[collpair->ap1].impulse_count++; | ||||
| VECADDMUL ( i2, collpair->normal, w2 * impulse ); | VECADDMUL ( impuplses[1], collpair->normal, w[1] * impulse ); | ||||
| cloth1->verts[collpair->ap2].impulse_count++; | cloth1->verts[collpair->ap2].impulse_count++; | ||||
| VECADDMUL ( i3, collpair->normal, w3 * impulse ); | VECADDMUL ( impuplses[2], collpair->normal, w[2] * impulse ); | ||||
| cloth1->verts[collpair->ap3].impulse_count++; | cloth1->verts[collpair->ap3].impulse_count++; | ||||
| /* Apply repulse impulse if distance too short | /* Apply repulse impulse if distance too short | ||||
| Context not available. | |||||
| repulse = min_ff( repulse, 5.0*impulse ); | repulse = min_ff( repulse, 5.0*impulse ); | ||||
| repulse = max_ff(impulse, repulse); | repulse = max_ff(impulse, repulse); | ||||
| impulse = repulse / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); /* original 2.0 / 0.25 */ | impulse = repulse / ( 1.0f + w[0]*w[0] + w[1]*w[1] + w[2]*w[2] ); /* original 2.0 / 0.25 */ | ||||
| VECADDMUL ( i1, collpair->normal, impulse ); | VECADDMUL ( impuplses[0], collpair->normal, impulse ); | ||||
| VECADDMUL ( i2, collpair->normal, impulse ); | VECADDMUL ( impuplses[1], collpair->normal, impulse ); | ||||
| VECADDMUL ( i3, collpair->normal, impulse ); | VECADDMUL ( impuplses[2], collpair->normal, impulse ); | ||||
| } | } | ||||
| result = 1; | result = 1; | ||||
| Context not available. | |||||
| /* stay on the safe side and clamp repulse */ | /* stay on the safe side and clamp repulse */ | ||||
| float repulse = d*1.0f/spf; | float repulse = d*1.0f/spf; | ||||
| float impulse = repulse / ( 3.0f * ( 1.0f + w1*w1 + w2*w2 + w3*w3 )); /* original 2.0 / 0.25 */ | float impulse = repulse / ( 3.0f * ( 1.0f + w[0]*w[0] + w[1]*w[1] + w[2]*w[2] )); /* original 2.0 / 0.25 */ | ||||
| VECADDMUL ( i1, collpair->normal, impulse ); | VECADDMUL ( impuplses[0], collpair->normal, impulse ); | ||||
| VECADDMUL ( i2, collpair->normal, impulse ); | VECADDMUL ( impuplses[1], collpair->normal, impulse ); | ||||
| VECADDMUL ( i3, collpair->normal, impulse ); | VECADDMUL ( impuplses[2], collpair->normal, impulse ); | ||||
| cloth1->verts[collpair->ap1].impulse_count++; | cloth1->verts[collpair->ap1].impulse_count++; | ||||
| cloth1->verts[collpair->ap2].impulse_count++; | cloth1->verts[collpair->ap2].impulse_count++; | ||||
| Context not available. | |||||
| } | } | ||||
| if (result) { | if (result) { | ||||
| int i = 0; | |||||
| for (i = 0; i < 3; i++) { | for (i = 0; i < 3; i++) { | ||||
| if (cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(i1[i])) | if (cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(impuplses[0][i])) | ||||
| cloth1->verts[collpair->ap1].impulse[i] = i1[i]; | cloth1->verts[collpair->ap1].impulse[i] = impuplses[0][i]; | ||||
| if (cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(i2[i])) | if (cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(impuplses[1][i])) | ||||
| cloth1->verts[collpair->ap2].impulse[i] = i2[i]; | cloth1->verts[collpair->ap2].impulse[i] = impuplses[1][i]; | ||||
| if (cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(i3[i])) | if (cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(impuplses[2][i])) | ||||
| cloth1->verts[collpair->ap3].impulse[i] = i3[i]; | cloth1->verts[collpair->ap3].impulse[i] = impuplses[2][i]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||