Softbody:

- Added browsing for vertex group for "Goal" in SoftBody buttons.
- Means the default name "SOFTGOAL" isn't needed anymore
- temporally, on file read, the "SOFTGOAL" vertex group is set, if exists
- removing vertex group possible too
- changed softbody.c code to use this
This commit is contained in:
Ton Roosendaal 2005-04-16 14:01:49 +00:00
parent 097726eb50
commit 7943f7990e
6 changed files with 128 additions and 94 deletions

@ -90,8 +90,6 @@ extern int get_defgroup_num (Object *ob, bDeformGroup *dg);
float SoftHeunTol = 1.0f; // humm .. this should be calculated from sb parameters and sizes
/* local prototypes */
//static void softbody_scale_time(float steptime);
static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target);
static void free_softbody_intern(SoftBody *sb);
@ -321,7 +319,7 @@ static int sb_deflect_particle(Object *ob,float *actpos, float *futurepos,float
}
#if 0
static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
{
@ -465,7 +463,7 @@ static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos,
return 0;
}
#endif
@ -728,7 +726,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
if(bp->goal < SOFTGOALSNAP){
/* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/
/* the ( ... )' operator denotes derivate respective time
/* the ( ... )' operator denotes derivate respective time */
/* the euler step for velocity then becomes */
/* v(t + dt) = v(t) + a(t) * dt */
bp->force[0]*= timeovermass; /* individual mass of node here */
@ -1018,37 +1016,29 @@ static void mesh_update_softbody(Object *ob)
}
static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target)
static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target)
/* result 0 on success, else indicates error number
-- kind of *inverse* result defintion,
-- but this way we can signal error condition to caller
-- and yes this function must not be here but in a *vertex group module*
*/
{
bDeformGroup *locGroup = NULL;
MDeformVert *dv;
int i, groupindex;
int i;
locGroup = get_named_vertexgroup(ob,name);
if(locGroup){
/* retrieve index for that group */
groupindex = get_defgroup_num(ob,locGroup);
/* spot the vert in deform vert list at mesh */
/* todo (coder paranoya) what if ob->data is not a mesh .. */
/* hrms.. would like to have the same for lattices anyhoo */
if(ob->type==OB_MESH) {
if (((Mesh *)ob->data)->dvert) {
dv = ((Mesh*)ob->data)->dvert + vertID;
/* Lets see if this vert is in the weight group */
for (i=0; i<dv->totweight; i++){
if (dv->dw[i].def_nr == groupindex){
*target= dv->dw[i].weight; /* got it ! */
return 0;
break;
}
}
}
}
return 2;
}/*if(locGroup)*/
return 1;
}
/* makes totally fresh start situation */
@ -1078,24 +1068,16 @@ static void mesh_to_softbody(Object *ob)
set_body_point(ob, bp, mvert->co);
if (1) { /* switch to vg scalars*/
/* get scalar values needed *per vertex* from vertex group functions,
so we can *paint* them nicly ..
they are normalized [0.0..1.0] so may be we need amplitude for scale
which can be done by caller
but still .. i'd like it to go this way
which can be done by caller but still .. i'd like it to go this way
*/
int error;
char name[32] = "SOFTGOAL";
float temp;
error = get_scalar_from_named_vertexgroup(ob, name, me->totvert - a, &temp);
if (!error) {
bp->goal = temp;
/* works assuming goal is <0.0, 1.0> */
if(sb->vertgroup) {
get_scalar_from_vertexgroup(ob, me->totvert - a, sb->vertgroup-1, &bp->goal);
// do this always, regardless successfull read from vertex group
bp->goal= sb->mingoal + bp->goal*goalfac;
}
/* a little ad hoc changing the goal control to be less *sharp* */
bp->goal = (float)pow(bp->goal, 4.0f);
@ -1106,10 +1088,6 @@ static void mesh_to_softbody(Object *ob)
error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
if (!error) bp->mass = temp * ob->rangeofmass;
*/
} /* switch to vg scalars */
}
/* but we only optionally add body edge springs */

@ -110,6 +110,7 @@
#include "BKE_action.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_deform.h"
#include "BKE_effect.h" // for give_parteff
#include "BKE_global.h" // for G
#include "BKE_property.h" // for get_property
@ -4681,6 +4682,13 @@ static void do_versions(Main *main)
ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
}
if(ob->soft && ob->soft->vertgroup==0) {
bDeformGroup *locGroup = get_named_vertexgroup(ob, "SOFTGOAL");
if(locGroup){
/* retrieve index for that group */
ob->soft->vertgroup = 1 + get_defgroup_num(ob, locGroup);
}
}
}
}

@ -35,6 +35,7 @@
/* all internal calls and event codes for buttons space */
struct Base;
struct Object;
struct ID;
@ -76,6 +77,7 @@ extern void do_fontbuts(unsigned short event);
extern void do_mballbuts(unsigned short event);
extern void do_latticebuts(unsigned short event);
extern void do_fpaintbuts(unsigned short event);
extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons
/* shading */
extern void material_panels(void);
@ -219,6 +221,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
#define B_CURVECHECK 1416
#define B_SOFTBODY_CHANGE 1420
#define B_SOFTBODY_DEL_VG 1421
/* this has MAX_EFFECT settings! Next free define is 1450... */
#define B_SELEFFECT 1430

@ -121,6 +121,8 @@ typedef struct SoftBody {
float goalfrict; /* softbody goal springs friction */
float mingoal; /* quick limits for goal */
float maxgoal;
short vertgroup; /* index starting at 1 */
short pad1, pad2, pad3;
float inspring; /* softbody inner springs */
float infrict; /* softbody inner springs friction */

@ -2165,6 +2165,49 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
}
char *get_vertexgroup_menustr(Object *ob)
{
bDeformGroup *dg;
int defCount, min, index;
char (*qsort_ptr)[32] = NULL;
char *s, *menustr;
defCount=BLI_countlist(&ob->defbase);
if (!defCount) min=0;
else min=1;
if (defCount > 0) {
/*
* This will hold the group names temporarily
* so we can sort them
*/
qsort_ptr = MEM_callocN (defCount * sizeof (qsort_ptr[0]),
"qsort_ptr");
for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) {
snprintf (qsort_ptr[index - 1], sizeof (qsort_ptr[0]),
"%s%%x%d|", dg->name, index);
}
qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]),
( int (*)(const void *, const void *) ) strcmp);
}
s= menustr = MEM_callocN((32 * defCount)+30, "menustr"); // plus 30 for when defCount==0
if(defCount) {
for (index = 0; index < defCount; index++) {
int cnt= sprintf (s, "%s", qsort_ptr[index]);
if (cnt>0) s+= cnt;
}
}
else strcpy(menustr, "No Vertex Groups in Object");
if (qsort_ptr)
MEM_freeN (qsort_ptr);
return menustr;
}
static void editing_panel_links(Object *ob)
{
uiBlock *block;
@ -2264,51 +2307,19 @@ static void editing_panel_links(Object *ob)
uiBut *but;
int defCount;
bDeformGroup *defGroup;
char *s, *menustr;
bDeformGroup *dg;
int min, index;
char (*qsort_ptr)[32] = NULL;
uiDefBut(block, LABEL,0,"Vertex Groups",
143,153,130,20, 0, 0, 0, 0, 0, "");
defCount=BLI_countlist(&ob->defbase);
if (!defCount) min=0;
else min=1;
if (defCount > 0) {
/*
* This will hold the group names temporarily
* so we can sort them
*/
qsort_ptr = MEM_callocN (defCount * sizeof (qsort_ptr[0]),
"qsort_ptr");
for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) {
snprintf (qsort_ptr[index - 1], sizeof (qsort_ptr[0]),
"%s%%x%d|", dg->name, index);
}
qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]),
( int (*)(const void *, const void *) ) strcmp);
}
s= menustr = MEM_callocN((32 * defCount)+20, "menustr");
for (index = 0; index < defCount; index++) {
int cnt= sprintf (s, "%s", qsort_ptr[index]);
if (cnt>0) s+= cnt;
}
if (qsort_ptr)
MEM_freeN (qsort_ptr);
uiBlockBeginAlign(block);
if (defCount)
uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr,
143, 132,18,21, &ob->actdef, min, defCount, 0, 0,
"Browses available vertex groups");
if (defCount) {
char *menustr= get_vertexgroup_menustr(ob);
uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr, 143, 132,18,21, &ob->actdef, 1, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (menustr);
}
if (ob->actdef){
defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);

@ -1192,8 +1192,20 @@ void do_object_panels(unsigned short event)
case B_SOFTBODY_CHANGE:
ob= OBACT;
if(ob) ob->softflag |= OB_SB_REDO;
if(ob) {
ob->softflag |= OB_SB_REDO;
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
break;
case B_SOFTBODY_DEL_VG:
ob= OBACT;
if(ob && ob->soft) {
ob->soft->vertgroup= 0;
ob->softflag |= OB_SB_REDO;
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
break;
default:
@ -1469,6 +1481,8 @@ static void object_softbodies(Object *ob)
if(ob->softflag & OB_SB_ENABLE) {
SoftBody *sb= ob->soft;
int defCount;
char *menustr;
if(sb==NULL) {
sb= ob->soft= sbNew();
@ -1491,8 +1505,26 @@ 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");
uiDefButBitS(block, TOG, OB_SB_GOAL, B_DIFF, "Use Goal", 10,100,130,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
menustr= get_vertexgroup_menustr(ob);
defCount=BLI_countlist(&ob->defbase);
if(defCount==0) sb->vertgroup= 0;
uiDefButS(block, MENU, B_SOFTBODY_CHANGE, menustr, 140,100,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
if(sb->vertgroup) {
bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1);
if(defGroup)
uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
else
uiDefBut(block, BUT, B_DIFF, "(no group)", 160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,100,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
}
else {
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");
}
MEM_freeN (menustr);
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_SOFTBODY_CHANGE, "GMin:", 10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Min Goal bound");