New softbody option: adjustable rigidity.

Gives local structure stability for though fabrics, thin steelplates ..
even suzanne gets pretty crash resistant that way.
If non zero it not only adds diagonals but all other "2edge-wide" springs
so it somehow replaces stiff quads for meshes too.
This commit is contained in:
Jens Ole Wund
2006-09-26 12:53:57 +00:00
parent e6251f6ae7
commit d8874df09c
3 changed files with 100 additions and 5 deletions

View File

@@ -537,6 +537,91 @@ static void add_mesh_quad_diag_springs(Object *ob)
}
}
static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int addsprings)
{
/*assume we have a softbody*/
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp,*bpo;
BodySpring *bs,*bs2,*bs3;
int a,b,c,notthis,v0;
if (!sb->bspring){return;} /* we are 2nd order here so 1rst should have been build :) */
/* first run counting second run adding */
/*run all body points*/
*counter = 0;
if (addsprings) bs3 = ob->soft->bspring+ob->soft->totspring;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/*scan for neighborhood*/
bpo = NULL;
v0 = (sb->totpoint-a);
for(b=bp->nofsprings;b>0;b--){
bs = sb->bspring + bp->springs[b-1];
/*nasty thing here that springs have two ends
so here we have to make sure we examine the other */
if (( v0 == bs->v1) ){
bpo =sb->bpoint+bs->v2;
notthis = bs->v2;
}
else {
if (( v0 == bs->v2) ){
bpo =sb->bpoint+bs->v1;
notthis = bs->v1;
}
else {printf("oops we should not get here - add_2nd_order_springs");}
}
if (bpo){/* so now we have a 2nd order humpdidump */
for(c=bpo->nofsprings;c>0;c--){
bs2 = sb->bspring + bpo->springs[c-1];
if ((bs2->v1 != notthis) && (bs2->v1 > v0)){
(*counter)++;/*hit */
if (addsprings){
bs3->v1= v0;
bs3->v2= bs2->v1;
bs3->strength= stiffness;
bs3++;
}
}
if ((bs2->v2 !=notthis)&&(bs2->v2 > v0)){
(*counter)++;/*hit */
if (addsprings){
bs3->v1= v0;
bs3->v2= bs2->v2;
bs3->strength= stiffness;
bs3++;
}
}
}
}
}
/*scan for neighborhood done*/
}
}
static void add_2nd_order_springs(Object *ob,float stiffness)
{
int counter = 0;
BodySpring *bs_new;
add_2nd_order_roller(ob,stiffness,&counter,0);
if (counter) {
/* printf("Added %d springs \n", counter); */
/* resize spring-array to hold additional springs */
bs_new= MEM_callocN( (ob->soft->totspring + counter )*sizeof(BodySpring), "bodyspring");
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
if(ob->soft->bspring)
MEM_freeN(ob->soft->bspring);
ob->soft->bspring = bs_new;
add_2nd_order_roller(ob,stiffness,&counter,1);
ob->soft->totspring +=counter ;
}
}
static void add_bp_springlist(BodyPoint *bp,int springID)
{
@@ -1026,6 +1111,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
forcefactor = (bs->len - actspringlen)/bs->len * iks;
else
forcefactor = actspringlen * iks;
forcefactor *= bs->strength;
Vec3PlusStVec(bp->force,-forcefactor,sd);
@@ -1048,6 +1134,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
forcefactor = (bs->len - actspringlen)/bs->len * iks;
else
forcefactor = actspringlen * iks;
forcefactor *= bs->strength;
Vec3PlusStVec(bp->force,+forcefactor,sd);
}
}/* loop springs */
@@ -1337,6 +1424,12 @@ static void mesh_to_softbody(Object *ob)
}
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
/* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) {
add_2nd_order_springs(ob,sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/
build_bps_springlist(ob); /* yes we need to do it again*/
}
springs_from_mesh(ob); /* write the 'rest'-lenght of the springs */
}
}

View File

@@ -97,7 +97,8 @@ typedef struct SoftBody {
SBVertex **keys; /* array of size totpointkey */
int totpointkey, totkey; /* if totpointkey != totpoint or totkey!- (efra-sfra)/interval -> free keys */
float secondspring;
float pad3; /* local==1: use local coords for baking */
} SoftBody;
/* pd->forcefield: Effector Fields types */

View File

@@ -2309,11 +2309,12 @@ static void object_softbodies(Object *ob)
else {
/* GENERAL STUFF */
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 10.0, 10, 0, "General media friction for point movements");
uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
uiDefButF(block, NUM, B_DIFF, "Mass:", 160, 170,150,20, &sb->nodemass , 0.001, 50.0, 10, 0, "Point Mass, the heavier the slower");
uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_DIFF, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
uiDefButF(block, NUM, B_DIFF, "Error Limit:", 10,130,150,20, &sb->rklimit , 0.01, 1.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
uiDefButF(block, NUM, B_DIFF, "Error Limit:", 10,130,150,20, &sb->rklimit , 0.01, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Rigidity:", 160,130,150,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Strenght of Springs over 2 Edges");
uiBlockEndAlign(block);
/* GOAL STUFF */
@@ -2344,7 +2345,7 @@ static void object_softbodies(Object *ob)
}
uiDefButF(block, NUM, B_DIFF, "G Stiff:", 10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
uiDefButF(block, NUM, B_DIFF, "G Damp:", 160,80,150,20, &sb->goalfrict , 0.0, 10.0, 10, 0, "Goal (vertex target position) friction");
uiDefButF(block, NUM, B_DIFF, "G Damp:", 160,80,150,20, &sb->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Min:", 10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Max:", 160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
uiBlockEndAlign(block);
@@ -2355,7 +2356,7 @@ static void object_softbodies(Object *ob)
uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,10,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 10.0, 10, 0, "Edge spring friction");
uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
uiBlockEndAlign(block);
}
}