== Bone Path Drawing - More Tweaks Again ==

Bugfixes:
* "Clear Paths" change from last commit wasn't complete yet. Now it REALLY only clears the paths of the selected bones

* Button layout in "Armature Visualisation" panel has been reorganised a bit to better present the options (clearer separation between Display and Calculation buttons)

New Stuff (Yay!):
* Paths of active bones now draw more visibly than those of unselected bones. This makes it easier to identify the path that is taken by the bone

* The part of path on the current frame is now drawn in green (the same shade that is used for the current-frame line in the Animation Editors). This nicely blends between the black and blue parts of the path (before and after current frame, respectively), and looks much nicer.

* The colour of the current-frame marker in the Animation Editors and the 3D-View, are now theme-colours. This is needed to make the previous option work.
This commit is contained in:
Joshua Leung
2007-12-02 05:50:38 +00:00
parent 1e32ec2000
commit 77e6a2ba86
11 changed files with 143 additions and 74 deletions

View File

@@ -494,6 +494,7 @@ enum {
TH_NORMAL,
TH_FACE_DOT,
TH_FACEDOT_SIZE,
TH_CFRAME,
TH_SYNTAX_B,
TH_SYNTAX_V,

View File

@@ -41,8 +41,7 @@
/* themes; defines in BIF_resource.h */
struct ColorBand;
// global, button colors
/* global, button colors */
typedef struct ThemeUI {
char outline[4];
char neutral[4];
@@ -68,8 +67,9 @@ typedef struct ThemeUI {
} ThemeUI;
// try to put them all in one, if needed a special struct can be created as well
// for example later on, when we introduce wire colors for ob types or so...
/* try to put them all in one, if needed a special struct can be created as well
* for example later on, when we introduce wire colors for ob types or so...
*/
typedef struct ThemeSpace {
char back[4];
char text[4];
@@ -94,6 +94,7 @@ typedef struct ThemeSpace {
char normal[4];
char bone_solid[4], bone_pose[4];
char strip[4], strip_select[4];
char cframe[4], pad[4];
char vertex_size, facedot_size;
char bpad[2];
@@ -104,16 +105,25 @@ typedef struct ThemeSpace {
char movie[4], image[4], scene[4], audio[4]; // for sequence editor
char effect[4], plugin[4], transition[4], meta[4];
char editmesh_active[4];
} ThemeSpace;
/* set of colors for use as a custom color set for Objects/Bones wire drawing */
typedef struct ThemeWireColor {
char unselected[3];
char selected[3];
char active[3];
char pad[7];
} ThemeWireColor;
/* A theme */
typedef struct bTheme {
struct bTheme *next, *prev;
char name[32];
/* Interface Elements (buttons, menus, icons) */
ThemeUI tui;
/* Individual Spacetypes */
ThemeSpace tbuts;
ThemeSpace tv3d;
ThemeSpace tfile;
@@ -129,9 +139,12 @@ typedef struct bTheme {
ThemeSpace toops;
ThemeSpace ttime;
ThemeSpace tnode;
/* 20 sets of bone colors for this theme */
ThemeWireColor tarm[20];
/*ThemeWireColor tobj[20];*/
unsigned char bpad[4], bpad1[4];
} bTheme;
typedef struct SolidLight {

View File

@@ -3986,10 +3986,10 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
uiDefBut(block, LABEL, 0, "Ghost Options", 10,180,150,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1",
10, 160, 150, 20, &arm->ghosttype, 0, 0, 0, 0, "Choose range of Ghosts to draw for current Action");
uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1",
10, 160, 150, 20, &arm->ghosttype, 0, 0, 0, 0, "Choose range of Ghosts to draw for current Action");
uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -4005,30 +4005,36 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
uiBlockEndAlign(block);
/* Bone Path Drawing Options */
uiDefBut(block, LABEL, 0, "Bone Paths", 165,180,150,20, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Bone Paths Drawing:", 165,180,170,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, ARM_PATH_FNUMS, REDRAWVIEW3D, "Frame Nums", 170, 160, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers on path");
uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",250,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",250,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 105, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Only show 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");
uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 110, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Only show Bone Path around the current frame");
/* only show extra ranges when needed */
if (arm->pathflag & ARM_PATH_ACFRA) {
uiDefButI(block, NUM, REDRAWVIEW3D,"PPre:",170,90,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,90,80,20, &arm->pathac, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames after current frame for Bone Path display range");
}
uiBlockEndAlign(block);
/* Bone Path Calculation Options */
uiDefBut(block, LABEL, 0, "Bone Paths Calc.", 10,50,170,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 10,30,155,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones");
uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear Paths", 10,10,155,20, 0, 0, 0, 0, 0, "Clears bone paths of the selected bones");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
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 bone paths of the selected bones");
uiDefButBitS(block, TOG, ARM_PATH_HEADS, REDRAWVIEW3D, "Bone-Head Path", 170, 30, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate the Path travelled by the Bone's Head instead of Tail");
uiDefButI(block, NUM,REDRAWVIEW3D,"PSta:",170,10,80,20, &arm->pathsf, 1.0, MAXFRAMEF, 0, 0, "The start frame for Bone Path display range");
uiDefButI(block, NUM,REDRAWVIEW3D,"PEnd:",250,10,80,20, &arm->pathef, arm->pathsf, MAXFRAMEF, 0, 0, "The end frame for Bone Path display range");
uiBlockEndAlign(block);
}

View File

@@ -362,7 +362,7 @@ void draw_cfra_action (void)
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
glColor3ub(0x60, 0xc0, 0x40);
BIF_ThemeColor(TH_CFRAME);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
@@ -373,10 +373,10 @@ void draw_cfra_action (void)
/* Draw dark green line if slow-parenting/time-offset is enabled */
ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
if ((ob) && (ob->sf!=0.0) && (ob->ipoflag & OB_OFFS_OB)) {
vec[0]-= ob->sf;
glColor3ub(0x10, 0x60, 0);
BIF_ThemeColorShade(TH_CFRAME, -30);
glBegin(GL_LINE_STRIP);
glVertex2fv(vec);

View File

@@ -1787,35 +1787,60 @@ static void draw_pose_paths(Object *ob)
}
/* draw curve-line of path */
if ((CFRA > sfra) && (CFRA < efra)) {
/* Show before/after current frame with slight difference in colour intensity
* This is done in two loops, as there seems to be some problems with changing color
* or something during a loop (noted somewhere in the codebase)
glShadeModel(GL_SMOOTH);
glBegin(GL_LINE_STRIP);
for (a=0, fp=fp_start; a<len; a++, fp+=3) {
float intensity; /* how faint */
/* set colour
* - more intense for active/selected bones, less intense for unselected bones
* - black for before current frame, green for current frame, blue for after current frame
* - intensity decreases as distance from current frame increases
*/
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min)
if ((a+sfra) < CFRA) {
/* black - before cfra */
if (pchan->bone->flag & BONE_SELECTED) {
// intensity= 0.5;
intensity = SET_INTENSITY(sfra, a, CFRA, 0.25f, 0.75f);
}
else {
//intensity= 0.8;
intensity = SET_INTENSITY(sfra, a, CFRA, 0.55f, 0.90f);
}
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
}
else if ((a+sfra) > CFRA) {
/* blue - after cfra */
if (pchan->bone->flag & BONE_SELECTED) {
//intensity = 0.5;
intensity = SET_INTENSITY(CFRA, a, efra, 0.25f, 0.75f);
}
else {
//intensity = 0.8;
intensity = SET_INTENSITY(CFRA, a, efra, 0.55f, 0.90f);
}
BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
}
else {
/* green - on cfra */
if (pchan->bone->flag & BONE_SELECTED) {
intensity= 0.3;
}
else {
intensity= 0.8;
}
BIF_ThemeColorBlend(TH_CFRAME, TH_BACK, intensity);
}
/* before cfra (darker) */
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5);
glBegin(GL_LINE_STRIP);
for (a=0, fp=fp_start; (sfra+a)<=CFRA; a++, fp+=3)
glVertex3fv(fp);
glEnd();
/* after cfra (lighter) - backtrack a bit so that we don't have gaps */
BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, 0.5);
glBegin(GL_LINE_STRIP);
for (--a, fp-=3; a<len; a++, fp+=3)
glVertex3fv(fp);
glEnd();
}
else {
/* show both directions with same intensity (cfra somewhere else) */
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
glBegin(GL_LINE_STRIP);
for (a=0, fp=fp_start; a<len; a++, fp+=3)
glVertex3fv(fp);
glEnd();
/* draw a vertex with this colour */
glVertex3fv(fp);
}
glEnd();
glShadeModel(GL_FLAT);
glPointSize(1.0);
/* draw little black point at each frame

View File

@@ -1560,7 +1560,7 @@ static void draw_cfra(SpaceIpo *sipo)
vec[0]*= G.scene->r.framelen;
vec[1]= v2d->cur.ymin;
glColor3ub(0x60, 0xc0, 0x40); // no theme, should be global color once...
BIF_ThemeColor(TH_CFRAME);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
@@ -1571,7 +1571,7 @@ static void draw_cfra(SpaceIpo *sipo)
if(sipo->blocktype==ID_OB) {
ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
if (ob && (ob->sf!=0.0) && (ob->ipoflag & OB_OFFS_OB) ) {
vec[0]-= ob->sf;
BIF_ThemeColorShade(TH_HILITE, -30);

View File

@@ -176,8 +176,8 @@ static void draw_cfra_sound(SpaceSound *ssound)
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
glColor3ub(0x20, 0x90, 0x20);
glLineWidth(4.0);
BIF_ThemeColor(TH_CFRAME);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
glVertex2fv(vec);
@@ -186,7 +186,6 @@ static void draw_cfra_sound(SpaceSound *ssound)
glEnd();
glLineWidth(1.0);
}
void drawsoundspace(ScrArea *sa, void *spacedata)

View File

@@ -93,7 +93,7 @@ static void draw_cfra_time(SpaceTime *stime)
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
glColor3ub(0x60, 0xc0, 0x40); // no theme, should be global color once...
BIF_ThemeColor(TH_CFRAME); // no theme, should be global color once...
glLineWidth(3.0);
glBegin(GL_LINES);

View File

@@ -253,33 +253,33 @@ void pose_calculate_path(Object *ob)
DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
/* malloc the path blocks */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
if(arm->layer & pchan->bone->layer) {
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
if (arm->layer & pchan->bone->layer) {
pchan->pathlen= efra-sfra+1;
pchan->pathsf= sfra;
pchan->pathef= efra+1;
if(pchan->path)
if (pchan->path)
MEM_freeN(pchan->path);
pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
}
}
}
for(CFRA=sfra; CFRA<=efra; CFRA++) {
for (CFRA=sfra; CFRA<=efra; CFRA++) {
/* do all updates */
for(base= FIRSTBASE; base; base= base->next) {
if(base->object->recalc) {
for (base= FIRSTBASE; base; base= base->next) {
if (base->object->recalc) {
int temp= base->object->recalc;
object_handle_update(base->object);
base->object->recalc= temp;
}
}
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
if(arm->layer & pchan->bone->layer) {
if(pchan->path) {
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if (pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
if (arm->layer & pchan->bone->layer) {
if (pchan->path) {
fp= pchan->path+3*(CFRA-sfra);
if (arm->pathflag & ARM_PATH_HEADS) {
@@ -307,14 +307,16 @@ void pose_clear_paths(Object *ob)
{
bPoseChannel *pchan;
if(ob==NULL || ob->pose==NULL)
if (ob==NULL || ob->pose==NULL)
return;
/* free the path blocks */
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if (pchan->path) {
MEM_freeN(pchan->path);
pchan->path= NULL;
if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
if (pchan->path) {
MEM_freeN(pchan->path);
pchan->path= NULL;
}
}
}

View File

@@ -274,6 +274,8 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp= ts->strip; break;
case TH_STRIP_SELECT:
cp= ts->strip_select; break;
case TH_CFRAME:
cp= ts->cframe; break;
case TH_SYNTAX_B:
cp= ts->syntaxb; break;
@@ -399,6 +401,7 @@ void BIF_InitTheme(void)
SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
btheme->tv3d.facedot_size= 4;
SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
@@ -605,6 +608,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Normal %%x%d|", TH_NORMAL);
str += sprintf(str, "Bone Solid %%x%d|", TH_BONE_SOLID);
str += sprintf(str, "Bone Pose %%x%d", TH_BONE_POSE);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_IPO:
str += sprintf(str, "Panel %%x%d|", TH_PANEL);
@@ -615,6 +619,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Vertex %%x%d|", TH_VERTEX);
str += sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT);
str += sprintf(str, "Vertex Size %%x%d|", TH_VERTEX_SIZE);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_FILE:
str += sprintf(str, "Selected file %%x%d", TH_HILITE);
@@ -628,6 +633,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Bars selected %%x%d|", TH_HILITE);
str += sprintf(str, "Strips %%x%d|", TH_STRIP);
str += sprintf(str, "Strips selected %%x%d|", TH_STRIP_SELECT);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_ACTION:
//str += sprintf(str, "Panel %%x%d|", TH_PANEL);
@@ -639,6 +645,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Channels Selected %%x%d|", TH_HILITE);
str += sprintf(str, "Long Key %%x%d|", TH_STRIP);
str += sprintf(str, "Long Key selected %%x%d|", TH_STRIP_SELECT);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_IMAGE:
str += sprintf(str, "%%l|");
@@ -660,10 +667,12 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Plugin Strip %%x%d|", TH_SEQ_PLUGIN);
str += sprintf(str, "Transition Strip %%x%d|", TH_SEQ_TRANSITION);
str += sprintf(str, "Meta Strip %%x%d|", TH_SEQ_META);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_SOUND:
str += sprintf(str, "Grid %%x%d|", TH_GRID);
str += sprintf(str, "Window Slider %%x%d|", TH_SHADE1);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_BUTS:
str += sprintf(str, "Panel %%x%d|", TH_PANEL);
@@ -689,6 +698,7 @@ char *BIF_ThemeColorsPup(int spacetype)
break;
case SPACE_TIME:
str += sprintf(str, "Grid %%x%d|", TH_GRID);
str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_NODE:
str += sprintf(str, "Wires %%x%d|", TH_WIRE);

View File

@@ -373,6 +373,19 @@ static void init_userdef_file(void)
if(U.coba_weight.tot==0)
init_colorband(&U.coba_weight, 1);
}
if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 11)) {
bTheme *btheme;
for (btheme= U.themes.first; btheme; btheme= btheme->next) {
/* these should all use the same colour */
SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tipo.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255);
}
}
/* GL Texture Garbage Collection (variable abused above!) */
if (U.textimeout == 0) {