Dual Links for control bones: Control bones that start and end on specific joints will do the same after retarget.

Template Renaming: Fix renaming to handle contraints properly

Template Renaming with Action constraints video available online: http://vimeo.com/2206779 and http://blenderartists.org/~theeth/bf/etch-a-ton/retarget_fingers_action.ogv
This commit is contained in:
Martin Poirier
2008-11-10 19:43:11 +00:00
parent f0a23dce9a
commit 5443d2d86b
4 changed files with 131 additions and 23 deletions

View File

@@ -72,13 +72,13 @@ EditBone *addEditBone(char *name, struct ListBase *ebones, struct bArmature *arm
/* duplicate method */
void preEditBoneDuplicate(struct ListBase *editbones);
EditBone *duplicateEditBone(EditBone *curBone, struct ListBase *editbones, struct Object *ob);
EditBone *duplicateEditBone(EditBone *curBone, char *name, struct ListBase *editbones, struct Object *ob);
void updateDuplicateSubtarget(EditBone *dupBone, struct ListBase *editbones, struct Object *ob);
/* duplicate method (cross objects */
/* editbones is the target list */
EditBone *duplicateEditBoneObjects(EditBone *curBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
/* editbones is the source list */
void updateDuplicateSubtargetObjects(EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);

View File

@@ -121,6 +121,12 @@ typedef struct RigEdge {
#define RIG_CTRL_DONE (RIG_CTRL_HEAD_DONE|RIG_CTRL_TAIL_DONE)
/* Control tail flags */
typedef enum {
TL_NONE = 0,
TL_TAIL,
TL_HEAD
} LinkTailMode;
typedef struct RigControl {
struct RigControl *next, *prev;
@@ -130,7 +136,9 @@ typedef struct RigControl {
EditBone *link_tail;
float up_axis[3];
float offset[3];
float qrot[4]; /* for dual linked bones, store the rotation of the linked bone for the finalization */
int flag;
LinkTailMode tail_mode;
} RigControl;
void BIF_retargetArc(ReebArc *earc);

View File

@@ -2288,7 +2288,7 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob
}
EditBone *duplicateEditBoneObjects(EditBone *curBone, ListBase *editbones, Object *src_ob, Object *dst_ob)
EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
{
EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone");
@@ -2297,6 +2297,11 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, ListBase *editbones, Objec
curBone->temp = eBone;
eBone->temp = curBone;
if (name != NULL)
{
BLI_strncpy(eBone->name, name, 32);
}
unique_editbone_name(editbones, eBone->name, NULL);
BLI_addtail(editbones, eBone);
@@ -2345,9 +2350,9 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, ListBase *editbones, Objec
return eBone;
}
EditBone *duplicateEditBone(EditBone *curBone, ListBase *editbones, Object *ob)
EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob)
{
return duplicateEditBoneObjects(curBone, editbones, ob, ob);
return duplicateEditBoneObjects(curBone, name, editbones, ob, ob);
}
void adduplicate_armature(void)

View File

@@ -400,7 +400,7 @@ static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone)
}
/************************************** CLONING TEMPLATES **********************************************/
static void renameTemplateBone(EditBone *bone, char *template_name, ListBase *editbones)
static void renameTemplateBone(char *name, char *template_name, ListBase *editbones)
{
char *side_string = G.scene->toolsettings->skgen_side_string;
char *num_string = G.scene->toolsettings->skgen_num_string;
@@ -412,35 +412,36 @@ static void renameTemplateBone(EditBone *bone, char *template_name, ListBase *ed
{
if (template_name[i+1] == 'S')
{
j += sprintf(bone->name + j, side_string);
j += sprintf(name + j, side_string);
i++;
}
else if (template_name[i+1] == 'N')
{
j += sprintf(bone->name + j, num_string);
j += sprintf(name + j, num_string);
i++;
}
else
{
bone->name[j] = template_name[i];
name[j] = template_name[i];
j++;
}
}
else
{
bone->name[j] = template_name[i];
name[j] = template_name[i];
j++;
}
}
bone->name[j] = '\0';
name[j] = '\0';
unique_editbone_name(editbones, bone->name, bone);
unique_editbone_name(editbones, name, NULL);
}
static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash)
{
RigControl *ctrl;
char name[32];
ctrl = newRigControl(rg);
@@ -449,14 +450,16 @@ static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_
VECCOPY(ctrl->up_axis, src_ctrl->up_axis);
VECCOPY(ctrl->offset, src_ctrl->offset);
ctrl->tail_mode = src_ctrl->tail_mode;
ctrl->flag = src_ctrl->flag;
ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, rg->editbones, src_rg->ob, rg->ob);
renameTemplateBone(ctrl->bone, src_ctrl->bone->name, rg->editbones);
renameTemplateBone(name, src_ctrl->bone->name, rg->editbones);
ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
ctrl->link = src_ctrl->link;
ctrl->link_tail = src_ctrl->link_tail;
return ctrl;
}
@@ -493,8 +496,9 @@ static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *
if (src_edge->bone != NULL)
{
edge->bone = duplicateEditBoneObjects(src_edge->bone, rg->editbones, src_rg->ob, rg->ob);
renameTemplateBone(edge->bone, src_edge->bone->name, rg->editbones);
char name[32];
renameTemplateBone(name, src_edge->bone->name, rg->editbones);
edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
}
@@ -581,6 +585,7 @@ static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob)
}
ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link);
ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail);
}
BLI_ghash_free(ptr_hash, NULL, NULL);
@@ -613,6 +618,7 @@ static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
VECCOPY(ctrl->head, bone->head);
VECCOPY(ctrl->tail, bone->tail);
getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis);
ctrl->tail_mode = TL_NONE;
BLI_ghash_insert(rg->controls_map, bone->name, ctrl);
}
@@ -900,8 +906,54 @@ static void RIG_reconnectControlBones(RigGraph *rg)
}
}
}
}
/* third pass, link control tails */
for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
{
/* fit bone already means full match, so skip those */
if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0)
{
GHashIterator ghi;
/* look on deform bones first */
BLI_ghashIterator_init(&ghi, rg->bones_map);
for( ; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi))
{
EditBone *bone = (EditBone*)BLI_ghashIterator_getValue(&ghi);
/* don't link with parent */
if (bone->parent != ctrl->bone)
{
if (VecLenf(ctrl->bone->tail, bone->head) < 0.01)
{
printf("%s -> %s: TL_HEAD\n", ctrl->bone->name, bone->name);
ctrl->tail_mode = TL_HEAD;
ctrl->link_tail = bone;
break;
}
else if (VecLenf(ctrl->bone->tail, bone->tail) < 0.01)
{
printf("%s -> %s: TL_TAIL\n", ctrl->bone->name, bone->name);
ctrl->tail_mode = TL_TAIL;
ctrl->link_tail = bone;
break;
}
}
}
/* if we haven't found one yet, look in control bones */
if (ctrl->tail_mode == TL_NONE)
{
}
}
else
{
printf("%s FIT\n", ctrl->bone->name);
}
}
}
/*******************************************************************************************************/
@@ -1666,31 +1718,68 @@ void generateMissingArcs(RigGraph *rigg)
static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize);
static void repositionTailControl(RigGraph *rigg, RigControl *ctrl);
static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float qrot[4], float resize)
static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize)
{
if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE)
{
RigControl *ctrl_child;
ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, qrot);
/* if there was a tail link: apply link, recalc resize factor and qrot */
if (ctrl->tail_mode != TL_NONE)
{
float *tail_vec = NULL;
float v1[3], v2[3], qtail[4];
if (ctrl->tail_mode == TL_TAIL)
{
tail_vec = ctrl->link_tail->tail;
}
else if (ctrl->tail_mode == TL_HEAD)
{
tail_vec = ctrl->link_tail->head;
}
VecSubf(v1, ctrl->bone->tail, ctrl->bone->head);
VecSubf(v2, tail_vec, ctrl->bone->head);
VECCOPY(ctrl->bone->tail, tail_vec);
RotationBetweenVectorsToQuat(qtail, v1, v2);
QuatMul(ctrl->qrot, qtail, ctrl->qrot);
resize = VecLength(v2) / VecLenf(ctrl->head, ctrl->tail);
}
ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot);
/* Cascade to connected control bones */
for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
{
if (ctrl_child->link == ctrl->bone)
{
repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, qrot, resize);
repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize);
}
if (ctrl_child->link_tail == ctrl->bone)
{
repositionTailControl(rigg, ctrl_child);
}
}
}
}
static void repositionTailControl(RigGraph *rigg, RigControl *ctrl)
{
ctrl->flag |= RIG_CTRL_TAIL_DONE;
finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */
}
static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize)
{
float parent_offset[3], tail_offset[3];
VECCOPY(parent_offset, ctrl->offset);
VecMulf(parent_offset, resize);
QuatMulVecf(qrot, parent_offset);
@@ -1699,7 +1788,9 @@ static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], f
ctrl->flag |= RIG_CTRL_HEAD_DONE;
if (ctrl->link_tail == NULL)
QUATCOPY(ctrl->qrot, qrot);
if (ctrl->tail_mode == TL_NONE)
{
VecSubf(tail_offset, ctrl->tail, ctrl->head);
VecMulf(tail_offset, resize);
@@ -1710,7 +1801,7 @@ static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], f
ctrl->flag |= RIG_CTRL_TAIL_DONE;
}
finalizeControl(rigg, ctrl, qrot, resize);
finalizeControl(rigg, ctrl, resize);
}
static void repositionBone(RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3])
@@ -1755,6 +1846,10 @@ static void repositionBone(RigGraph *rigg, RigEdge *edge, float vec0[3], float v
{
repositionControl(rigg, ctrl, vec0, vec1, qrot, resize);
}
if (ctrl->link_tail == bone)
{
repositionTailControl(rigg, ctrl);
}
}
}