IK work-in-progress commit;
authorTon Roosendaal <ton@blender.org>
Sat, 27 Aug 2005 17:04:29 +0000 (17:04 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 27 Aug 2005 17:04:29 +0000 (17:04 +0000)
- 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

source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/intern/armature.c
source/blender/blenloader/intern/readfile.c
source/blender/include/BIF_editarmature.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/editarmature.c
source/blender/src/poseobject.c

index 84d87b2..7d0caa4 100644 (file)
@@ -55,12 +55,12 @@ typedef struct PoseTarget
 
 typedef struct PoseChain
 {
-       struct PoseChain *next, *prev;  // hurms
+       struct PoseChain *next, *prev;
        struct bPoseChannel     **pchanchain;
        struct ListBase targets;
        int             totchannel;
+       int             tree;           // true or false
        float   (*basis_change)[3][3];
-       char    group[32];
        float   tolerance;
        int             iterations;
 } PoseChain;
index 0d516e1..0699ed1 100644 (file)
@@ -1012,10 +1012,10 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
        /* setup the chain data */
        chain = NULL;
 
-       /* if part of group, look for existing chain */
-       if(strlen(data->group) > 0)
+       /* if tree-IK, look for mathing chain */
+       if(data->flag & CONSTRAINT_IK_TREE) 
                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 */
        target= MEM_callocN(sizeof(PoseTarget), "posetarget");
@@ -1025,7 +1025,7 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
                /* make new chain */
                chain= MEM_callocN(sizeof(PoseChain), "posechain");
 
-               strcpy(chain->group, data->group);
+               chain->tree= data->flag & CONSTRAINT_IK_TREE;
                chain->tolerance= data->tolerance;
                chain->iterations= data->iterations;
                chain->totchannel= segcount;
@@ -1223,7 +1223,7 @@ static void execute_posechain(Object *ob, PoseChain *chain)
 
                if(data->weight != 0.0)
                        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);
        }
 
index 9c18265..7434ed3 100644 (file)
@@ -4917,7 +4917,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                bKinematicConstraint *data = (bKinematicConstraint*)con->data;
                                                                data->weight = 1.0f;
                                                                data->orientweight = 0.0f;
-                                                               data->flag &= ~KINEMATIC_ORIENTATION;
+                                                               data->flag &= ~CONSTRAINT_IK_ROT;
                                                        }       
                                                }
                                        }
index 6afe090..d559456 100644 (file)
@@ -103,9 +103,6 @@ void        selectconnected_armature(void);
 void   selectconnected_posearmature(void);
 void   select_bone_by_name (struct bArmature *arm, char *name, int select);
 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 create_vgroups_from_armature(Object *ob, Object *par);
index e8895e9..9f05532 100644 (file)
@@ -67,9 +67,8 @@ typedef struct bKinematicConstraint{
        short           flag;                   /* Like IK to Tip */
        char            subtarget[32];  /* String to specify sub-object target */
 
-       char            group[32];              /* Name of group */
-       float           weight;                 /* Weight of goal in IK group */
-       float           orientweight;
+       float           weight;                 /* Weight of goal in IK tree */
+       float           orientweight;   /* Amount of rotation a target applies on chain */
 } bKinematicConstraint;
 
 typedef struct bTrackToConstraint{
@@ -214,8 +213,9 @@ typedef struct bStretchToConstraint{
 #define PLANE_Z                0x02
 
 /* bKinematicConstraint->flag */
-#define CONSTRAINT_IK_TIP                      1
-#define KINEMATIC_ORIENTATION          2
+#define CONSTRAINT_IK_TIP              1
+#define CONSTRAINT_IK_ROT              2
+#define CONSTRAINT_IK_TREE             4
 
 #endif
 
index 6b458ef..077e3be 100644 (file)
@@ -2065,6 +2065,18 @@ static int editbone_to_parnr (EditBone *bone)
        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)
 {
        if (bone->parNr == -1){
@@ -2073,7 +2085,7 @@ static void parnr_to_editbone(EditBone *bone)
        }
        else{
                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)
 {
        uiBlock         *block;
index 7a1ce94..d514f22 100644 (file)
@@ -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"); 
                                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");
                                
-                               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");
                        }
                        break;
index c3a9a93..78e72a4 100644 (file)
@@ -1248,7 +1248,7 @@ void add_primitiveArmature(int type)
 /* the ctrl-click method */
 void addvert_armature(void)
 {
-       EditBone *ebone, *newbone, *partest;
+       EditBone *ebone, *newbone;
        float *curs, mat[3][3],imat[3][3];
        int to_root= 0;
        
@@ -1279,16 +1279,8 @@ void addvert_armature(void)
        else {
                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->flag |= BONE_IK_TOPARENT;
        }
        
        curs= give_cursor();
@@ -1453,37 +1445,6 @@ void show_all_armature_bones(void)
        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)
 {
        EditBone *ebone;
@@ -1631,7 +1592,7 @@ void unique_editbone_name (char *name)
 void extrude_armature(int forked)
 {
        bArmature *arm= G.obedit->data;
-       EditBone *newbone, *ebone, *flipbone, *first=NULL, *partest;
+       EditBone *newbone, *ebone, *flipbone, *first=NULL;
        int a, totbone= 0, do_extrude;
        
        TEST_EDITARMATURE;
@@ -1713,16 +1674,7 @@ void extrude_armature(int forked)
                                newbone->segments= 1;
                                newbone->boneclass= ebone->boneclass;
                                
-                               /* See if there are any ik children of the parent */
-                               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;
-                               }
+                               newbone->flag |= BONE_IK_TOPARENT;
                                
                                strcpy (newbone->name, ebone->name);
                                
index 3ead7a3..588bf70 100644 (file)
@@ -299,6 +299,12 @@ void pose_add_IK(void)
                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
        DAG_scene_sort(G.scene);                // sort order of objects