Cloth: Bugfix for wrong calculated bending springs, Bugfix for selfcollisions (faster + bugfix for explode), Changed: Collision response also put vertices back to surface now

This commit is contained in:
2008-02-28 23:12:50 +00:00
parent 8c5a22daec
commit 6169b29b3a
4 changed files with 58 additions and 49 deletions

View File

@@ -147,7 +147,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->structural = 30.0;
clmd->sim_parms->shear = 30.0;
clmd->sim_parms->bending = 1.0;
clmd->sim_parms->Cdis = 5.0;
clmd->sim_parms->Cdis = 1.0; // was 5
clmd->sim_parms->Cvi = 1.0;
clmd->sim_parms->mass = 1.0f;
clmd->sim_parms->stepsPerFrame = 5;
@@ -186,7 +186,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->mingoal = 0.0f;
clmd->sim_parms->defgoal = 0.0f;
clmd->sim_parms->goalspring = 1.0f;
clmd->sim_parms->goalfrict = 5.0f;
clmd->sim_parms->goalfrict = 0.0f;
}
@@ -310,7 +310,7 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm )
for ( i = 0; i < numsprings; i++ )
{
if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE )
&& ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) )
&& ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) )
{
BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL );
BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL );
@@ -1392,9 +1392,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
// check for existing spring
// check also if startpoint is equal to endpoint
if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij )
&& !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 )
&& ( index2!=tspring2->ij ) )
if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
&& ( index2!=tspring2->ij ) )
{
spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
@@ -1406,11 +1405,11 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(tspring2->ij, index2);
spring->kl = MAX2(tspring2->ij, index2);
VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x );
VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL );
BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
bend_springs++;
BLI_linklist_prepend ( &cloth->springs, spring );
@@ -1420,6 +1419,21 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
search2 = search2->next;
}
/* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
for ( i = 0; i < numedges; i++ ) // struct springs
BLI_edgehash_insert ( edgehash, MIN2(medge[i].v1, medge[i].v2), MAX2(medge[i].v2, medge[i].v1), NULL );
for ( i = 0; i < numfaces; i++ ) // edge springs
{
BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL );
if(mface[i].v4)
{
BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL );
}
}
cloth->numsprings = struct_springs + shear_springs + bend_springs;
if ( edgelist )

View File

@@ -520,7 +520,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
// Apply velocity stopping impulse
// I_c = m * v_N / 2.0
// no 2.0 * magrelVel normally, but looks nicer DG
impulse = 2.0 * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
cloth1->verts[collpair->ap1].impulse_count++;
@@ -531,21 +531,23 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
cloth1->verts[collpair->ap3].impulse_count++;
/*
// doesn't perform nice, dunno why DG
// Apply repulse impulse if distance too short
// I_r = -min(dt*kd, m(0,1d/dt - v_n))
d = clmd->coll_parms->epsilon - collpair->distance;
d = clmd->coll_parms->epsilon*8.0/9.0 - collpair->distance;
if((magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame) && (d > ALMOST_ZERO))
{
repulse = MIN2(d*5.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
repulse = MIN2(d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
impulse = 0.25 * repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3); // original 2.0 / 0.25
VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
// stay on the safe side and clamp repulse
if(impulse > ALMOST_ZERO)
repulse = MIN2(repulse, 5.0*impulse);
repulse = MAX2(impulse, repulse);
impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3); // original 2.0 / 0.25
VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, impulse);
VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, impulse);
VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, impulse);
}
*/
result = 1;
}
@@ -971,16 +973,6 @@ void cloth_collision_self_static(ModifierData *md1, ModifierData *md2, Collision
}
#if 0
/* aye this belongs to arith.c */
static void Vec3PlusStVec(float *v, float s, float *v1)
{
v[0] += s*v1[0];
v[1] += s*v1[1];
v[2] += s*v1[2];
}
#endif
// cloth - object collisions
int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
@@ -1149,7 +1141,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
if ((ABS(temp[0]) > mindistance) || (ABS(temp[1]) > mindistance) || (ABS(temp[2]) > mindistance)) continue;
// check for adjacent points
// check for adjacent points (i must be smaller j)
if(BLI_edgehash_haskey (cloth->edgehash, i, j ))
{
continue;

View File

@@ -1295,7 +1295,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
// Ascher & Boxman, p.21: Damping only during elonglation
// something wrong with it...
mul_fvector_S(damping_force, dir, MIN2(1.0, clmd->sim_parms->Cdis) * INPR(vel,dir));
mul_fvector_S(damping_force, dir, clmd->sim_parms->Cdis * INPR(vel,dir));
VECADD(s->f, s->f, damping_force);
/* VERIFIED */
@@ -1330,7 +1330,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
VECADDS(s->f, s->f, extent, -k);
mul_fvector_S(damping_force, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)) * INPR(vel,dir));
mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01 * INPR(vel,dir));
VECADD(s->f, s->f, damping_force);
// HERE IS THE PROBLEM!!!!
@@ -1611,13 +1611,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
if(result)
{
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
{
if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
{
continue;
}
}
if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
continue;
VECCOPY(id->Xnew[i], verts[i].tx);
VECCOPY(id->Vnew[i], verts[i].tv);

View File

@@ -5135,28 +5135,33 @@ static void cloth_presets_material(void *ob_v, void *arg2)
{
clmd->sim_parms->structural = clmd->sim_parms->shear = 30.0;
clmd->sim_parms->bending = 0.1;
clmd->sim_parms->Cdis = 0.0;
}
else if(clmd->sim_parms->presets==2) /* COTTON */
{
clmd->sim_parms->structural = clmd->sim_parms->shear = 30.0;
clmd->sim_parms->bending = 1.0;
clmd->sim_parms->Cdis = 5.0;
}
else if(clmd->sim_parms->presets==3) /* RUBBER */
{
clmd->sim_parms->structural = clmd->sim_parms->shear = 5.0;
clmd->sim_parms->bending = 25.0;
clmd->sim_parms->Cdis = 25.0;
clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 7.0);
}
else if(clmd->sim_parms->presets==4) /* DENIM */
{
clmd->sim_parms->structural = clmd->sim_parms->shear = 70.0;
clmd->sim_parms->bending = 300.0;
clmd->sim_parms->Cdis = 25.0;
clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 15.0);
}
else if(clmd->sim_parms->presets==5) /* LEATHER */
{
clmd->sim_parms->structural = clmd->sim_parms->shear = 1000.0;
clmd->sim_parms->bending = 2500.0;
clmd->sim_parms->Cdis = 25.0;
clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 25.0);
}
}
@@ -5229,22 +5234,25 @@ static void object_panel_cloth(Object *ob)
but = uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,130,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
but = uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 10,130,150,20, &clmd->sim_parms->Cdis, 0.0, 50.0, 100, 0, "Damping of cloth velocity (higher = more smooth, less jiggling)");
uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
uiDefButF(block, NUM, B_CLOTH_RENEW, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
uiDefBut(block, LABEL, 0, "Gravity:", 10,110,60,20, NULL, 0.0, 0, 0, 0, "");
uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,110,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,110,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,110,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,110,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiDefBut(block, LABEL, 0, "Gravity:", 10,90,60,20, NULL, 0.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,90,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,90,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,90,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiBlockEndAlign(block);
/* GOAL STUFF */
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth", 10,80,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth", 10,60,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0))
{
@@ -5273,13 +5281,13 @@ static void object_panel_cloth(Object *ob)
sprintf (clvg2, "%s%s", clmvg, clvg1);
uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,80,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,60,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (clvg1);
MEM_freeN (clvg2);
}
uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,60,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,40,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
uiDefBut(block, LABEL, 0, "",160,40,150,20, NULL, 0.0, 0, 0, 0, "");
// uiDefButI(block, NUM, B_CLOTH_RENEW, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
/*
// nobody is changing these ones anyway
@@ -5289,8 +5297,8 @@ static void object_panel_cloth(Object *ob)
}
else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
{
uiDefBut(block, LABEL, 0, " ", 160,80,150,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,50,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, " ", 160,60,150,20, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,30,300,20, NULL, 0.0, 0, 0, 0, "");
}
uiBlockEndAlign(block);