[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16059] trunk/blender/source/blender/ blenkernel/intern/softbody.c: bdiego no 2.47 option for now

Jens Ole Wund (bjornmose) bjornmose at gmx.net
Mon Aug 11 22:40:29 CEST 2008


Revision: 16059
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16059
Author:   bjornmose
Date:     2008-08-11 22:40:29 +0200 (Mon, 11 Aug 2008)

Log Message:
-----------
bdiego no 2.47 option for now
make soft bodies spawn threads on a mid level 
use G.rt == 16 to switch to 'old style'
i am going to remove that G.rt switch if everyone is fine /* i do not intend to keep 2 versions of code up because of "BAD STYLE" */
so .. give feed back .. 

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/softbody.c

Modified: trunk/blender/source/blender/blenkernel/intern/softbody.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/softbody.c	2008-08-11 20:01:15 UTC (rev 16058)
+++ trunk/blender/source/blender/blenkernel/intern/softbody.c	2008-08-11 20:40:29 UTC (rev 16059)
@@ -69,6 +69,8 @@
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_ghash.h"
+#include "BLI_threads.h"
+
 #include "BKE_curve.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
@@ -118,6 +120,20 @@
 	float aabbmin[3],aabbmax[3];
 }SBScratch;
 
+typedef struct  SB_thread_context{
+        Object *ob;
+		float forcetime;
+		float timenow;
+		int ifirst;
+		int ilast;
+		ListBase *do_effector;
+		int do_deflector;
+		float fieldfactor;
+		float windfactor;
+		int nr;
+		int tot;
+}SB_thread_context;
+
 #define NLF_BUILD  1 
 #define NLF_SOLVE  2 
 
@@ -1514,17 +1530,15 @@
 
 
 
-void scan_for_ext_spring_forces(Object *ob,float timenow)
+void _scan_for_ext_spring_forces(Object *ob,float timenow,int ifirst,int ilast, struct ListBase *do_effector)
 {
 	SoftBody *sb = ob->soft;
-	ListBase *do_effector;
 	int a;
 	float damp; 
 	float feedback[3];
-	do_effector= pdInitEffectors(ob,NULL);
 
 	if (sb && sb->totspring){
-		for(a=0; a<sb->totspring; a++) {
+		for(a=ifirst; a<ilast; a++) {
 			BodySpring *bs = &sb->bspring[a];
 			bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f; 
 			feedback[0]=feedback[1]=feedback[2]=0.0f;
@@ -1584,9 +1598,88 @@
 			}
 		}
 	}
-	if(do_effector)
-		pdEndEffectors(do_effector);
 }
+
+
+void scan_for_ext_spring_forces(Object *ob,float timenow)
+{
+  SoftBody *sb = ob->soft;
+  ListBase *do_effector= NULL; 
+  do_effector= pdInitEffectors(ob,NULL);
+  if (sb){
+  _scan_for_ext_spring_forces(ob,timenow,0,sb->totspring,do_effector);
+  }
+  if(do_effector)
+  pdEndEffectors(do_effector);
+}
+
+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())
+{
+    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 */
+
+	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();
+	}
+	/*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);
+	left = totsprings;
+	dec = totsprings/totthread +1;
+	for(i=0; i<totthread; i++) {
+		sb_threads[i].ob = ob; 
+		sb_threads[i].forcetime = 0.0; // not used here 
+		sb_threads[i].timenow = timenow; 
+		sb_threads[i].ilast   = left; 
+		left = left - dec;
+		if (left >0){
+			sb_threads[i].ifirst  = left;
+		}
+		else
+			sb_threads[i].ifirst  = 0; 
+        sb_threads[i].do_effector = do_effector;
+        sb_threads[i].do_deflector = 0;// not used here
+		sb_threads[i].fieldfactor = 0.0f;// not used here
+		sb_threads[i].windfactor  = 0.0f;// not used here
+		sb_threads[i].nr= i;
+		sb_threads[i].tot= totthread;
+	}
+	if(totthread > 1) {
+		BLI_init_threads(&threads, exec_scan_for_ext_spring_forces, totthread);
+
+		for(i=0; i<totthread; i++)
+			BLI_insert_thread(&threads, &sb_threads[i]);
+
+		BLI_end_threads(&threads);
+	}
+	else
+		exec_scan_for_ext_spring_forces(&sb_threads[0]);
+    /* clean up */
+	MEM_freeN(sb_threads);
+
+	  if(do_effector)
+  pdEndEffectors(do_effector);
+}
+
+
 /* --- the spring external section*/
 
 int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,float*cb,float*cc)
@@ -2023,109 +2116,72 @@
 }
 
 
-static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags)
+/* 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)
 {
-/* rule we never alter free variables :bp->vec bp->pos in here ! 
- * this will ruin adaptive stepsize AKA heun! (BM) 
- */
+	float iks;
+	int bb,do_selfcollision,do_springcollision,do_aero;
+	int number_of_points_here = ilast - ifirst;
 	SoftBody *sb= ob->soft;	/* is supposed to be there */
 	BodyPoint  *bp;
-	BodyPoint *bproot;
-	BodySpring *bs;	
-	ListBase *do_effector;
-	float iks, ks, kd, gravity;
-	float fieldfactor = 1000.0f, windfactor  = 250.0f;   
-	float tune = sb->ballstiff;
-	int a, b,  do_deflector,do_selfcollision,do_springcollision,do_aero;
-
-
-/* jacobian
-	NLboolean success;
-
-	if(nl_flags){
-		nlBegin(NL_SYSTEM);
-		nlBegin(NL_MATRIX);
-	}
-*/
-	
-	
-	gravity = sb->grav * sb_grav_force_scale(ob);	
-	
+	/* intitialize */
+	if (sb) {
 	/* check conditions for various options */
-	do_deflector= query_external_colliders(ob);
+    /* +++ could be done on object level to squeeze out the last bits of it */
 	do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
 	do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
 	do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
-	
-	iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
-	bproot= sb->bpoint; /* need this for proper spring addressing */
-	
-	if (do_springcollision || do_aero)  scan_for_ext_spring_forces(ob,timenow);
-	/* after spring scan because it uses Effoctors too */
-	do_effector= pdInitEffectors(ob,NULL);
+    /* --- could be done on object level to squeeze out the last bits of it */
+	}
+	else {
+		printf("Error expected a SB here \n");
+		return (999);
+	}
 
-	if (do_deflector) {
-		float defforce[3];
-		do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
+/* debugerin */
+	if  (sb->totpoint < ifirst) {
+		printf("Aye 998");
+		return (998);
 	}
+/* debugerin */
 
-	for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+	bp = &sb->bpoint[ifirst]; 
+	for(bb=number_of_points_here; bb>0; bb--, bp++) {
 		/* clear forces  accumulator */
 		bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
-		if(nl_flags & NLF_BUILD){
-			//int ia =3*(sb->totpoint-a);
-			//int op =3*sb->totpoint;
-			/* dF/dV = v */ 
-			/* jacobioan
-			nlMatrixAdd(op+ia,ia,-forcetime);
-			nlMatrixAdd(op+ia+1,ia+1,-forcetime);
-			nlMatrixAdd(op+ia+2,ia+2,-forcetime);
-     		
-			nlMatrixAdd(ia,ia,1);
-			nlMatrixAdd(ia+1,ia+1,1);
-			nlMatrixAdd(ia+2,ia+2,1);
-
-			nlMatrixAdd(op+ia,op+ia,1);
-			nlMatrixAdd(op+ia+1,op+ia+1,1);
-			nlMatrixAdd(op+ia+2,op+ia+2,1);
-			*/
-
-
-		}
-
 		/* naive ball self collision */
 		/* needs to be done if goal snaps or not */
 		if(do_selfcollision){
 			 	int attached;
 				BodyPoint   *obp;
+				BodySpring *bs;	
 				int c,b;
 				float velcenter[3],dvel[3],def[3];
 				float distance;
 				float compare;
+     	        float bstune = sb->ballstiff;
 
-				for(c=sb->totpoint, obp= sb->bpoint; c>=a; c--, obp++) {
-					
-					//if ((bp->octantflag & obp->octantflag) == 0) continue;
-
+				for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) {
 					compare = (obp->colball + bp->colball);		
 					VecSubf(def, bp->pos, obp->pos);
-
 					/* rather check the AABBoxes before ever calulating the real distance */
 					/* mathematically it is completly nuts, but performace is pretty much (3) times faster */
 					if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
-
                     distance = Normalize(def);
 					if (distance < compare ){
 						/* exclude body points attached with a spring */
 						attached = 0;
 						for(b=obp->nofsprings;b>0;b--){
 							bs = sb->bspring + obp->springs[b-1];
-							if (( sb->totpoint-a == bs->v2)  || ( sb->totpoint-a == bs->v1)){
+							if (( ilast-bb == bs->v2)  || ( ilast-bb == bs->v1)){
 								attached=1;
 								continue;}
 						}
 						if (!attached){
-							float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
+							float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ;
 
 							VecMidf(velcenter, bp->vec, obp->vec);
 							VecSubf(dvel,velcenter,bp->vec);
@@ -2134,38 +2190,12 @@
 							Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
 							Vec3PlusStVec(bp->force,sb->balldamp,dvel);
 
-							if(nl_flags & NLF_BUILD){
-								//int ia =3*(sb->totpoint-a);
-								//int ic =3*(sb->totpoint-c);
-								//int op =3*sb->totpoint;
-								//float mvel = forcetime*sb->nodemass*sb->balldamp;
-								//float mpos = forcetime*tune*(1.0f-sb->balldamp);
-								/*some quick and dirty entries to the jacobian*/
-								//dfdx_goal(ia,ia,op,mpos);
-								//dfdv_goal(ia,ia,mvel);
-								/* exploit force(a,b) == -force(b,a) part1/2 */
-								//dfdx_goal(ic,ic,op,mpos);
-								//dfdv_goal(ic,ic,mvel);
-								
-								
-								/*TODO sit down an X-out the true jacobian entries*/
-								/*well does not make to much sense because the eigenvalues
-								of the jacobian go negative; and negative eigenvalues
-								on a complex iterative system z(n+1)=A * z(n) 
-								give imaginary roots in the charcateristic polynom
-								--> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here 
-								where u(t) is a unknown amplitude function (worst case rising fast)
-								*/ 
-							}
-
 							/* exploit force(a,b) == -force(b,a) part2/2 */
 							VecSubf(dvel,velcenter,obp->vec);
 							VecMulf(dvel,sb->nodemass);
 
 							Vec3PlusStVec(obp->force,sb->balldamp,dvel);
 							Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
-
-
 						}
 					}
 				}
@@ -2179,20 +2209,13 @@
 			/* do goal stuff */
 			if(ob->softflag & OB_SB_GOAL) {
 				/* true elastic goal */
+				float ks,kd;
 				VecSubf(auxvect,bp->pos,bp->origT);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list