diff options
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 120 |
1 files changed, 71 insertions, 49 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index d465c058d30..5d93f10526a 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -236,7 +236,7 @@ typedef struct ccd_Mesh { -ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm) +static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm) { ccd_Mesh *pccd_M = NULL; ccdf_minmax *mima =NULL; @@ -333,7 +333,7 @@ ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm) } return pccd_M; } -void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm) +static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm) { ccdf_minmax *mima =NULL; MFace *mface=NULL; @@ -472,7 +472,7 @@ void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm) return ; } -void ccd_mesh_free(ccd_Mesh *ccdm) +static void ccd_mesh_free(ccd_Mesh *ccdm) { if(ccdm && (ccdm->savety == CCD_SAVETY )){ /*make sure we're not nuking objects we don't know*/ MEM_freeN(ccdm->mface); @@ -484,7 +484,7 @@ void ccd_mesh_free(ccd_Mesh *ccdm) } } -void ccd_build_deflector_hache(Object *vertexowner,GHash *hash) +static void ccd_build_deflector_hache(Object *vertexowner,GHash *hash) { Base *base; Object *ob; @@ -536,7 +536,7 @@ void ccd_build_deflector_hache(Object *vertexowner,GHash *hash) } /* while (base) */ } -void ccd_update_deflector_hache(Object *vertexowner,GHash *hash) +static void ccd_update_deflector_hache(Object *vertexowner,GHash *hash) { Base *base; Object *ob; @@ -991,7 +991,7 @@ static int query_external_colliders(Object *me) /* +++ the aabb "force" section*/ -int sb_detect_aabb_collisionCached( float force[3], unsigned int par_layer,struct Object *vertexowner,float time) +static int sb_detect_aabb_collisionCached( float force[3], unsigned int par_layer,struct Object *vertexowner,float time) { Object *ob; SoftBody *sb=vertexowner->soft; @@ -1055,7 +1055,7 @@ int sb_detect_aabb_collisionCached( float force[3], unsigned int par_layer,struc /* +++ the face external section*/ -int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp, +static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp, float force[3], unsigned int par_layer,struct Object *vertexowner,float time) { Object *ob; @@ -1153,7 +1153,7 @@ int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3 } -int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp, +static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp, float force[3], unsigned int par_layer,struct Object *vertexowner,float time) { Object *ob; @@ -1291,7 +1291,7 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_ -void scan_for_ext_face_forces(Object *ob,float timenow) +static void scan_for_ext_face_forces(Object *ob,float timenow) { SoftBody *sb = ob->soft; BodyFace *bf; @@ -1379,7 +1379,7 @@ void scan_for_ext_face_forces(Object *ob,float timenow) /* +++ the spring external section*/ -int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp, +static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp, float force[3], unsigned int par_layer,struct Object *vertexowner,float time) { Object *ob; @@ -1530,7 +1530,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp -void _scan_for_ext_spring_forces(Object *ob,float timenow,int ifirst,int ilast, struct ListBase *do_effector) +static void _scan_for_ext_spring_forces(Object *ob,float timenow,int ifirst,int ilast, struct ListBase *do_effector) { SoftBody *sb = ob->soft; int a; @@ -1601,7 +1601,7 @@ void _scan_for_ext_spring_forces(Object *ob,float timenow,int ifirst,int ilast, } -void scan_for_ext_spring_forces(Object *ob,float timenow) +static void scan_for_ext_spring_forces(Object *ob,float timenow) { SoftBody *sb = ob->soft; ListBase *do_effector= NULL; @@ -1613,32 +1613,32 @@ void scan_for_ext_spring_forces(Object *ob,float timenow) pdEndEffectors(do_effector); } -void *exec_scan_for_ext_spring_forces(void *data) +static void *exec_scan_for_ext_spring_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; _scan_for_ext_spring_forces(pctx->ob,pctx->timenow,pctx->ifirst,pctx->ilast,pctx->do_effector); return 0; } -void sb_sfesf_threads_run(struct Object *ob, float timenow,int totsprings,int *ptr_to_break_func()) +static void sb_sfesf_threads_run(struct Object *ob, float timenow,int totsprings,int *ptr_to_break_func()) { - ListBase *do_effector = NULL; + ListBase *do_effector = NULL; ListBase threads; SB_thread_context *sb_threads; int i, totthread,left,dec; - int lowsprings =10; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ + int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ do_effector= pdInitEffectors(ob,NULL); /* figure the number of threads while preventing pretty pointless threading overhead */ - if(totsprings < lowsprings) {totthread=1;} - else{ - if(G.scene->r.mode & R_FIXED_THREADS) - totthread= G.scene->r.threads; - else - totthread= BLI_system_thread_count(); + if(G.scene->r.mode & R_FIXED_THREADS) + totthread= G.scene->r.threads; + else + totthread= BLI_system_thread_count(); + /* what if we got zillions of CPUs running but less to spread*/ + while ((totsprings/totthread < lowsprings) && (totthread > 1)) { + totthread--; } - /*left to do--> what if we got zillions of CPUs running but 'totsprings' tasks to spread*/ sb_threads= MEM_callocN(sizeof(SB_thread_context)*totthread, "SBSpringsThread"); memset(sb_threads, 0, sizeof(SB_thread_context)*totthread); @@ -1682,7 +1682,7 @@ void sb_sfesf_threads_run(struct Object *ob, float timenow,int totsprings,int *p /* --- the spring external section*/ -int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,float*cb,float*cc) +static int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,float*cb,float*cc) { float mindist,cp; int winner =1; @@ -1709,7 +1709,7 @@ int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,float*cb, -int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp, +static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp, float force[3], unsigned int par_layer,struct Object *vertexowner, float time,float vel[3], float *intrusion) { @@ -2119,7 +2119,7 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo /* since this is definitely the most CPU consuming task here .. try to spread it */ /* core function _softbody_calc_forces_slice_in_a_thread */ /* result is int to be able to flag user break */ -int _softbody_calc_forces_slice_in_a_thread(Object *ob, float forcetime, float timenow,int ifirst,int ilast,int *ptr_to_break_func(),ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor) +static int _softbody_calc_forces_slice_in_a_thread(Object *ob, float forcetime, float timenow,int ifirst,int ilast,int *ptr_to_break_func(),ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor) { float iks; int bb,do_selfcollision,do_springcollision,do_aero; @@ -2279,6 +2279,11 @@ int _softbody_calc_forces_slice_in_a_thread(Object *ob, float forcetime, float t float kd = 1.0f; if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){ + if (intrusion < 0.0f){ + sb->scratch->flag |= SBF_DOFUZZY; + bp->flag |= SBF_DOFUZZY; + bp->choke = sb->choke*0.01f; + } VECSUB(cfforce,bp->vec,vel); Vec3PlusStVec(bp->force,-cf*50.0f,cfforce); @@ -2314,29 +2319,31 @@ int _softbody_calc_forces_slice_in_a_thread(Object *ob, float forcetime, float t return 0; /*done fine*/ } -void *exec_softbody_calc_forces(void *data) +static void *exec_softbody_calc_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; _softbody_calc_forces_slice_in_a_thread(pctx->ob,pctx->forcetime,pctx->timenow,pctx->ifirst,pctx->ilast,NULL,pctx->do_effector,pctx->do_deflector,pctx->fieldfactor,pctx->windfactor); return 0; } -void sb_cf_threads_run(struct Object *ob, float forcetime, float timenow,int totpoint,int *ptr_to_break_func(),struct ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor) +static void sb_cf_threads_run(struct Object *ob, float forcetime, float timenow,int totpoint,int *ptr_to_break_func(),struct ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor) { ListBase threads; SB_thread_context *sb_threads; int i, totthread,left,dec; - int lowpoints =10; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ + int lowpoints =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ /* figure the number of threads while preventing pretty pointless threading overhead */ - if(totpoint < lowpoints) {totthread=1;} - else{ - if(G.scene->r.mode & R_FIXED_THREADS) - totthread= G.scene->r.threads; - else - totthread= BLI_system_thread_count(); + if(G.scene->r.mode & R_FIXED_THREADS) + totthread= G.scene->r.threads; + else + totthread= BLI_system_thread_count(); + /* what if we got zillions of CPUs running but less to spread*/ + while ((totpoint/totthread < lowpoints) && (totthread > 1)) { + totthread--; } - /*left to do--> what if we got zillions of CPUs running but 'totpoint' tasks to spread*/ + + /* printf("sb_cf_threads_run spawning %d threads \n",totthread); */ sb_threads= MEM_callocN(sizeof(SB_thread_context)*totthread, "SBThread"); memset(sb_threads, 0, sizeof(SB_thread_context)*totthread); @@ -2425,7 +2432,7 @@ static void softbody_calc_forcesEx(Object *ob, float forcetime, float timenow, i static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags) { /* redirection to the new threaded Version */ - if (G.rt !=16){ + if (!(G.rt & 0x10)){ // 16 softbody_calc_forcesEx(ob, forcetime, timenow, nl_flags); return; } @@ -2433,6 +2440,10 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int /* so the following will die */ /* |||||||||||||||||||||||||| */ /* VVVVVVVVVVVVVVVVVVVVVVVVVV */ + /*backward compatibility note: + fixing bug [17428] which forces adaptive step size to tiny steps + in some situations + .. keeping G.rt==17 0x11 option for old files 'needing' the bug*/ /* rule we never alter free variables :bp->vec bp->pos in here ! * this will ruin adaptive stepsize AKA heun! (BM) @@ -2681,14 +2692,25 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){ if ((!nl_flags)&&(intrusion < 0.0f)){ - /*bjornmose: uugh.. what an evil hack - violation of the 'don't touch bp->pos in here' rule - but works nice, like this--> - we predict the solution beeing out of the collider - in heun step No1 and leave the heun step No2 adapt to it - so we kind of introduced a implicit solver for this case - */ - Vec3PlusStVec(bp->pos,-intrusion,facenormal); + if(G.rt & 0x01){ // 17 we did check for bit 0x10 before + /*fixing bug [17428] this forces adaptive step size to tiny steps + in some situations .. keeping G.rt==17 option for old files 'needing' the bug + */ + /*bjornmose: uugh.. what an evil hack + violation of the 'don't touch bp->pos in here' rule + but works nice, like this--> + we predict the solution beeing out of the collider + in heun step No1 and leave the heun step No2 adapt to it + so we kind of introduced a implicit solver for this case + */ + Vec3PlusStVec(bp->pos,-intrusion,facenormal); + } + else{ + + VECSUB(cfforce,bp->vec,vel); + Vec3PlusStVec(bp->force,-cf*50.0f,cfforce); + } + sb->scratch->flag |= SBF_DOFUZZY; bp->flag |= SBF_DOFUZZY; @@ -3045,7 +3067,7 @@ static void softbody_apply_goalsnap(Object *ob) } -void apply_spring_memory(Object *ob) +static void apply_spring_memory(Object *ob) { SoftBody *sb = ob->soft; BodySpring *bs; @@ -3271,7 +3293,7 @@ static void mesh_faces_to_scratch(Object *ob) helper function to get proper spring length when object is rescaled */ -float globallen(float *v1,float *v2,Object *ob) +static float globallen(float *v1,float *v2,Object *ob) { float p1[3],p2[3]; VECCOPY(p1,v1); @@ -3689,7 +3711,7 @@ static int softbody_read_cache(Object *ob, float framenr) } /* +++ ************ maintaining scratch *************** */ -void sb_new_scratch(SoftBody *sb) +static void sb_new_scratch(SoftBody *sb) { if (!sb) return; sb->scratch = MEM_callocN(sizeof(SBScratch), "SBScratch"); @@ -4040,7 +4062,7 @@ static void softbody_step(Object *ob, SoftBody *sb, float dtime) if(sb->solverflags & SBSO_MONITOR ){ sct=PIL_check_seconds_timer(); - if (sct-sst > 0.5f) printf(" solver time %f sec %s \n",sct-sst,ob->id.name); + if ((sct-sst > 0.5f) || (G.f & G_DEBUG)) printf(" solver time %f sec %s \n",sct-sst,ob->id.name); } } |