New softbody option: adjustable rigidity.
authorJens Ole Wund <bjornmose@gmx.net>
Tue, 26 Sep 2006 12:53:57 +0000 (12:53 +0000)
committerJens Ole Wund <bjornmose@gmx.net>
Tue, 26 Sep 2006 12:53:57 +0000 (12:53 +0000)
Gives local structure stability for though fabrics, thin steelplates ..
even suzanne gets pretty crash resistant that way.
If non zero it not only adds diagonals but all other "2edge-wide" springs
so it somehow replaces stiff quads for meshes too.

source/blender/blenkernel/intern/softbody.c
source/blender/makesdna/DNA_object_force.h
source/blender/src/buttons_object.c

index bdc9b2342ee9cc75a076dc2b4f9a2af657ee986a..06b285fb0e88cde8c86cf8e8541dbb6f1ab9336b 100644 (file)
@@ -537,6 +537,91 @@ static void add_mesh_quad_diag_springs(Object *ob)
        }
 }
 
+static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int addsprings)
+{
+       /*assume we have a softbody*/
+       SoftBody *sb= ob->soft; /* is supposed to be there */
+       BodyPoint *bp,*bpo;     
+       BodySpring *bs,*bs2,*bs3;       
+       int a,b,c,notthis,v0;
+       if (!sb->bspring){return;} /* we are 2nd order here so 1rst should have been build :) */
+       /* first run counting  second run adding */
+       /*run all body points*/
+       *counter = 0;
+       if (addsprings) bs3 = ob->soft->bspring+ob->soft->totspring;
+       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+               /*scan for neighborhood*/
+               bpo = NULL;
+               v0  = (sb->totpoint-a);
+               for(b=bp->nofsprings;b>0;b--){
+                       bs = sb->bspring + bp->springs[b-1];
+                       /*nasty thing here that springs have two ends
+                       so here we have to make sure we examine the other */
+                       if (( v0 == bs->v1) ){ 
+                               bpo =sb->bpoint+bs->v2;
+                               notthis = bs->v2;
+                       }
+                       else {
+                       if (( v0 == bs->v2) ){
+                               bpo =sb->bpoint+bs->v1;
+                               notthis = bs->v1;
+                       } 
+                       else {printf("oops we should not get here -  add_2nd_order_springs");}
+                       }
+            if (bpo){/* so now we have a 2nd order humpdidump */
+                               for(c=bpo->nofsprings;c>0;c--){
+                                       bs2 = sb->bspring + bpo->springs[c-1];
+                                       if ((bs2->v1 != notthis)  && (bs2->v1 > v0)){
+                                               (*counter)++;/*hit */
+                                               if (addsprings){
+                                                       bs3->v1= v0;
+                                                       bs3->v2= bs2->v1;
+                                                       bs3->strength= stiffness;
+                                                       bs3++;
+                                               }
+                                       }
+                                       if ((bs2->v2 !=notthis)&&(bs2->v2 > v0)){
+                                       (*counter)++;/*hit */
+                                               if (addsprings){
+                                                       bs3->v1= v0;
+                                                       bs3->v2= bs2->v2;
+                                                       bs3->strength= stiffness;
+                                                       bs3++;
+                                               }
+
+                                       }
+                               }
+                               
+                       }
+                       
+               }
+               /*scan for neighborhood done*/
+       }
+}
+
+
+static void add_2nd_order_springs(Object *ob,float stiffness)
+{
+       int counter = 0;
+       BodySpring *bs_new;
+       
+       add_2nd_order_roller(ob,stiffness,&counter,0);
+       if (counter) {
+               /* printf("Added %d springs \n", counter); */
+               /* resize spring-array to hold additional springs */
+               bs_new= MEM_callocN( (ob->soft->totspring + counter )*sizeof(BodySpring), "bodyspring");
+               memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
+               
+               if(ob->soft->bspring)
+                       MEM_freeN(ob->soft->bspring); 
+               ob->soft->bspring = bs_new; 
+               
+               
+               add_2nd_order_roller(ob,stiffness,&counter,1);
+               ob->soft->totspring +=counter ;
+       }
+       
+}
 
 static void add_bp_springlist(BodyPoint *bp,int springID)
 {
@@ -1026,6 +1111,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
                                                                forcefactor = (bs->len - actspringlen)/bs->len * iks;
                                                        else
                                                                forcefactor = actspringlen * iks;
+                                                       forcefactor *= bs->strength; 
                                                        
                                                        Vec3PlusStVec(bp->force,-forcefactor,sd);
                                                        
@@ -1048,6 +1134,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
                                                                forcefactor = (bs->len - actspringlen)/bs->len * iks;
                                                        else
                                                                forcefactor = actspringlen * iks;
+                                                       forcefactor *= bs->strength; 
                                                        Vec3PlusStVec(bp->force,+forcefactor,sd);                                                       
                                                }
                                        }/* loop springs */
@@ -1337,6 +1424,12 @@ static void mesh_to_softbody(Object *ob)
                        }
 
                        build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
+
+                       /* insert *other second order* springs if desired */
+                       if (sb->secondspring > 0.0000001f) {
+                               add_2nd_order_springs(ob,sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/
+                               build_bps_springlist(ob); /* yes we need to do it again*/
+                       }
                        springs_from_mesh(ob); /* write the 'rest'-lenght of the springs */
                }
        }
index 35cb4ecbf8bc46eb94a7d31fd044da3449188572..b7bc74d524b8970c139e954541eec6aa69a64dd1 100644 (file)
@@ -97,7 +97,8 @@ typedef struct SoftBody {
        
        SBVertex **keys;                        /* array of size totpointkey */
        int totpointkey, totkey;        /* if totpointkey != totpoint or totkey!- (efra-sfra)/interval -> free keys */
-       
+       float secondspring;
+       float pad3;             /* local==1: use local coords for baking */
 } SoftBody;
 
 /* pd->forcefield:  Effector Fields types */
index d5b628380c6dbb292a0b671f09967a80f6a7a711..eb125b8f10508e2ad0ad97196d20cacbdb2b4371 100644 (file)
@@ -2309,11 +2309,12 @@ static void object_softbodies(Object *ob)
                else {
                        /* GENERAL STUFF */
                        uiBlockBeginAlign(block);
-                       uiDefButF(block, NUM, B_DIFF, "Friction:",              10, 170,150,20, &sb->mediafrict, 0.0, 10.0, 10, 0, "General media friction for point movements");
+                       uiDefButF(block, NUM, B_DIFF, "Friction:",              10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
                        uiDefButF(block, NUM, B_DIFF, "Mass:",                  160, 170,150,20, &sb->nodemass , 0.001, 50.0, 10, 0, "Point Mass, the heavier the slower");
                        uiDefButF(block, NUM, B_DIFF, "Grav:",                  10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
                        uiDefButF(block, NUM, B_DIFF, "Speed:",                 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
-                       uiDefButF(block, NUM, B_DIFF, "Error Limit:",   10,130,150,20, &sb->rklimit , 0.01, 1.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
+                       uiDefButF(block, NUM, B_DIFF, "Error Limit:",   10,130,150,20, &sb->rklimit , 0.01, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
+                       uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Rigidity:", 160,130,150,20, &sb->secondspring, 0.0,  10.0, 10, 0, "Strenght of Springs over 2 Edges");
                        uiBlockEndAlign(block);
                        
                        /* GOAL STUFF */
@@ -2344,7 +2345,7 @@ static void object_softbodies(Object *ob)
                        }
 
                        uiDefButF(block, NUM, B_DIFF, "G Stiff:",       10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
-                       uiDefButF(block, NUM, B_DIFF, "G Damp:",        160,80,150,20, &sb->goalfrict  , 0.0, 10.0, 10, 0, "Goal (vertex target position) friction");
+                       uiDefButF(block, NUM, B_DIFF, "G Damp:",        160,80,150,20, &sb->goalfrict  , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
                        uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Min:",              10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
                        uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Max:",              160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
                        uiBlockEndAlign(block);
@@ -2355,7 +2356,7 @@ static void object_softbodies(Object *ob)
                                uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges",           10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
                                uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads",         160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
                                uiDefButF(block, NUM, B_DIFF, "E Stiff:",       10,10,150,20, &sb->inspring, 0.0,  0.999, 10, 0, "Edge spring stiffness");
-                               uiDefButF(block, NUM, B_DIFF, "E Damp:",        160,10,150,20, &sb->infrict, 0.0,  10.0, 10, 0, "Edge spring friction");
+                               uiDefButF(block, NUM, B_DIFF, "E Damp:",        160,10,150,20, &sb->infrict, 0.0,  50.0, 10, 0, "Edge spring friction");
                                uiBlockEndAlign(block);
                        }
                }