More softbody goodness;
authorTon Roosendaal <ton@blender.org>
Sat, 2 Apr 2005 19:52:32 +0000 (19:52 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 2 Apr 2005 19:52:32 +0000 (19:52 +0000)
- Added Softbody effect for Lattices (not too useful yet without
  vertexgroups though)
- Added default vertex "goal" value + button, to be assigned when no
  vertexgroup exists (or vertex isn't in the group)
- Made softmin and softmax work as documented (defining min and max range)
- made changes in buttons send 'update' signal to softbody

And:

- added Nkey Properties to show lattice coordinates

source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_object_types.h
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/drawview.c

index d1c156380e8de3ca9502d7813ce8b318d795ee9a..ba7d49af293ea49d873b4f233266a9b80e1b8b7e 100644 (file)
@@ -392,6 +392,7 @@ int lattice_modifier(Object *ob, char mode)
        /* conditions if it's needed */
        if(ob->hooks.first);
        else if(ob->parent && ob->partype==PARSKEL); 
+       else if((ob->softflag & OB_SB_ENABLE));
        else return 0;
        
        if(mode=='s') { // "start"
@@ -412,6 +413,11 @@ int lattice_modifier(Object *ob, char mode)
                                bp++;
                        }
                }
+               
+               if((ob->softflag & OB_SB_ENABLE)) {
+                       sbObjectStep(ob, (float)G.scene->r.cfra);
+               }
+               
        }
        else { // end
                MEM_freeN(lt->def);
index 01d0735af5dcbda518aeede9ac7011b10db27549..e8051db4c3378279f361f8078247a7cc3915e934 100644 (file)
@@ -58,9 +58,11 @@ variables on the UI for now
 #include "MEM_guardedalloc.h"
 
 /* types */
+#include "DNA_curve_types.h"
 #include "DNA_object_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
 #include "DNA_scene_types.h"
 
 #include "BLI_blenlib.h"
@@ -130,7 +132,9 @@ static void add_mesh_quad_diag_springs(Object *ob)
                        /* resize spring-array to hold additional quad springs */
                        bs_new= MEM_callocN( (ob->soft->totspring + nofquads *2 )*sizeof(BodySpring), "bodyspring");
                        memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
-                       MEM_freeN(ob->soft->bspring); /* do this before reassigning the pointer  or have a 1st class memory leak */
+                       
+                       if(ob->soft->bspring)
+                               MEM_freeN(ob->soft->bspring); /* do this before reassigning the pointer  or have a 1st class memory leak */
                        ob->soft->bspring = bs_new; 
                        
                        /* fill the tail */
@@ -587,6 +591,7 @@ static void interpolate_exciter(Object *ob, int timescale, int time)
     - softbody_to_xxxx(Object *ob)      : after simulation, copy vertex locations back
 */
 
+/* helper  call */
 static int object_has_edges(Object *ob) 
 {
        if(ob->type==OB_MESH) {
@@ -600,6 +605,24 @@ static int object_has_edges(Object *ob)
        return 0;
 }
 
+/* helper  call */
+static void set_body_point(Object *ob, BodyPoint *bp, float *vec)
+{
+       
+       VECCOPY(bp->pos, vec);
+       Mat4MulVecfl(ob->obmat, bp->pos);  // yep, sofbody is global coords
+       VECCOPY(bp->origS, bp->pos);
+       VECCOPY(bp->origE, bp->pos);
+       VECCOPY(bp->origT, bp->pos);
+       
+       bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
+       bp->weight= 1.0;
+       bp->goal= ob->soft->defgoal;
+       
+       bp->nofsprings= 0;
+       bp->springs= NULL;
+}
+
 
 /* copy original (new) situation in softbody, as result of matrices or deform */
 /* is assumed to enter function with ob->soft, but can be without points */
@@ -641,7 +664,6 @@ static void mesh_update_softbody(Object *ob)
                        */
                }
        }
-
 }
 
 
@@ -687,27 +709,20 @@ static void mesh_to_softbody(Object *ob)
        MEdge *medge= me->medge;
        BodyPoint *bp;
        BodySpring *bs;
+       float goalfac;
        int a;
        
        /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
        renew_softbody(ob, me->totvert, me->totedge);
-       
+               
        /* we always make body points */
        sb= ob->soft;   
        bp= sb->bpoint;
+       goalfac= ABS(sb->maxgoal - sb->mingoal);
+       
        for(a=me->totvert; a>0; a--, mvert++, bp++) {
                
-               VECCOPY(bp->pos, mvert->co);
-               Mat4MulVecfl(ob->obmat, bp->pos);  // yep, sofbody is global coords
-               VECCOPY(bp->origS, bp->pos);
-               VECCOPY(bp->origE, bp->pos);
-               VECCOPY(bp->origT, bp->pos);
-               
-               bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
-               bp->weight= 1.0;
-               bp->goal= 0.5;
-               bp->nofsprings= 0;
-               bp->springs= NULL;
+               set_body_point(ob, bp, mvert->co);
                
                if (1) { /* switch to vg scalars*/
                        /* get scalar values needed  *per vertex* from vertex group functions,
@@ -721,11 +736,15 @@ static void mesh_to_softbody(Object *ob)
                        float temp;
                        
                        error = get_scalar_from_named_vertexgroup(ob, name, me->totvert - a, &temp);
-                       if (!error) bp->goal = temp;
-                       if (bp->goal < sb->mingoal) bp->goal = sb->mingoal;
-                       if (bp->goal > sb->maxgoal) bp->goal = sb->maxgoal;
+                       if (!error) {
+                               bp->goal = temp;
+                               
+                               /* works assuming goal is <0.0, 1.0> */
+                               bp->goal= sb->mingoal + (bp->goal - sb->mingoal)*goalfac;
+                               
+                       }
                        /* a little ad hoc changing the goal control to be less *sharp* */
-                       bp->goal = (float)pow(bp->goal,4.0f);
+                       bp->goal = (float)pow(bp->goal, 4.0f);
                        
                        /* to proove the concept
                        this would enable per vertex *mass painting*
@@ -770,8 +789,6 @@ static void softbody_to_mesh(Object *ob)
        BodyPoint *bp;
        int a;
 
-       Mat4Invert(ob->imat, ob->obmat);
-       
        bp= ob->soft->bpoint;
        mvert= me->mvert;
        for(a=me->totvert; a>0; a--, mvert++, bp++) {
@@ -784,15 +801,66 @@ static void softbody_to_mesh(Object *ob)
 /* makes totally fresh start situation */
 static void lattice_to_softbody(Object *ob)
 {
-
+       SoftBody *sb;
+       Lattice *lt= ob->data;
+       BodyPoint *bop;
+       BPoint *bp;
+       int a, totvert;
+       
+       totvert= lt->pntsu*lt->pntsv*lt->pntsw;
+       
+       /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
+       renew_softbody(ob, totvert, 0);
+       
+       /* we always make body points */
+       sb= ob->soft;   
+       
+       for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) {
+               set_body_point(ob, bop, bp->vec);
+       }
 }
 
 /* copies current sofbody position */
 static void softbody_to_lattice(Object *ob)
 {
+       SoftBody *sb;
+       Lattice *lt= ob->data;
+       BodyPoint *bop;
+       BPoint *bp;
+       int a, totvert;
+       
+       totvert= lt->pntsu*lt->pntsv*lt->pntsw;
+       sb= ob->soft;   
+       
+       for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) {
+               VECCOPY(bp->vec, bop->pos);
+               Mat4MulVecfl(ob->imat, bp->vec);        // softbody is in global coords
+       }
+}
 
+/* copy original (new) situation in softbody, as result of matrices or deform */
+/* is assumed to enter function with ob->soft, but can be without points */
+static void lattice_update_softbody(Object *ob)
+{
+       Lattice *lt= ob->data;
+       BodyPoint *bop;
+       BPoint *bp;
+       int a, totvert;
+       
+       totvert= lt->pntsu*lt->pntsv*lt->pntsw;
+       
+       /* possible after a file read... */
+       if(ob->soft->totpoint!=totvert) sbObjectToSoftbody(ob);
+       
+       for(a= totvert, bp= lt->def, bop= ob->soft->bpoint; a>0; a--, bp++, bop++) {
+               VECCOPY(bop->origS, bop->origE);
+               VECCOPY(bop->origE, bp->vec);
+               Mat4MulVecfl(ob->obmat, bop->origE);
+               VECCOPY(bop->origT, bop->origE);
+       }       
 }
 
+
 /* copies softbody result back in object */
 /* only used in sbObjectStep() */
 static void softbody_to_object(Object *ob)
@@ -800,13 +868,16 @@ static void softbody_to_object(Object *ob)
        
        if(ob->soft==NULL) return;
        
+       /* inverse matrix is not uptodate... */
+       Mat4Invert(ob->imat, ob->obmat);
+       
        switch(ob->type) {
-               case OB_MESH:
-                       softbody_to_mesh(ob);
-                       break;
-               case OB_LATTICE:
-                       softbody_to_lattice(ob);
-                       break;
+       case OB_MESH:
+               softbody_to_mesh(ob);
+               break;
+       case OB_LATTICE:
+               softbody_to_lattice(ob);
+               break;
        }
 }
 
@@ -817,12 +888,12 @@ static void object_update_softbody(Object *ob)
 {
        
        switch(ob->type) {
-               case OB_MESH:
-                       mesh_update_softbody(ob);
-                       break;
-               case OB_LATTICE:
-                       //lattice_update_softbody(ob);
-                       break;
+       case OB_MESH:
+               mesh_update_softbody(ob);
+               break;
+       case OB_LATTICE:
+               lattice_update_softbody(ob);
+               break;
        }
        
 }
@@ -838,17 +909,18 @@ SoftBody *sbNew(void)
        
        sb= MEM_callocN(sizeof(SoftBody), "softbody");
        
-       sb->mediafrict= 1.0
+       sb->mediafrict= 0.5
        sb->nodemass= 1.0;
        sb->grav= 0.0; 
        
-       sb->goalspring= 1.0
-       sb->goalfrict= 1.0; 
+       sb->goalspring= 0.5
+       sb->goalfrict= 0.0; 
        sb->mingoal= 0.0;  
        sb->maxgoal= 1.0;
+       sb->defgoal= 0.7;
        
-       sb->inspring= 1.0;
-       sb->infrict= 1.0
+       sb->inspring= 0.5;
+       sb->infrict= 0.5
        
        return sb;
 }
@@ -917,7 +989,7 @@ void sbObjectStep(Object *ob, float framenr)
                        sbObjectToSoftbody(ob);
        
        sb= ob->soft;
-       
+
        /* still no points? go away */
        if(sb->totpoint==0) return;
        
index d10d970e0d443f9a93bbe2455dcb1f58c7ee0de7..b2fce9edfe6c2f43b8c3e82844ca5e2924169cc9 100644 (file)
@@ -4677,6 +4677,7 @@ static void do_versions(Main *main)
                                sb->maxgoal= ob->sb_maxgoal;
                                sb->mediafrict= ob->sb_mediafrict; 
                                sb->rklimit= ob->softtime;
+                               sb->defgoal= 0.7;
                                
                                ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
                        }
index 839e268351898f92bd430164a57935a144963347..1b6d20f1b168f9db680776e6e66549002b971b7c 100644 (file)
@@ -218,6 +218,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
 #define B_RELKEY               1415
 #define B_CURVECHECK   1416
 
+#define B_SOFTBODY_CHANGE      1420
+
        /* this has MAX_EFFECT settings! Next free define is 1450... */
 #define B_SELEFFECT    1430    
 
index 13ea7def290d2c669b21e5f8bdf1f017174ac6f2..fb11938c442b0d972da24a40b1e43d61598323a6 100644 (file)
@@ -112,7 +112,7 @@ typedef struct SoftBody {
        float inspring;         /* softbody inner springs */
        float infrict;          /* softbody inner springs friction */
        
-       float pad;
+       float defgoal;          /* default goal for vertices without vgroup */
        
 } SoftBody;
 
index 6bb4c647901ec2847bd5bfc6dbb27129015b6823..4da272184550560750cd9c748b8c71e8b07bb07b 100644 (file)
@@ -1469,6 +1469,7 @@ void do_latticebuts(unsigned short event)
                if(ob) {
                        if(ob==G.obedit) resizelattice(editLatt);
                        else resizelattice(ob->data);
+                       ob->softflag |= OB_SB_REDO;
                }
                allqueue(REDRAWVIEW3D, 0);
                break;
index f9533f0ebd735d9e737c7056fc878a11cb5b50a7..6984757d476402fc43b821c73ddb81bb04e2c072 100644 (file)
@@ -1190,6 +1190,12 @@ void do_object_panels(unsigned short event)
                allqueue(REDRAWVIEW3D, 0);
                break;
        
+       case B_SOFTBODY_CHANGE:
+               ob= OBACT;
+               if(ob) ob->softflag |= OB_SB_REDO;
+               allqueue(REDRAWVIEW3D, 0);
+               break;
+               
        default:
                if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
                        ob= OBACT;
@@ -1475,16 +1481,17 @@ static void object_softbodies(Object *ob)
                /* GOAL STUFF */
                uiBlockBeginAlign(block);
                uiDefButBitS(block, TOG, OB_SB_GOAL, B_DIFF, "Use Goal",        10,100,150,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+               uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:",               160,100,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
                uiDefButF(block, NUM, B_DIFF, "GSpring:",       10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) Spring Constant");
                uiDefButF(block, NUM, B_DIFF, "GFrict:",        160,80,150,20, &sb->goalfrict  , 0.0, 10.0, 10, 0, "Goal (vertex target position) Friction Constant");
-               uiDefButF(block, NUM, B_DIFF, "GMin:",          10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Min Goal bound");
-               uiDefButF(block, NUM, B_DIFF, "GMax:",          160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Max Goal bound");
+               uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "GMin:",               10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Min Goal bound");
+               uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "GMax:",               160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Max Goal bound");
                uiBlockEndAlign(block);
                
                /* EDGE SPRING STUFF */
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG, OB_SB_EDGES, B_DIFF, "Use Edges",              10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Robust 2nd order solver");
-               uiDefButBitS(block, TOG, OB_SB_QUADS, B_DIFF, "Stiff Quads",    160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to have diagonal springs on 4-gons");
+               uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges",           10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Robust 2nd order solver");
+               uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads",         160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to have diagonal springs on 4-gons");
                uiDefButF(block, NUM, B_DIFF, "ESpring:",       10,10,150,20, &sb->inspring, 0.0,  0.999, 10, 0, "Edge Spring Constant");
                uiDefButF(block, NUM, B_DIFF, "EFrict:",        160,10,150,20, &sb->infrict, 0.0,  10.0, 10, 0, "Edge Friction Constant");
                uiBlockEndAlign(block);
index d05f45bc841b4a80ca9da5118e00b375db26327b..742ff09d72f567e2409e0903fa19d1566a2ecc1d 100644 (file)
@@ -1152,8 +1152,22 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
                        }
                        nu= nu->next;
                }
-       
        }
+       else if(ob->type==OB_LATTICE) {
+               BPoint *bp;
+               int a;
+               
+               a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+               bp= editLatt->def;
+               while(a--) {
+                       if(bp->f1 & SELECT) {
+                               VecAddf(median, median, bp->vec);
+                               tot++;
+                       }
+                       bp++;
+               }
+       }
+       
        if(tot==0) return;
 
        median[0] /= (float)tot;
@@ -1266,7 +1280,6 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
                                                if(bp->f1 & 1) {
                                                        VecAddf(bp->vec, bp->vec, median);
                                                        bp->vec[3]+= median[3];
-                                                       tot++;
                                                }
                                                bp++;
                                        }
@@ -1277,6 +1290,21 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
                                nu= nu->next;
                        }
                }
+               else if(ob->type==OB_LATTICE) {
+                       BPoint *bp;
+                       int a;
+                       
+                       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+                       bp= editLatt->def;
+                       while(a--) {
+                               if(bp->f1 & SELECT) {
+                                       VecAddf(median, median, bp->vec);
+                                       VecAddf(bp->vec, bp->vec, median);
+                               }
+                               bp++;
+                       }
+               }
+               
                BIF_undo_push("Transform properties");
        }
 }