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:
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user