diff options
author | Jens Ole Wund <bjornmose@gmx.net> | 2009-11-04 03:21:25 +0300 |
---|---|---|
committer | Jens Ole Wund <bjornmose@gmx.net> | 2009-11-04 03:21:25 +0300 |
commit | 2a8ef208b2ca6d7d69f317847d1ce06a2a740c9a (patch) | |
tree | a440756f942874713d4ec60233c023c5237d953e /source/blender/blenkernel/intern/softbody.c | |
parent | c8ee492e7afe877c6ba85cd9b814cce8419b62cd (diff) |
Soft bodies care for real time
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 95 |
1 files changed, 48 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 599630fe0a0..6e986325f55 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -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; |