diff options
author | Joshua Leung <aligorith@gmail.com> | 2008-03-25 13:36:36 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2008-03-25 13:36:36 +0300 |
commit | 74e835342e6559905f4cdebe6191799629e6fd32 (patch) | |
tree | 7107fce58cf514646c0728469c2de6e61c333983 | |
parent | 34494425fa484c98199b7b1fadc5cbaa894473f6 (diff) |
Two constraints related fixes
* Bugfix #8599d:
When using the ChildOf constraint on bones without parents, with cyclic-offset in action the effect of the cyclic-offset was applied twice. Added a bone option to make the effect of cyclic-offset not be applied to rootbones which have the option 'enabled'.
In the UI, this is presented in the opposite way. It is represented by the 'Offs' button beside the parent-bone selector in the Armature Bones panel when in EditMode.
* Head/Tail setting and Constraint Channels:
Added back in checks to see if the head/tail IPO-curves for Constraint Channels can get applied for the target constraint. I had removed these when applying the patch, but I'd overlooked the fact that users could add an IPO-curve for this from the IPO-editor, potentially mucking up the behaviour of some constraints.
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 33 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 7 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 25 |
4 files changed, 47 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 4bb31c1e9b9..24819f44ac1 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2172,8 +2172,10 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime) } else { Mat4MulMat4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); - /* only rootbones get the cyclic offset */ - VecAddf(pchan->pose_mat[3], pchan->pose_mat[3], ob->pose->cyclic_offset); + + /* only rootbones get the cyclic offset (unless user doesn't want that) */ + if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0) + VecAddf(pchan->pose_mat[3], pchan->pose_mat[3], ob->pose->cyclic_offset); } /* do NLA strip modifiers - i.e. curve follow */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 4a0c799d2be..6cd2147391e 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -84,10 +84,10 @@ /* ******************* Constraint Channels ********************** */ /* Constraint Channels exist in one of two places: * - Under Action Channels in an Action (act->chanbase->achan->constraintChannels) - * - Under Object without object-level action yet (ob->constraintChannels) + * - Under Object without Object-level Action yet (ob->constraintChannels) * - * The main purpose that constraint channels serve is to act as a link - * between an IPO-block which + * The main purpose that Constraint Channels serve is to act as a link + * between an IPO-block (which provides values to interpolate between for some settings) */ /* ------------ Data Management ----------- */ @@ -143,7 +143,7 @@ bConstraintChannel *get_constraint_channel (ListBase *list, const char name[]) { bConstraintChannel *chan; - if(list) { + if (list) { for (chan = list->first; chan; chan=chan->next) { if (!strcmp(name, chan->name)) { return chan; @@ -183,11 +183,11 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, for (con=conbase->first; con; con=con->next) { Ipo *ipo= NULL; - if(con->flag & CONSTRAINT_OWN_IPO) + if (con->flag & CONSTRAINT_OWN_IPO) ipo= con->ipo; else { bConstraintChannel *chan = get_constraint_channel(chanbase, con->name); - if(chan) ipo= chan->ipo; + if (chan) ipo= chan->ipo; } if (ipo) { @@ -206,7 +206,24 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, break; case CO_HEADTAIL: { - con->headtail = icu->curval; + /* we need to check types of constraints that can get this here, as user + * may have created an IPO-curve for this from IPO-editor but for a constraint + * that cannot support this + */ + switch (con->type) { + /* supported constraints go here... */ + case CONSTRAINT_TYPE_LOCLIKE: + case CONSTRAINT_TYPE_TRACKTO: + case CONSTRAINT_TYPE_MINMAX: + case CONSTRAINT_TYPE_STRETCHTO: + case CONSTRAINT_TYPE_DISTLIMIT: + con->headtail = icu->curval; + break; + + default: + /* not supported */ + break; + } } break; } @@ -438,7 +455,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4 /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ if (pchan->parent) { float offs_bone[4][4]; - + /* construct offs_bone the same way it is done in armature.c */ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat); VECCOPY(offs_bone[3], pchan->bone->head); diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index fcc847a1b30..ad03c8af459 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -143,7 +143,7 @@ typedef enum eBone_Flag { BONE_ROOTSEL = (1<<1), BONE_TIPSEL = (1<<2), BONE_TRANSFORM = (1<<3), /* Used instead of BONE_SELECTED during transform */ - BONE_CONNECTED = (1<<4), + BONE_CONNECTED = (1<<4), /* when bone has a parent, connect head of bone to parent's tail*/ /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */ BONE_HIDDEN_P = (1<<6), /* hidden Bones when drawing PoseChannels */ BONE_DONE = (1<<7), /* For detecting cyclic dependancies */ @@ -151,12 +151,13 @@ typedef enum eBone_Flag { BONE_HINGE = (1<<9), /* No parent rotation or scale */ BONE_HIDDEN_A = (1<<10), /* hidden Bones when drawing Armature Editmode */ BONE_MULT_VG_ENV = (1<<11), /* multiplies vgroup with envelope */ - BONE_NO_DEFORM = (1<<12), + BONE_NO_DEFORM = (1<<12), /* bone doesn't deform geometry */ BONE_UNKEYED = (1<<13), /* set to prevent destruction of its unkeyframed pose (after transform) */ BONE_HINGE_CHILD_TRANSFORM = (1<<14), /* set to prevent hinge child bones from influencing the transform center */ BONE_NO_SCALE = (1<<15), /* No parent scale */ BONE_HIDDEN_PG = (1<<16), /* hidden bone when drawing PoseChannels (for ghost drawing) */ - BONE_DRAWWIRE = (1<<17) /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */ + BONE_DRAWWIRE = (1<<17), /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */ + BONE_NO_CYCLICOFFSET = (1<<18) /* when no parent, bone will not get cyclic offset */ } eBone_Flag; #endif diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3f383bb274b..06c04652d55 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4315,38 +4315,41 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) uiDefBut(block, LABEL, 0, "Selected Bones", 0,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode"); by-=20; - for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++){ + for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++) { if ((curBone->flag & BONE_SELECTED) && (curBone->layer & arm->layer)) { - /* Bone naming button */ but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", -10,by,117,18, curBone->name, 0, 31, 0, 0, "Change the bone name"); uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL); uiButSetCompleteFunc(but, autocomplete_editbone, (void *)OBACT); - + uiDefBut(block, LABEL, 0, "child of", 107,by,73,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); - + boneString = MEM_mallocN((BLI_countlist(&G.edbo) * 64)+64, "Bone str"); build_bonestring (boneString, curBone); - + curBone->parNr = editbone_to_parnr(curBone->parent); but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, 180,by,120,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent"); /* last arg NULL means button will put old string there */ uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL); - + MEM_freeN(boneString); - - /* Connect to parent flag */ - if (curBone->parent){ + + if (curBone->parent) { + /* Connect to parent flag */ but=uiDefButBitI(block, TOG, BONE_CONNECTED, B_ARM_RECALCDATA, "Con", 300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Connect this Bone to Parent"); uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL); } - + else { + /* No cyclic-offset flag */ + uiDefButBitI(block, TOGN, BONE_NO_CYCLICOFFSET, B_ARM_RECALCDATA, "Offs", 300,by,31,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Apply cyclic-offset to this Bone"); + } + /* Segment, dist and weight buttons */ uiBlockBeginAlign(block); uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", -10,by-19,117,18, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones"); uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", 110, by-19, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); - + /* bone types */ uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); |