Added an option in the IK constraint to disable stretching, useful

in rigs with layered IK constraints. Also removed the tolerance
setting, this value wasn't used in the solver anymore.
This commit is contained in:
2006-11-06 23:51:37 +00:00
parent 10a4b1ad8b
commit b48c514db8
7 changed files with 37 additions and 26 deletions

View File

@@ -63,8 +63,8 @@ typedef struct PoseTree
int *parent; /* and their parents */
int totchannel; /* number of pose channels */
float (*basis_change)[3][3]; /* basis change result from solver */
float tolerance; /* tolerance from the constraint */
int iterations; /* iterations from the constraint */
int stretch; /* disable stretching */
} PoseTree;
/* Core armature functionality */

View File

@@ -1118,9 +1118,9 @@ static void initialize_posetree(struct Object *ob, bPoseChannel *pchan_tip)
/* make new tree */
tree= MEM_callocN(sizeof(PoseTree), "posetree");
tree->tolerance= data->tolerance;
tree->iterations= data->iterations;
tree->totchannel= segcount;
tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
tree->pchan= MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
tree->parent= MEM_callocN(segcount*sizeof(int), "ik tree parent");
@@ -1134,8 +1134,8 @@ static void initialize_posetree(struct Object *ob, bPoseChannel *pchan_tip)
BLI_addtail(&pchan_root->iktree, tree);
}
else {
tree->tolerance= MIN2(tree->tolerance, data->tolerance);
tree->iterations= MAX2(data->iterations, tree->iterations);
tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
/* skip common pose channels and add remaining*/
size= MIN2(segcount, tree->totchannel);
@@ -1216,7 +1216,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
if((pchan->ikflag & BONE_IK_NO_ZDOF) == 0)
flag |= IK_ZDOF;
if(pchan->ikstretch > 0.0) {
if(tree->stretch && (pchan->ikstretch > 0.0)) {
flag |= IK_TRANS_YDOF;
hasstretch = 1;
}
@@ -1281,7 +1281,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
if(pchan->ikstretch > 0.0) {
if(tree->stretch && (pchan->ikstretch > 0.0)) {
float ikstretch = pchan->ikstretch*pchan->ikstretch;
IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99));
IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
@@ -1352,7 +1352,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
}
/* solve */
IK_Solve(solver, tree->tolerance, tree->iterations);
IK_Solve(solver, 0.0f, tree->iterations);
IK_FreeSolver(solver);
/* gather basis changes */
@@ -1370,7 +1370,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
pchan= tree->pchan[a];
parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0;
if(pchan->ikstretch > 0.0) {
if(tree->stretch && (pchan->ikstretch > 0.0)) {
float trans[3], length;
IK_GetTranslationChange(iktree[a], trans);

View File

@@ -563,10 +563,10 @@ void *new_constraint_data (short type)
bKinematicConstraint *data;
data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
data->tolerance = (float)0.001;
data->weight= (float)1.0;
data->orientweight= (float)1.0;
data->iterations = 500;
data->flag= CONSTRAINT_IK_TIP;
data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
result = data;
}

View File

@@ -5764,6 +5764,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
data->flag&=~MINMAX_STICKY;
}
}
else if (curcon->type == CONSTRAINT_TYPE_KINEMATIC){
bKinematicConstraint *data = curcon->data;
if (!(data->flag & CONSTRAINT_IK_POS)) {
data->flag |= CONSTRAINT_IK_POS;
data->flag |= CONSTRAINT_IK_STRETCH;
}
}
}
}
}

View File

@@ -62,16 +62,15 @@ typedef struct bConstraint{
/* Single-target subobject constraints */
typedef struct bKinematicConstraint{
Object *tar;
float tolerance; /* Acceptable distance from target */
short iterations; /* Maximum number of iterations to try */
short flag; /* Like CONSTRAINT_IK_TIP */
int rootbone, pad; /* index to rootbone, if zero go all the way to mother bone */
int rootbone; /* index to rootbone, if zero go all the way to mother bone */
char subtarget[32]; /* String to specify sub-object target */
float weight; /* Weight of goal in IK tree */
float orientweight; /* Amount of rotation a target applies on chain */
float grabtarget[3]; /* for target-less IK */
float pad2;
int pad;
} bKinematicConstraint;
typedef struct bTrackToConstraint{
@@ -277,6 +276,8 @@ typedef struct bSizeLimitConstraint{
#define CONSTRAINT_IK_ROT 2
#define CONSTRAINT_IK_AUTO 4
#define CONSTRAINT_IK_TEMP 8
#define CONSTRAINT_IK_STRETCH 16
#define CONSTRAINT_IK_POS 32
/* MinMax (floor) flags */
#define MINMAX_STICKY 0x01

View File

@@ -67,7 +67,7 @@ enum constraint_constants {
EXPP_CONSTR_MINZ = TRACK_nZ,
EXPP_CONSTR_TARGET = 100,
EXPP_CONSTR_TOLERANCE,
EXPP_CONSTR_STRETCH,
EXPP_CONSTR_ITERATIONS,
EXPP_CONSTR_BONE,
EXPP_CONSTR_CHAINLEN,
@@ -390,8 +390,8 @@ static PyObject *kinematic_getter( BPy_Constraint * self, int type )
return Object_CreatePyObject( con->tar );
case EXPP_CONSTR_BONE:
return PyString_FromString( con->subtarget );
case EXPP_CONSTR_TOLERANCE:
return PyFloat_FromDouble( (double)con->tolerance );
case EXPP_CONSTR_STRETCH:
return PyBool_FromLong( (long)( con->flag & CONSTRAINT_IK_STRETCH ) ) ;
case EXPP_CONSTR_ITERATIONS:
return PyInt_FromLong( (long)con->iterations );
case EXPP_CONSTR_CHAINLEN:
@@ -432,8 +432,8 @@ static int kinematic_setter( BPy_Constraint *self, int type, PyObject *value )
return 0;
}
case EXPP_CONSTR_TOLERANCE:
return EXPP_setFloatClamped( value, &con->tolerance, 0.0001, 1.0 );
case EXPP_CONSTR_STRETCH:
return EXPP_setBitfield( value, &con->flag, CONSTRAINT_IK_STRETCH, 'h' );
case EXPP_CONSTR_ITERATIONS:
return EXPP_setIValueClamped( value, &con->iterations, 1, 10000, 'h' );
case EXPP_CONSTR_CHAINLEN:
@@ -1829,8 +1829,8 @@ static PyObject *M_Constraint_SettingsDict( void )
PyConstant_Insert( d, "TARGET",
PyInt_FromLong( EXPP_CONSTR_TARGET ) );
PyConstant_Insert( d, "TOLERANCE",
PyInt_FromLong( EXPP_CONSTR_TOLERANCE ) );
PyConstant_Insert( d, "STRETCH",
PyInt_FromLong( EXPP_CONSTR_STRETCH ) );
PyConstant_Insert( d, "ITERATIONS",
PyInt_FromLong( EXPP_CONSTR_ITERATIONS ) );
PyConstant_Insert( d, "BONE",

View File

@@ -757,7 +757,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
{
bKinematicConstraint *data = con->data;
height = 108;
height = 111;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -776,14 +776,17 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
strcpy (data->subtarget, "");
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco, *yco-64, 142, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco+142, *yco-64,143,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco, *yco-64, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-84,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco, *yco-86, 142, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+142, *yco-86, 143, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Tolerance:", *xco, *yco-106, 142, 19, &data->tolerance, 0.0001f, 1.0, 0, 0, "Maximum distance to target after solving");
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+142, *yco-106, 143, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-64, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+147, *yco-84, 137, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
uiBlockBeginAlign(block);
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco, *yco-109, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco+147, *yco-109,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
}
break;