IK work-in-progress commit;
- Removed old convention that only allowed one "IK" connection for Bones in a joint. Was highly frustrating for editing trees or branches. In a next commit, there will be a different method to define IK target and IK root, so this option actually will become "Connect Bone" or so. - the IK group name is gone, now is just an option "Tree IK". When IK chains share a root they'll form a tree. Todo is preventing conflicts here (will be for editor to define IK Root) - Adding new IK constraint with CTRL+I activates Constraint
This commit is contained in:
@@ -55,12 +55,12 @@ typedef struct PoseTarget
|
|||||||
|
|
||||||
typedef struct PoseChain
|
typedef struct PoseChain
|
||||||
{
|
{
|
||||||
struct PoseChain *next, *prev; // hurms
|
struct PoseChain *next, *prev;
|
||||||
struct bPoseChannel **pchanchain;
|
struct bPoseChannel **pchanchain;
|
||||||
struct ListBase targets;
|
struct ListBase targets;
|
||||||
int totchannel;
|
int totchannel;
|
||||||
|
int tree; // true or false
|
||||||
float (*basis_change)[3][3];
|
float (*basis_change)[3][3];
|
||||||
char group[32];
|
|
||||||
float tolerance;
|
float tolerance;
|
||||||
int iterations;
|
int iterations;
|
||||||
} PoseChain;
|
} PoseChain;
|
||||||
|
|||||||
@@ -1012,10 +1012,10 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
|
|||||||
/* setup the chain data */
|
/* setup the chain data */
|
||||||
chain = NULL;
|
chain = NULL;
|
||||||
|
|
||||||
/* if part of group, look for existing chain */
|
/* if tree-IK, look for mathing chain */
|
||||||
if(strlen(data->group) > 0)
|
if(data->flag & CONSTRAINT_IK_TREE)
|
||||||
for(chain= pchan_root->chain.first; chain; chain= chain->next)
|
for(chain= pchan_root->chain.first; chain; chain= chain->next)
|
||||||
if(strcmp(data->group, chain->group)==0) break;
|
if(chain->tree) break;
|
||||||
|
|
||||||
/* create a target */
|
/* create a target */
|
||||||
target= MEM_callocN(sizeof(PoseTarget), "posetarget");
|
target= MEM_callocN(sizeof(PoseTarget), "posetarget");
|
||||||
@@ -1025,7 +1025,7 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
|
|||||||
/* make new chain */
|
/* make new chain */
|
||||||
chain= MEM_callocN(sizeof(PoseChain), "posechain");
|
chain= MEM_callocN(sizeof(PoseChain), "posechain");
|
||||||
|
|
||||||
strcpy(chain->group, data->group);
|
chain->tree= data->flag & CONSTRAINT_IK_TREE;
|
||||||
chain->tolerance= data->tolerance;
|
chain->tolerance= data->tolerance;
|
||||||
chain->iterations= data->iterations;
|
chain->iterations= data->iterations;
|
||||||
chain->totchannel= segcount;
|
chain->totchannel= segcount;
|
||||||
@@ -1223,7 +1223,7 @@ static void execute_posechain(Object *ob, PoseChain *chain)
|
|||||||
|
|
||||||
if(data->weight != 0.0)
|
if(data->weight != 0.0)
|
||||||
IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
|
IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
|
||||||
if((data->flag & KINEMATIC_ORIENTATION) && (data->orientweight != 0.0))
|
if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
|
||||||
IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
|
IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4917,7 +4917,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
bKinematicConstraint *data = (bKinematicConstraint*)con->data;
|
bKinematicConstraint *data = (bKinematicConstraint*)con->data;
|
||||||
data->weight = 1.0f;
|
data->weight = 1.0f;
|
||||||
data->orientweight = 0.0f;
|
data->orientweight = 0.0f;
|
||||||
data->flag &= ~KINEMATIC_ORIENTATION;
|
data->flag &= ~CONSTRAINT_IK_ROT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,9 +103,6 @@ void selectconnected_armature(void);
|
|||||||
void selectconnected_posearmature(void);
|
void selectconnected_posearmature(void);
|
||||||
void select_bone_by_name (struct bArmature *arm, char *name, int select);
|
void select_bone_by_name (struct bArmature *arm, char *name, int select);
|
||||||
void unique_editbone_name (char* name);
|
void unique_editbone_name (char* name);
|
||||||
void attach_bone_to_parent(EditBone *bone);
|
|
||||||
void attach_bone_to_parent_cb(void *bonev, void *arg2_unused);
|
|
||||||
|
|
||||||
|
|
||||||
void auto_align_armature(void);
|
void auto_align_armature(void);
|
||||||
void create_vgroups_from_armature(Object *ob, Object *par);
|
void create_vgroups_from_armature(Object *ob, Object *par);
|
||||||
|
|||||||
@@ -67,9 +67,8 @@ typedef struct bKinematicConstraint{
|
|||||||
short flag; /* Like IK to Tip */
|
short flag; /* Like IK to Tip */
|
||||||
char subtarget[32]; /* String to specify sub-object target */
|
char subtarget[32]; /* String to specify sub-object target */
|
||||||
|
|
||||||
char group[32]; /* Name of group */
|
float weight; /* Weight of goal in IK tree */
|
||||||
float weight; /* Weight of goal in IK group */
|
float orientweight; /* Amount of rotation a target applies on chain */
|
||||||
float orientweight;
|
|
||||||
} bKinematicConstraint;
|
} bKinematicConstraint;
|
||||||
|
|
||||||
typedef struct bTrackToConstraint{
|
typedef struct bTrackToConstraint{
|
||||||
@@ -214,8 +213,9 @@ typedef struct bStretchToConstraint{
|
|||||||
#define PLANE_Z 0x02
|
#define PLANE_Z 0x02
|
||||||
|
|
||||||
/* bKinematicConstraint->flag */
|
/* bKinematicConstraint->flag */
|
||||||
#define CONSTRAINT_IK_TIP 1
|
#define CONSTRAINT_IK_TIP 1
|
||||||
#define KINEMATIC_ORIENTATION 2
|
#define CONSTRAINT_IK_ROT 2
|
||||||
|
#define CONSTRAINT_IK_TREE 4
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2065,6 +2065,18 @@ static int editbone_to_parnr (EditBone *bone)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* the "IK" button in editbuttons */
|
||||||
|
static void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
|
||||||
|
{
|
||||||
|
EditBone *ebone= bonev;
|
||||||
|
|
||||||
|
if (ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) {
|
||||||
|
/* Attach this bone to its parent */
|
||||||
|
VECCOPY(ebone->head, ebone->parent->tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void parnr_to_editbone(EditBone *bone)
|
static void parnr_to_editbone(EditBone *bone)
|
||||||
{
|
{
|
||||||
if (bone->parNr == -1){
|
if (bone->parNr == -1){
|
||||||
@@ -2073,7 +2085,7 @@ static void parnr_to_editbone(EditBone *bone)
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
bone->parent = BLI_findlink(&G.edbo, bone->parNr);
|
bone->parent = BLI_findlink(&G.edbo, bone->parNr);
|
||||||
attach_bone_to_parent(bone);
|
attach_bone_to_parent_cb(bone, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2202,6 +2214,7 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
||||||
{
|
{
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
|
|||||||
@@ -608,10 +608,10 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
|
|||||||
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
|
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
|
||||||
uiBlockEndAlign(block);
|
uiBlockEndAlign(block);
|
||||||
|
|
||||||
uiDefBut(block, TEX, B_CONSTRAINT_TEST, "IK group:", *xco+((width/2)-117), *yco-86,120,18, &data->group, 0, 24, 0, 0, "IK group name");
|
uiDefButBitS(block, TOG, CONSTRAINT_IK_TREE, B_CONSTRAINT_TEST, "Tree IK", *xco+((width/2)-117), *yco-86,120,18, &data->flag, 0, 0, 0, 0, "IK chain becomes tree, when it shares Root with other Chains");
|
||||||
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-86, 120, 18, &data->weight, 0.0, 1.0, 0.0, 0.0, "Weight of position control for this target");
|
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-86, 120, 18, &data->weight, 0.0, 1.0, 0.0, 0.0, "Weight of position control for this target");
|
||||||
|
|
||||||
uiDefButBitS(block, TOG, KINEMATIC_ORIENTATION, B_CONSTRAINT_TEST, "Orientation", *xco+((width/2)-117), *yco-108,120,18, &data->flag, 0, 0, 0, 0, "Follow orientation of target");
|
uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Orientation", *xco+((width/2)-117), *yco-108,120,18, &data->flag, 0, 0, 0, 0, "Follow orientation of target");
|
||||||
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-108, 120, 18, &data->orientweight, 0.0, 1.0, 0.0, 0.0, "Weight of orientation control for this target");
|
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-108, 120, 18, &data->orientweight, 0.0, 1.0, 0.0, 0.0, "Weight of orientation control for this target");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1248,7 +1248,7 @@ void add_primitiveArmature(int type)
|
|||||||
/* the ctrl-click method */
|
/* the ctrl-click method */
|
||||||
void addvert_armature(void)
|
void addvert_armature(void)
|
||||||
{
|
{
|
||||||
EditBone *ebone, *newbone, *partest;
|
EditBone *ebone, *newbone;
|
||||||
float *curs, mat[3][3],imat[3][3];
|
float *curs, mat[3][3],imat[3][3];
|
||||||
int to_root= 0;
|
int to_root= 0;
|
||||||
|
|
||||||
@@ -1279,16 +1279,8 @@ void addvert_armature(void)
|
|||||||
else {
|
else {
|
||||||
VECCOPY(newbone->head, ebone->tail);
|
VECCOPY(newbone->head, ebone->tail);
|
||||||
|
|
||||||
|
|
||||||
/* See if there are any ik children of the parent */
|
|
||||||
for (partest = G.edbo.first; partest; partest= partest->next){
|
|
||||||
if ((partest->parent == ebone) && (partest->flag & BONE_IK_TOPARENT))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!partest)
|
|
||||||
newbone->flag |= BONE_IK_TOPARENT;
|
|
||||||
|
|
||||||
newbone->parent= ebone;
|
newbone->parent= ebone;
|
||||||
|
newbone->flag |= BONE_IK_TOPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
curs= give_cursor();
|
curs= give_cursor();
|
||||||
@@ -1453,37 +1445,6 @@ void show_all_armature_bones(void)
|
|||||||
allqueue(REDRAWBUTSEDIT, 0);
|
allqueue(REDRAWBUTSEDIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* the "IK" button in editbuttons */
|
|
||||||
void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
|
|
||||||
{
|
|
||||||
EditBone *ebone= bonev;
|
|
||||||
attach_bone_to_parent(ebone);
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach_bone_to_parent(EditBone *bone)
|
|
||||||
{
|
|
||||||
EditBone *ebone;
|
|
||||||
|
|
||||||
if (bone->flag & BONE_IK_TOPARENT) {
|
|
||||||
|
|
||||||
/* See if there are any other bones that refer to the same
|
|
||||||
* parent and disconnect them
|
|
||||||
*/
|
|
||||||
for (ebone = G.edbo.first; ebone; ebone=ebone->next){
|
|
||||||
if (ebone!=bone){
|
|
||||||
if (ebone->parent && (ebone->parent == bone->parent) &&
|
|
||||||
(ebone->flag & BONE_IK_TOPARENT))
|
|
||||||
ebone->flag &= ~BONE_IK_TOPARENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attach this bone to its parent */
|
|
||||||
VECCOPY(bone->head, bone->parent->tail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_bone_parent(void)
|
void make_bone_parent(void)
|
||||||
{
|
{
|
||||||
EditBone *ebone;
|
EditBone *ebone;
|
||||||
@@ -1631,7 +1592,7 @@ void unique_editbone_name (char *name)
|
|||||||
void extrude_armature(int forked)
|
void extrude_armature(int forked)
|
||||||
{
|
{
|
||||||
bArmature *arm= G.obedit->data;
|
bArmature *arm= G.obedit->data;
|
||||||
EditBone *newbone, *ebone, *flipbone, *first=NULL, *partest;
|
EditBone *newbone, *ebone, *flipbone, *first=NULL;
|
||||||
int a, totbone= 0, do_extrude;
|
int a, totbone= 0, do_extrude;
|
||||||
|
|
||||||
TEST_EDITARMATURE;
|
TEST_EDITARMATURE;
|
||||||
@@ -1713,16 +1674,7 @@ void extrude_armature(int forked)
|
|||||||
newbone->segments= 1;
|
newbone->segments= 1;
|
||||||
newbone->boneclass= ebone->boneclass;
|
newbone->boneclass= ebone->boneclass;
|
||||||
|
|
||||||
/* See if there are any ik children of the parent */
|
newbone->flag |= BONE_IK_TOPARENT;
|
||||||
if(do_extrude==1) {
|
|
||||||
for (partest = G.edbo.first; partest; partest=partest->next){
|
|
||||||
if ((partest->parent == ebone) && (partest->flag & BONE_IK_TOPARENT))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!partest)
|
|
||||||
newbone->flag |= BONE_IK_TOPARENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy (newbone->name, ebone->name);
|
strcpy (newbone->name, ebone->name);
|
||||||
|
|
||||||
|
|||||||
@@ -299,6 +299,12 @@ void pose_add_IK(void)
|
|||||||
set_constraint_target(con, ob, pchansel->name);
|
set_constraint_target(con, ob, pchansel->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* active flag */
|
||||||
|
con->flag |= CONSTRAINT_ACTIVE;
|
||||||
|
for(con= con->prev; con; con= con->prev)
|
||||||
|
con->flag &= ~CONSTRAINT_ACTIVE;
|
||||||
|
|
||||||
|
|
||||||
ob->pose->flag |= POSE_RECALC; // sort pose channels
|
ob->pose->flag |= POSE_RECALC; // sort pose channels
|
||||||
DAG_scene_sort(G.scene); // sort order of objects
|
DAG_scene_sort(G.scene); // sort order of objects
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user