== Peach Feature Requests (Bone-Path Drawing) ==
authorJoshua Leung <aligorith@gmail.com>
Tue, 13 Nov 2007 11:54:20 +0000 (11:54 +0000)
committerJoshua Leung <aligorith@gmail.com>
Tue, 13 Nov 2007 11:54:20 +0000 (11:54 +0000)
* Added a new option to only calculate a certain number of frames before/after the current frame instead of defining a frame range. This is useful in certain cases on longer timelines, to be able to view the paths for certain regions quicker.

* When inserting a keyframe, if a bone already has path drawing on, the path for that bone will get automatically recalculated. More testing is required to see if there are any more cases where this would be useful. Also, a global setting to turn this on/off would be a good idea.

Todo (requested but not yet implemented):
* Parts of path before/after current frame could get drawn with different colours

source/blender/makesdna/DNA_armature_types.h
source/blender/src/buttons_editing.c
source/blender/src/drawarmature.c
source/blender/src/editipo.c
source/blender/src/poseobject.c

index f178820ac02d0bda1a674dde5b72581d362d50c7..82d120533d6da6ee04e4e762d42ef1ca748640fb 100644 (file)
@@ -79,10 +79,11 @@ typedef struct bArmature {
        short           deformflag; 
        short           pathflag;
        short           layer, layer_protected;         /* for buttons to work, both variables in this order together */
-       short           ghostep, ghostsize;             /*number of frames to ghosts to show, and step between them  */
+       short           ghostep, ghostsize;             /* number of frames to ghosts to show, and step between them  */
        short           ghosttype, pathsize;            /* ghost drawing options and number of frames between points of path */
        int                     ghostsf, ghostef;               /* start and end frames of ghost-drawing range */
-       int             pathsf, pathef;                 /* start and end frames of path-calculation range for all bones */      
+       int             pathsf, pathef;                 /* start and end frames of path-calculation range for all bones */
+       int                     pathbc, pathac;                 /* number of frames before/after current frame of path-calculation for all bones  */
 }bArmature;
 
 /* armature->flag */
@@ -117,9 +118,10 @@ typedef struct bArmature {
 #define                ARM_DEF_B_BONE_REST     8
 
 /* armature->pathflag */
-#define                ARM_PATH_FNUMS  0x001
-#define                ARM_PATH_KFRAS  0x002
-#define                ARM_PATH_HEADS  0x004
+#define                ARM_PATH_FNUMS          (1<<0)
+#define                ARM_PATH_KFRAS          (1<<1)
+#define                ARM_PATH_HEADS          (1<<2)
+#define        ARM_PATH_ACFRA          (1<<3)
 
 /* armature->ghosttype */
 #define        ARM_GHOST_CUR   0
index 24964b30ce95d7826291df00dd91f506f03d3198..c393cdade9a8db441f0128be0659517a57ce6f3a 100644 (file)
@@ -3771,6 +3771,10 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
                arm->pathsf = SFRA;
                arm->pathef = EFRA;
        }
+       if ((arm->pathbc == 0) || (arm->pathac == 0)) {
+               arm->pathbc = 15;
+               arm->pathac = 15;
+       }
        
        /* Ghost Drawing Options */
        uiDefBut(block, LABEL, 0, "Ghost Options", 10,180,150,20, 0, 0, 0, 0, 0, "");
@@ -3804,14 +3808,21 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
        uiBlockEndAlign(block);
        
        uiBlockBeginAlign(block);
-       uiDefButI(block, NUM,REDRAWVIEW3D,"PSta:",170,100,80,20, &arm->pathsf, 1.0, MAXFRAMEF, 0, 0, "The start frame for Bone Path display range");
-       uiDefButI(block, NUM,REDRAWVIEW3D,"PEnd:",250,100,80,20, &arm->pathef, arm->pathsf, MAXFRAMEF, 0, 0, "The end frame for Bone Path display range");      
-       uiDefButBitS(block, TOG, ARM_PATH_HEADS, REDRAWVIEW3D, "Bone-Head Path", 170, 80, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate the Path travelled by the Bone's Head instead of Tail");
+       uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 105, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate Bone Path around the current frame");
+       if (arm->pathflag & ARM_PATH_ACFRA) {
+               uiDefButI(block, NUM,REDRAWVIEW3D,"PPre:",170,85,80,20, &arm->pathbc, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames before current frame for Bone Path display range");
+               uiDefButI(block, NUM,REDRAWVIEW3D,"PPost:",250,85,80,20, &arm->pathac, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames after current frame for Bone Path display range"); 
+       }
+       else {
+               uiDefButI(block, NUM,REDRAWVIEW3D,"PSta:",170,85,80,20, &arm->pathsf, 1.0, MAXFRAMEF, 0, 0, "The start frame for Bone Path display range");
+               uiDefButI(block, NUM,REDRAWVIEW3D,"PEnd:",250,85,80,20, &arm->pathef, arm->pathsf, MAXFRAMEF, 0, 0, "The end frame for Bone Path display range");       
+       }
+       uiDefButBitS(block, TOG, ARM_PATH_HEADS, REDRAWVIEW3D, "Bone-Head Path", 170, 65, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate the Path travelled by the Bone's Head instead of Tail");
        uiBlockEndAlign(block);
        
        uiBlockBeginAlign(block);
-       uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 170,40,160,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones");
-       uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear All Paths", 170,20,160,20, 0, 0, 0, 0, 0, "Clears all bone paths");
+       uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 170,30,160,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones");
+       uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear All Paths", 170,10,160,20, 0, 0, 0, 0, 0, "Clears all bone paths");
        uiBlockEndAlign(block);
 }
 
index 601a3fdf589cb58263217f35882543d0312ead80..c424a24718bc31ff90a41e0360698e5dccb94da3 100644 (file)
@@ -1749,17 +1749,20 @@ static void draw_pose_paths(Object *ob)
        if (arm->pathsize == 0) arm->pathsize= 1;
        stepsize = arm->pathsize;
        
-       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               if(pchan->bone->layer & arm->layer) {
-                       if(pchan->path) {
+       for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+               if (pchan->bone->layer & arm->layer) {
+                       if (pchan->path) {
                                /* version patch here - cannot access frame info from file reading */
                                if ((pchan->pathsf == 0) || (pchan->pathef == 0)) {
                                        pchan->pathsf= SFRA;
                                        pchan->pathef= EFRA;
                                }
+                               
+                               /* get start frame of calculated range */
                                sfra= pchan->pathsf;
                                
                                /* draw curve-line of path */
+                               // TODO: show before/after with slight difference in colour intensity
                                BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
                                glBegin(GL_LINE_STRIP);
                                for(a=0, fp= pchan->path; a<pchan->pathlen; a++, fp+=3)
@@ -1779,7 +1782,7 @@ static void draw_pose_paths(Object *ob)
                                /* Draw little white dots at each framestep value */
                                BIF_ThemeColor(TH_TEXT_HI);
                                glBegin(GL_POINTS);
-                               for(a=0, fp= pchan->path; a<pchan->pathlen; a+=stepsize, fp+=(stepsize*3)) 
+                               for (a=0, fp= pchan->path; a<pchan->pathlen; a+=stepsize, fp+=(stepsize*3)) 
                                        glVertex3fv(fp);
                                glEnd();
                                
index 52b485c539b47960232de1215d755b9d974b1741..8375e9713eae3016da087a02329c3831caef0aff 100644 (file)
@@ -3050,12 +3050,13 @@ void common_insertkey(void)
 
                if (ob && (ob->flag & OB_POSEMODE)){
                        bPoseChannel *pchan;
-
+                       short recalc_bonepaths= 0;
+                       
                        if (ob->action && ob->action->id.lib) {
                                error ("Can't key libactions");
                                return;
                        }
-
+                       
                        id= &ob->id;
                        for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
                                if (pchan->flag & POSE_KEY) {
@@ -3134,11 +3135,23 @@ void common_insertkey(void)
                                        /* clear unkeyed flag (it doesn't matter if it's set or not) */
                                        if (pchan->bone)
                                                pchan->bone->flag &= ~BONE_UNKEYED;
+                                               
+                                       /* check if bone has a path */
+                                       if (pchan->path)
+                                               recalc_bonepaths = 1;
                                }
                        }
+                       
+                       /* recalculate ipo handles, etc. */
                        if(ob->action)
                                remake_action_ipos(ob->action);
-
+                               
+                       /* recalculate bone-paths on adding new keyframe? */
+                       // TODO: currently, there is no setting to turn this on/off globally
+                       if (recalc_bonepaths)
+                               pose_calculate_path(ob);
+                       
+                       
                        allqueue(REDRAWIPO, 0);
                        allqueue(REDRAWACTION, 0);
                        allqueue(REDRAWNLA, 0);
index faae6bd0da4dcce5596d11611206129063efca74..c0835c84e6216c0d24d1d236500c2f85c7d3f498 100644 (file)
@@ -229,7 +229,7 @@ void pose_calculate_path(Object *ob)
        int cfra;
        int sfra, efra;
        
-       if(ob==NULL || ob->pose==NULL)
+       if (ob==NULL || ob->pose==NULL)
                return;
        arm= ob->data;
        
@@ -238,14 +238,24 @@ void pose_calculate_path(Object *ob)
                arm->pathsf = SFRA;
                arm->pathef = EFRA;
        }
+       if ((arm->pathbc == 0) || (arm->pathac == 0)) {
+               arm->pathbc = 15;
+               arm->pathac = 15;
+       }
        if (arm->pathsize == 0) {
                arm->pathsize = 1;
        }
        
        /* set frame values */
        cfra= CFRA;
-       sfra = arm->pathsf;
-       efra = arm->pathef;
+       if (arm->pathflag & ARM_PATH_ACFRA) {
+               sfra = cfra - arm->pathbc;
+               efra = cfra + arm->pathac;
+       }
+       else {
+               sfra = arm->pathsf;
+               efra = arm->pathef;
+       }
        if (efra<=sfra) return;
        
        DAG_object_update_flags(G.scene, ob, screen_view3d_layers());