Two transform tweaks:
authorJoshua Leung <aligorith@gmail.com>
Wed, 5 Dec 2007 11:19:36 +0000 (11:19 +0000)
committerJoshua Leung <aligorith@gmail.com>
Wed, 5 Dec 2007 11:19:36 +0000 (11:19 +0000)
* [Peach Request] AutoIK now respects axis locking (rotation locks).
- Temporary DOF-Locks are turned on for those bones that are part of an AutoIK chain while transforming. These locks get cleared after transforming.
- This works for all bones except the root bone of the chain, which doesn't seem to be able to be locked.

* Limit Location constraint can now optionally affect Translations too (i.e. NKEY panel values won't change).
- LimitRot,LimitScale support (for their respective transforms) will be done at a later date
- This only works if the constraint is using World/Local space (the other spaces are not supported yet).
- I've added a temporary button in the LimitLoc panel to enable this option (it is disabled by default). This button will be properly assigned a place in that panel sometime.

source/blender/blenkernel/intern/armature.c
source/blender/include/transform.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/src/buttons_object.c
source/blender/src/transform.c
source/blender/src/transform_conversions.c

index ab15770c3df6de06208867692ffd39dde32093df..6bdb663545c52b5e905074182245666ab93c0974 100644 (file)
@@ -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)) {
index 623514a1a322724eb7ebe7dcc9301637551a8e78..52eb3edf19fdeb7c948a59346dbde5ee31df197c 100644 (file)
@@ -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 */
index 3c5ef7c94e68b34d2f1cda650d325cf23f966a5f..707460d0fb671963eef578f59fda77149b9d0ec2 100644 (file)
@@ -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;
 
 
index 72506b0eb57b8fea731d29255e70e1d8a7888c49..1b289650e2cb2b05698ab94905ed09e9c913dd45 100644 (file)
@@ -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
index 6da410be246924a8d95b283f2daf2bc0b64f0772..2d51064112be31019892f119ecb441ea0f35a122 100644 (file)
@@ -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);
                        }
index 3a438f7331a6450a650b37f926c8e9464b5b4756..637bed97abd4b250bec17c14c62061ce67c84a45 100644 (file)
@@ -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);
        }
 }
 
index 1d18577668e51cbc7e3aa62990bf3c44e199b116..8c8894affbd6ebe38e471052c64b78adad476e16 100644 (file)
@@ -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)) {