diff options
author | Ton Roosendaal <ton@blender.org> | 2005-04-02 23:52:32 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-04-02 23:52:32 +0400 |
commit | 90df59630eaf886977e8aea2691cae7d365d9fe4 (patch) | |
tree | cd0d5d587655acc9955517b5a5ca9b47595bb8dd /source | |
parent | fc663edf7278f5b2a7dcde9845be0d17a3dc6926 (diff) |
More softbody goodness;
- 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
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 150 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 15 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 32 |
8 files changed, 163 insertions, 46 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index d1c156380e8..ba7d49af293 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -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); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 01d0735af5d..e8051db4c33 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -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; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d10d970e0d4..b2fce9edfe6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 839e2683518..1b6d20f1b16 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -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 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 13ea7def290..fb11938c442 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -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; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 6bb4c647901..4da27218455 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -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; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index f9533f0ebd7..6984757d476 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -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); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index d05f45bc841..742ff09d72f 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -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"); } } |