softbody self collision

ironing out a few glitches related to goal pinning
volatile test blend ->
http://www.wund.homepage.t-online.de/hidden/sb_col_must.blend
+ adding a few alternative collision ball calculation algos
since i did not want to blow up (waste)  DNA space without need,
coded as -1.0 -0.1 -1.1 values in 'ball size' (look at tooltip popup)
This commit is contained in:
Jens Ole Wund 2006-10-04 21:36:55 +00:00
parent 0c6bb8c079
commit 21d6b199ab
2 changed files with 41 additions and 12 deletions

@ -98,6 +98,7 @@ typedef struct BodyPoint {
typedef struct BodySpring {
int v1, v2;
float len, strength;
short order;
} BodySpring;
@ -522,10 +523,12 @@ static void add_mesh_quad_diag_springs(Object *ob)
bs->v1= mface->v1;
bs->v2= mface->v3;
bs->strength= 1.0;
bs->order =2;
bs++;
bs->v1= mface->v2;
bs->v2= mface->v4;
bs->strength= 1.0;
bs->order =2;
bs++;
}
@ -578,6 +581,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
bs3->v1= v0;
bs3->v2= bs2->v1;
bs3->strength= stiffness;
bs3->order=2;
bs3++;
}
}
@ -587,6 +591,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
bs3->v1= v0;
bs3->v2= bs2->v2;
bs3->strength= stiffness;
bs3->order=2;
bs3++;
}
@ -679,34 +684,47 @@ static void calculate_collision_balls(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp;
BodySpring *bs;
int a,b;
float min,max;
int a,b,akku_count;
float min,max,akku;
if (sb==NULL) return; /* paranoya check */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
bp->colball=0;
akku =0.0f;
akku_count=0;
min = 1e22f;
max = -1e22f;
/* first estimation based on attached */
for(b=bp->nofsprings;b>0;b--){
bs = sb->bspring + bp->springs[b-1];
bp->colball += bs->len;
if (bs->order == 1){
akku += bs->len;
akku_count++,
min = MIN2(bs->len,min);
max = MAX2(bs->len,max);
}
}
if (bp->nofsprings != 0) {
/*bp->colball /= bp->nofsprings;*/
bp->colball = (min + max)/2.0f;
if (akku_count > 0) {
bp->colball = akku/(float)akku_count;
/* i don't want to taint a "short pad" member in SDNA yet
so hack alternatives in that way */
if (sb->colball > 0.0f){
bp->colball=sb->colball;
}
if (sb->colball == -1.0f){
bp->colball=max;
}
if (sb->colball == -0.1f){
bp->colball=min;
}
if (sb->colball == -1.1f){
bp->colball = (min + max)/2.0f;
}
}
else bp->colball=0;
/* printf("CB %f \n",bp->colball); */
}/*for bp*/
}
@ -1047,14 +1065,13 @@ static void softbody_calc_forces(Object *ob, float forcetime)
BodyPoint *obp;
int c,b;
float def[3];
float tune2 = 0.5f;
float tune = 1.0f;
float distance;
float compare;
for(c=sb->totpoint, obp= sb->bpoint; c>0; c--, obp++) {
if (c < a ) continue; /* exploit force(a,b) == force(b,a) part1/2 */
compare = (obp->colball + bp->colball) * tune2;
compare = (obp->colball + bp->colball);
VecSubf(def, bp->pos, obp->pos);
distance = Normalise(def);
if (distance < compare ){
@ -1091,9 +1108,9 @@ static void softbody_calc_forces(Object *ob, float forcetime)
/* true elastic goal */
VecSubf(auxvect,bp->origT,bp->pos);
ks = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
bp->force[0]= ks*(auxvect[0]);
bp->force[1]= ks*(auxvect[1]);
bp->force[2]= ks*(auxvect[2]);
bp->force[0]+= ks*(auxvect[0]);
bp->force[1]+= ks*(auxvect[1]);
bp->force[2]+= ks*(auxvect[2]);
/* calulate damping forces generated by goals*/
VecSubf(velgoal,bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob) ;
@ -1503,6 +1520,7 @@ static void mesh_to_softbody(Object *ob)
bs->v1= medge->v1;
bs->v2= medge->v2;
bs->strength= 1.0;
bs->order=1;
}
@ -1558,6 +1576,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc-dw;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen((bp-dw)->vec, bp->vec,ob);
bs++;
}
@ -1565,6 +1584,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc-dv;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen((bp-dv)->vec, bp->vec,ob);
bs++;
}
@ -1572,6 +1592,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpuc;
bs->v2 = bpc;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen((bpu)->vec, bp->vec,ob);
bs++;
}
@ -1583,6 +1604,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc-dw-dv-1;
bs->strength= 1.0;
bs->order=2;
bs->len= globallen((bp-dw-dv-1)->vec, bp->vec,ob);
bs++;
}
@ -1590,6 +1612,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc-dw+dv-1;
bs->strength= 1.0;
bs->order=2;
bs->len= globallen((bp-dw+dv-1)->vec, bp->vec,ob);
bs++;
}
@ -1600,6 +1623,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc+dw-dv-1;
bs->strength= 1.0;
bs->order=2;
bs->len= globallen((bp+dw-dv-1)->vec, bp->vec,ob);
bs++;
}
@ -1607,6 +1631,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->v1 = bpc;
bs->v2 = bpc+dw+dv-1;
bs->strength= 1.0;
bs->order=2;
bs->len= globallen((bp+dw+dv-1)->vec, bp->vec,ob);
bs++;
}
@ -1717,18 +1742,21 @@ static void curve_surf_to_softbody(Object *ob)
bs->v1= curindex-1;
bs->v2= curindex;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob );
bs++;
}
bs->v1= curindex;
bs->v2= curindex+1;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen( bezt->vec[0], bezt->vec[1], ob );
bs++;
bs->v1= curindex+1;
bs->v2= curindex+2;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
bs++;
}
@ -1745,6 +1773,7 @@ static void curve_surf_to_softbody(Object *ob)
bs->v1= curindex-1;
bs->v2= curindex;
bs->strength= 1.0;
bs->order=1;
bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob );
bs++;
}

@ -2319,7 +2319,7 @@ static void object_softbodies(Object *ob)
if(ob->softflag & OB_SB_COLLISIONSET) {
/* COLLISION STUFF */
uiDefButBitS(block, TOG, OB_SB_SELF, B_SOFTBODY_CHANGE, "Self Collision", 10,170,90,20, &ob->softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Ball Size:", 110,170,170,20, &sb->colball, -10.0, 10.0, 10, 0, "col. ball size ==0 auto, >0 set collision ball manual, -1 use longest attached spring for ball radius");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Ball Size:", 110,170,170,20, &sb->colball, -10.0, 10.0, 10, 0, "col. ball size ==0 average spring lenght, >0 set collision ball manual, -1.0 max, -0.1 min ,-1.1 (min+max)/2");
/* OTHER OBJECTS COLLISION STUFF */
uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to other softbody objects");
if(ob->pd->deflect) {