Soft bodies care for real time
authorJens Ole Wund <bjornmose@gmx.net>
Wed, 4 Nov 2009 00:21:25 +0000 (00:21 +0000)
committerJens Ole Wund <bjornmose@gmx.net>
Wed, 4 Nov 2009 00:21:25 +0000 (00:21 +0000)
source/blender/blenkernel/intern/softbody.c

index 599630fe0a0228fbef781184061ac55bf3e3f66d..6e986325f551b70efce0858375e5b7ff3b400236 100644 (file)
@@ -92,12 +92,13 @@ static int (*SB_localInterruptCallBack)(void) = NULL;
 
 /* ********** soft body engine ******* */
 
+typedef        enum {SB_EDGE=1,SB_BEND=2,SB_STIFFQUAD=3} type_spring;
 
 typedef struct BodySpring {
        int v1, v2;
-       float len, strength, cf,load;
+       float len,cf,load;
        float ext_force[3]; /* edges colliding and sailing */
-       short order;
+       type_spring springtype;
        short flag;
 } BodySpring;
 
@@ -613,13 +614,11 @@ static void add_mesh_quad_diag_springs(Object *ob)
                                        if(mface->v4) {
                                                bs->v1= mface->v1;
                                                bs->v2= mface->v3;
-                                               bs->strength= s_shear;
-                                               bs->order   =2;
+                                               bs->springtype   =SB_STIFFQUAD;
                                                bs++;
                                                bs->v1= mface->v2;
                                                bs->v2= mface->v4;
-                                               bs->strength= s_shear;
-                                               bs->order   =2;
+                                               bs->springtype   =SB_STIFFQUAD;
                                                bs++;
                                                
                                        }
@@ -670,8 +669,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
                                                if (addsprings){
                                                        bs3->v1= v0;
                                                        bs3->v2= bs2->v1;
-                                                       bs3->strength= stiffness;
-                                                       bs3->order=2;
+                                                   bs3->springtype   =SB_BEND;
                                                        bs3++;
                                                }
                                        }
@@ -680,8 +678,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
                                                if (addsprings){
                                                        bs3->v1= v0;
                                                        bs3->v2= bs2->v2;
-                                                       bs3->strength= stiffness;
-                                                       bs3->order=2;
+                                                   bs3->springtype   =SB_BEND;
                                                        bs3++;
                                                }
 
@@ -785,7 +782,7 @@ static void calculate_collision_balls(Object *ob)
                /* first estimation based on attached */
                for(b=bp->nofsprings;b>0;b--){
                        bs = sb->bspring + bp->springs[b-1];
-                       if (bs->order == 1){
+                       if (bs->springtype == SB_EDGE){
                        akku += bs->len;
                        akku_count++,
                        min = MIN2(bs->len,min);
@@ -1529,7 +1526,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
                        feedback[0]=feedback[1]=feedback[2]=0.0f;
                        bs->flag &= ~BSF_INTERSECT;
 
-                       if (bs->order ==1){
+                       if (bs->springtype == SB_EDGE){
                                /* +++ springs colliding */
                                if (ob->softflag & OB_SB_EDGECOLL){
                                        if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
@@ -2074,10 +2071,24 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo
                forcefactor = iks/bs->len;
        else
                forcefactor = iks;
-           kw = (bp1->springweight+bp2->springweight)/2.0f;
-               kw = kw * kw;
-               kw = kw * kw;
-       forcefactor *= bs->strength * kw; 
+       kw = (bp1->springweight+bp2->springweight)/2.0f;
+       kw = kw * kw;
+       kw = kw * kw;
+       switch (bs->springtype){
+               case SB_EDGE:
+                       forcefactor *=  kw; 
+                       break;
+               case SB_BEND:
+                       forcefactor *=sb->secondspring*kw; 
+                       break;
+               case SB_STIFFQUAD:
+                       forcefactor *=sb->shearstiff*sb->shearstiff* kw; 
+                       break;
+               default:
+                       break;
+       }
+
+
        Vec3PlusStVec(bp1->force,(bs->len - distance)*forcefactor,dir);
 
        /* do bp1 <--> bp2 viscous */
@@ -3275,8 +3286,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
                        for(a=me->totedge; a>0; a--, medge++, bs++) {
                                bs->v1= medge->v1;
                                bs->v2= medge->v2;
-                               bs->strength= 1.0;
-                               bs->order=1;
+                               bs->springtype=SB_EDGE;
                        }
                        
                        
@@ -3354,44 +3364,39 @@ static void makelatticesprings(Lattice *lt,     BodySpring *bs, int dostiff,Object *
                                if(w) {
                                        bs->v1 = bpc;
                                        bs->v2 = bpc-dw;
-                                   bs->strength= 1.0;
-                                       bs->order=1;
+                                       bs->springtype=SB_EDGE;
                                        bs->len= globallen((bp-dw)->vec, bp->vec,ob);
                                        bs++;
                                }
                                if(v) {
                                        bs->v1 = bpc;
                                        bs->v2 = bpc-dv;
-                                   bs->strength= 1.0;
-                                       bs->order=1;
+                                       bs->springtype=SB_EDGE;
                                        bs->len= globallen((bp-dv)->vec, bp->vec,ob);
                                        bs++;
                                }
                                if(u) {
                                        bs->v1 = bpuc;
                                        bs->v2 = bpc;
-                                   bs->strength= 1.0;
-                                       bs->order=1;
+                                       bs->springtype=SB_EDGE;
                                        bs->len= globallen((bpu)->vec, bp->vec,ob);
                                        bs++;
                                }
                                
                                if (dostiff) {
 
-                                       if(w){
+                                       if(w){
                                                if( v && u ) {
                                                        bs->v1 = bpc;
                                                        bs->v2 = bpc-dw-dv-1;
-                                                       bs->strength= 1.0;
-                                       bs->order=2;
+                                                       bs->springtype=SB_BEND;
                                                        bs->len= globallen((bp-dw-dv-1)->vec, bp->vec,ob);
                                                        bs++;
                                                }                                               
                                                if( (v < lt->pntsv-1) && (u) ) {
                                                        bs->v1 = bpc;
                                                        bs->v2 = bpc-dw+dv-1;
-                                                       bs->strength= 1.0;
-                                       bs->order=2;
+                                                       bs->springtype=SB_BEND;
                                                        bs->len= globallen((bp-dw+dv-1)->vec, bp->vec,ob);
                                                        bs++;
                                                }                                               
@@ -3401,16 +3406,14 @@ static void makelatticesprings(Lattice *lt,     BodySpring *bs, int dostiff,Object *
                                                if( v && u ) {
                                                        bs->v1 = bpc;
                                                        bs->v2 = bpc+dw-dv-1;
-                                                       bs->strength= 1.0;
-                                       bs->order=2;
+                                                       bs->springtype=SB_BEND;
                                                        bs->len= globallen((bp+dw-dv-1)->vec, bp->vec,ob);
                                                        bs++;
                                                }                                               
                                                if( (v < lt->pntsv-1) && (u) ) {
                                                        bs->v1 = bpc;
                                                        bs->v2 = bpc+dw+dv-1;
-                                                       bs->strength= 1.0;
-                                       bs->order=2;
+                                                       bs->springtype=SB_BEND;
                                                         bs->len= globallen((bp+dw+dv-1)->vec, bp->vec,ob);
                                                        bs++;
                                                }                                               
@@ -3520,22 +3523,19 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
                                        if(a>0) {
                                                bs->v1= curindex-1;
                                                bs->v2= curindex;
-                                               bs->strength= 1.0;
-                                               bs->order=1;
+                                               bs->springtype=SB_EDGE;
                                                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->springtype=SB_EDGE;
                                        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->springtype=SB_EDGE;
                                        bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
                                        bs++;
                                }
@@ -3551,8 +3551,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
                                if(totspring && a>0) {
                                        bs->v1= curindex-1;
                                        bs->v2= curindex;
-                                       bs->strength= 1.0;
-                                       bs->order=1;
+                                       bs->springtype=SB_EDGE;
                                        bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob );
                                        bs++;
                                }
@@ -3773,9 +3772,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
                
                
        sst=PIL_check_seconds_timer();
-       /* integration back in time is possible in theory, but pretty useless here 
-       so refuse to do so */
-       if(dtime < 0) return; 
+       /* Integration back in time is possible in theory, but pretty useless here. 
+       So we refuse to do so. Since we do not know anything about 'outside' canges
+       especially colliders we refuse to go more than 10 frames.
+       */
+       if(dtime < 0 || dtime > 10.5f) return; 
        
        ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
 
@@ -3858,7 +3859,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
                        loops++;
                        if(sb->solverflags & SBSO_MONITOR ){
                                sct=PIL_check_seconds_timer();
-                               if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
+                               if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone/dtime);
                        }
                        /* ask for user break */ 
                        if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
@@ -4027,11 +4028,11 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
        /* checking time: */
        dtime = framedelta*timescale;
 
+       /* do simulation */
        softbody_step(scene, ob, sb, dtime);
 
        softbody_to_object(ob, vertexCos, numVerts, 0);
 
-       /* do simulation */
        cache->simframe= framenr;
        cache->flag |= PTCACHE_SIMULATION_VALID;