diff options
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 6 | ||||
-rw-r--r-- | source/blender/include/transform.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 10 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 4 | ||||
-rw-r--r-- | source/blender/src/transform.c | 85 | ||||
-rw-r--r-- | source/blender/src/transform_conversions.c | 33 |
7 files changed, 125 insertions, 25 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index ab15770c3df..6bdb663545c 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1589,11 +1589,11 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* set DoF flag */ flag= 0; - if((pchan->ikflag & BONE_IK_NO_XDOF) == 0) + if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP)) flag |= IK_XDOF; - if((pchan->ikflag & BONE_IK_NO_YDOF) == 0) + if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP)) flag |= IK_YDOF; - if((pchan->ikflag & BONE_IK_NO_ZDOF) == 0) + if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP)) flag |= IK_ZDOF; if(tree->stretch && (pchan->ikstretch > 0.0)) { diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 623514a1a32..52eb3edf19f 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -45,6 +45,7 @@ struct Object; struct View3D; struct ScrArea; struct bPose; +struct bConstraint; typedef struct NumInput { @@ -142,6 +143,7 @@ typedef struct TransData { float smtx[3][3]; /* Transformation matrix from global space to data space */ float axismtx[3][3];/* Axis orientation matrix of the data */ struct Object *ob; + struct bConstraint *con; /* for objects/bones, the first constraint in its constraint stack */ TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */ void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */ diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 3c5ef7c94e6..707460d0fb6 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -39,7 +39,6 @@ struct Object; /* PoseChannel stores the results of Actions (ipos) and transform information with respect to the restposition of Armature bones */ - typedef struct bPoseChannel { struct bPoseChannel *next, *prev; ListBase constraints;/* Constraints that act on this PoseChannel */ @@ -50,7 +49,7 @@ typedef struct bPoseChannel { short ikflag; /* settings for IK bones */ short selectflag; /* copy of bone flag, so you can work with library armatures */ short protectflag; /* protect channels from being transformed */ - short pad2; + short customCol; /* index of custom color set to use (0=default - used for all old files) */ int pathlen; /* for drawing paths, the amount of frames */ int pathsf; /* for drawing paths, the start frame number */ @@ -84,7 +83,6 @@ typedef struct bPoseChannel { float *path; /* totpath x 3 x float */ struct Object *custom; /* draws custom object instead of this channel */ - } bPoseChannel; /* Pose-Object. It is only found under ob->pose. It is not library data, even @@ -217,7 +215,11 @@ typedef enum PCHAN_IKFLAG { BONE_IK_XLIMIT = (1<<3), BONE_IK_YLIMIT = (1<<4), - BONE_IK_ZLIMIT = (1<<5) + BONE_IK_ZLIMIT = (1<<5), + + BONE_IK_NO_XDOF_TEMP = (1<<10), + BONE_IK_NO_YDOF_TEMP = (1<<11), + BONE_IK_NO_ZDOF_TEMP = (1<<12) } PCHAN_IKFLAG; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 72506b0eb57..1b289650e2c 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -294,7 +294,7 @@ typedef struct bRotLimitConstraint { float ymin, ymax; float zmin, zmax; short flag; - short pad1; + short flag2; } bRotLimitConstraint; /* Limit Scaling Constraint */ @@ -303,7 +303,7 @@ typedef struct bSizeLimitConstraint { float ymin, ymax; float zmin, zmax; short flag; - short pad1; + short flag2; } bSizeLimitConstraint; /* ------------------------------------------ */ @@ -471,9 +471,11 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG { #define LIMIT_YROT 0x02 #define LIMIT_ZROT 0x04 -/* not used anymore - for older Limit Location constraints only */ + /* not used anymore - for older Limit Location constraints only */ #define LIMIT_NOPARENT 0x01 - + /* for all Limit constraints - allow to be used during transform? */ +#define LIMIT_TRANSFORM 0x02 + /* python constraint -> flag */ #define PYCON_USETARGETS 0x01 #define PYCON_SCRIPTERROR 0x02 diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 6da410be246..2d51064112b 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -459,7 +459,6 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short bwidth = 125; tarx = 120; ownx = 0; - } else if (target == -1) { bwidth = 125; @@ -1284,6 +1283,9 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), -1000, 1000, 0.1,0.5,"Highest z value to allow"); uiBlockEndAlign(block); + // temp placement!!! + uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "Trans", *xco+245, *yco-100, 50, 18, &data->flag2, 0, 24, 0, 0, "Only use during transform"); + /* constraint space settings */ draw_constraint_spaceselect(block, con, *xco, *yco-100, is_armature_owner(ob), -1); } diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 3a438f7331a..637bed97abd 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -49,6 +49,7 @@ #include "DNA_armature_types.h" #include "DNA_action_types.h" /* for some special action-editor settings */ +#include "DNA_constraint_types.h" #include "DNA_ipo_types.h" /* some silly ipo flag */ #include "DNA_listBase.h" #include "DNA_meshdata_types.h" @@ -80,6 +81,7 @@ #include "BIF_editaction.h" #include "BKE_action.h" /* get_action_frame */ +#include "BKE_constraint.h" #include "BKE_global.h" #include "BKE_utildefines.h" #include "BKE_bad_level_calls.h"/* popmenu and error */ @@ -1251,7 +1253,7 @@ void ManipulatorTransform() } -/* ************************** TRANSFORMATIONS **************************** */ +/* ************************** TRANSFORM LOCKS **************************** */ static void protectedTransBits(short protectflag, float *vec) { @@ -1310,6 +1312,79 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu } } +/* ******************* TRANSFORM LIMITS ********************** */ + +static void constraintTransLim(TransInfo *t, TransData *td) +{ + if (td->con) { + bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); + bConstraintOb *cob; + bConstraint *con; + + /* Make a temporary bConstraintOb for using these limit constraints + * - they only care that cob->matrix is correctly set ;-) + * - current space should be local + */ + cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb-Transform"); + Mat4One(cob->matrix); + if (td->tdi) { + TransDataIpokey *tdi= td->tdi; + cob->matrix[3][0]= tdi->locx[0]; + cob->matrix[3][1]= tdi->locy[0]; + cob->matrix[3][2]= tdi->locz[0]; + } + else { + VECCOPY(cob->matrix[3], td->loc); + } + + /* Evaluate valid constraints */ + for (con= td->con; con; con= con->next) { + /* we're only interested in Limit-Location constraints */ + if (con->type == CONSTRAINT_TYPE_LOCLIMIT) { + bLocLimitConstraint *data= con->data; + float tmat[4][4]; + + /* only use it if it's tagged for this purpose */ + if ((data->flag2 & LIMIT_TRANSFORM)==0) + continue; + + /* do space conversions */ + if (con->ownspace == CONSTRAINT_SPACE_WORLD) { + /* just multiply by td->mtx (this should be ok) */ + Mat4CpyMat4(tmat, cob->matrix); + Mat4MulMat34(cob->matrix, td->mtx, tmat); // checkme + } + else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) { + /* skip... incompatable spacetype */ + continue; + } + + /* do constraint */ + cti->evaluate_constraint(con, cob, NULL); + + /* convert spaces again */ + if (con->ownspace == CONSTRAINT_SPACE_WORLD) { + /* just multiply by td->mtx (this should be ok) */ + Mat4CpyMat4(tmat, cob->matrix); + Mat4MulMat34(cob->matrix, td->smtx, tmat); // checkme + } + } + } + + /* copy results from cob->matrix, and free */ + if (td->tdi) { + TransDataIpokey *tdi= td->tdi; + tdi->locx[0]= cob->matrix[3][0]; + tdi->locy[0]= cob->matrix[3][1]; + tdi->locz[0]= cob->matrix[3][2]; + } + else { + VECCOPY(td->loc, cob->matrix[3]); + } + MEM_freeN(cob); + } +} + /* ************************** WARP *************************** */ void initWarp(TransInfo *t) @@ -2484,10 +2559,10 @@ static void applyTranslation(TransInfo *t, float vec[3]) { for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + if (t->con.applyVec) { float pvec[3]; t->con.applyVec(t, td, vec, tvec, pvec); @@ -2495,7 +2570,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) { else { VECCOPY(tvec, vec); } - + Mat3MulVecfl(td->smtx, tvec); VecMulf(tvec, td->factor); @@ -2509,6 +2584,8 @@ static void applyTranslation(TransInfo *t, float vec[3]) { add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]); } else VecAddf(td->loc, td->iloc, tvec); + + constraintTransLim(t, td); } } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 1d18577668e..8c8894affbd 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -616,6 +616,9 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr Mat3Inv (td->smtx, td->mtx); } } + + /* store reference to first constraint */ + td->con= pchan->constraints.first; } static void bone_children_clear_transflag(ListBase *lb) @@ -689,11 +692,15 @@ static void pose_grab_with_ik_clear(Object *ob) bPoseChannel *pchan; bConstraint *con; - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - for(con= pchan->constraints.first; con; con= con->next) { - if(con->type==CONSTRAINT_TYPE_KINEMATIC) { + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + /* clear all temporary lock flags */ + pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP|BONE_IK_NO_YDOF_TEMP|BONE_IK_NO_ZDOF_TEMP); + + /* remove all temporary IK-constraints added */ + for (con= pchan->constraints.first; con; con= con->next) { + if (con->type==CONSTRAINT_TYPE_KINEMATIC) { data= con->data; - if(data->flag & CONSTRAINT_IK_TEMP) { + if (data->flag & CONSTRAINT_IK_TEMP) { BLI_remlink(&pchan->constraints, con); MEM_freeN(con->data); MEM_freeN(con); @@ -716,14 +723,14 @@ static void pose_grab_with_ik_add(bPoseChannel *pchan) } /* rule: not if there's already an IK on this channel */ - for(con= pchan->constraints.first; con; con= con->next) + for (con= pchan->constraints.first; con; con= con->next) if(con->type==CONSTRAINT_TYPE_KINEMATIC) break; - if(con) { + if (con) { /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */ data= has_targetless_ik(pchan); - if(data) + if (data) data->flag |= CONSTRAINT_IK_AUTO; return; } @@ -737,7 +744,13 @@ static void pose_grab_with_ik_add(bPoseChannel *pchan) data->rootbone= 1; /* we include only a connected chain */ - while(pchan && (pchan->bone->flag & BONE_CONNECTED)) { + while ((pchan) && (pchan->bone->flag & BONE_CONNECTED)) { + /* here, we set ik-settings for bone from pchan->protectflag */ + if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; + if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; + if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; + + /* now we count this pchan as being included */ data->rootbone++; pchan= pchan->parent; } @@ -2721,6 +2734,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) Mat3CpyMat4(td->axismtx, ob->obmat); Mat3Ortho(td->axismtx); + td->con= ob->constraints.first; + /* hack: tempolarily disable tracking and/or constraints when getting * object matrix, if tracking is on, or if constraints don't need * inverse correction to stop it from screwing up space conversion @@ -3312,7 +3327,7 @@ static void createTransObject(TransInfo *t) td->flag= TD_SELECTED; td->protectflag= ob->protectflag; td->ext = tx; - + /* store ipo keys? */ if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { |