forked from bartvdbraak/blender
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:
parent
097726eb50
commit
7943f7990e
@ -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 */
|
||||
/* spot the vert in deform vert list at mesh */
|
||||
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,38 +1068,26 @@ 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
|
||||
*/
|
||||
int error;
|
||||
char name[32] = "SOFTGOAL";
|
||||
float temp;
|
||||
/* 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
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
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> */
|
||||
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);
|
||||
|
||||
/* to proove the concept
|
||||
this would enable per vertex *mass painting*
|
||||
strcpy(name,"SOFTMASS");
|
||||
error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
|
||||
if (!error) bp->mass = temp * ob->rangeofmass;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} /* switch to vg scalars */
|
||||
/* to proove the concept
|
||||
this would enable per vertex *mass painting*
|
||||
strcpy(name,"SOFTMASS");
|
||||
error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
|
||||
if (!error) bp->mass = temp * ob->rangeofmass;
|
||||
*/
|
||||
}
|
||||
|
||||
/* 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,52 +2307,20 @@ 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");
|
||||
|
||||
MEM_freeN (menustr);
|
||||
|
||||
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);
|
||||
but= uiDefBut(block, TEX,REDRAWBUTSEDIT,"", 161,132,140-18,21, defGroup->name, 0, 32, 0, 0, "Displays current vertex group name. Click to change. (Match bone name for deformation.)");
|
||||
|
@ -1192,8 +1192,20 @@ void do_object_panels(unsigned short event)
|
||||
|
||||
case B_SOFTBODY_CHANGE:
|
||||
ob= OBACT;
|
||||
if(ob) ob->softflag |= OB_SB_REDO;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user