|
Blender
V2.59
|
00001 /* 00002 * $Id: drawarmature.c 38112 2011-07-05 09:35:38Z blendix $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <stdlib.h> 00036 #include <string.h> 00037 #include <math.h> 00038 00039 00040 #include "DNA_anim_types.h" 00041 #include "DNA_armature_types.h" 00042 #include "DNA_constraint_types.h" 00043 #include "DNA_scene_types.h" 00044 #include "DNA_screen_types.h" 00045 #include "DNA_view3d_types.h" 00046 #include "DNA_object_types.h" 00047 00048 #include "BLI_blenlib.h" 00049 #include "BLI_math.h" 00050 #include "BLI_dlrbTree.h" 00051 #include "BLI_utildefines.h" 00052 00053 #include "BKE_animsys.h" 00054 #include "BKE_action.h" 00055 #include "BKE_armature.h" 00056 #include "BKE_global.h" 00057 #include "BKE_modifier.h" 00058 #include "BKE_nla.h" 00059 00060 00061 #include "BIF_gl.h" 00062 #include "BIF_glutil.h" 00063 00064 #include "ED_armature.h" 00065 #include "ED_keyframes_draw.h" 00066 00067 #include "BLF_api.h" 00068 00069 #include "UI_resources.h" 00070 00071 #include "view3d_intern.h" 00072 00073 00074 /* *************** Armature Drawing - Coloring API ***************************** */ 00075 00076 /* global here is reset before drawing each bone */ 00077 static ThemeWireColor *bcolor= NULL; 00078 00079 /* values of colCode for set_pchan_glcolor */ 00080 enum { 00081 PCHAN_COLOR_NORMAL = 0, /* normal drawing */ 00082 PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */ 00083 PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */ 00084 00085 PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ 00086 PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ 00087 PCHAN_COLOR_LINEBONE /* for the middle of line-bones */ 00088 }; 00089 00090 /* This function sets the color-set for coloring a certain bone */ 00091 static void set_pchan_colorset (Object *ob, bPoseChannel *pchan) 00092 { 00093 bPose *pose= (ob) ? ob->pose : NULL; 00094 bArmature *arm= (ob) ? ob->data : NULL; 00095 bActionGroup *grp= NULL; 00096 short color_index= 0; 00097 00098 /* sanity check */ 00099 if (ELEM4(NULL, ob, arm, pose, pchan)) { 00100 bcolor= NULL; 00101 return; 00102 } 00103 00104 /* only try to set custom color if enabled for armature */ 00105 if (arm->flag & ARM_COL_CUSTOM) { 00106 /* currently, a bone can only use a custom color set if it's group (if it has one), 00107 * has been set to use one 00108 */ 00109 if (pchan->agrp_index) { 00110 grp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1)); 00111 if (grp) 00112 color_index= grp->customCol; 00113 } 00114 } 00115 00116 /* bcolor is a pointer to the color set to use. If NULL, then the default 00117 * color set (based on the theme colors for 3d-view) is used. 00118 */ 00119 if (color_index > 0) { 00120 bTheme *btheme= U.themes.first; 00121 bcolor= &btheme->tarm[(color_index - 1)]; 00122 } 00123 else if (color_index == -1) { 00124 /* use the group's own custom color set */ 00125 bcolor= (grp)? &grp->cs : NULL; 00126 } 00127 else 00128 bcolor= NULL; 00129 } 00130 00131 /* This function is for brightening/darkening a given color (like UI_ThemeColorShade()) */ 00132 static void cp_shade_color3ub (unsigned char cp[3], const int offset) 00133 { 00134 int r, g, b; 00135 00136 r= offset + (int) cp[0]; 00137 CLAMP(r, 0, 255); 00138 g= offset + (int) cp[1]; 00139 CLAMP(g, 0, 255); 00140 b= offset + (int) cp[2]; 00141 CLAMP(b, 0, 255); 00142 00143 cp[0]= r; 00144 cp[1]= g; 00145 cp[2]= b; 00146 } 00147 00148 /* This function sets the gl-color for coloring a certain bone (based on bcolor) */ 00149 static short set_pchan_glColor (short colCode, int boneflag, int constflag) 00150 { 00151 switch (colCode) { 00152 case PCHAN_COLOR_NORMAL: 00153 { 00154 if (bcolor) { 00155 unsigned char cp[3]; 00156 00157 if (boneflag & BONE_DRAW_ACTIVE) { 00158 VECCOPY(cp, bcolor->active); 00159 if(!(boneflag & BONE_SELECTED)) { 00160 cp_shade_color3ub(cp, -80); 00161 } 00162 } 00163 else if (boneflag & BONE_SELECTED) { 00164 VECCOPY(cp, bcolor->select); 00165 } 00166 else { 00167 /* a bit darker than solid */ 00168 VECCOPY(cp, bcolor->solid); 00169 cp_shade_color3ub(cp, -50); 00170 } 00171 00172 glColor3ubv(cp); 00173 } 00174 else { 00175 if (boneflag & BONE_DRAW_ACTIVE && boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, 40); 00176 else if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */ 00177 else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE); 00178 else UI_ThemeColor(TH_WIRE); 00179 } 00180 00181 return 1; 00182 } 00183 break; 00184 00185 case PCHAN_COLOR_SOLID: 00186 { 00187 if (bcolor) { 00188 glColor3ubv((unsigned char *)bcolor->solid); 00189 } 00190 else 00191 UI_ThemeColor(TH_BONE_SOLID); 00192 00193 return 1; 00194 } 00195 break; 00196 00197 case PCHAN_COLOR_CONSTS: 00198 { 00199 if ( (bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS) ) { 00200 if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80); 00201 else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80); 00202 else if (constflag & PCHAN_HAS_SPLINEIK) glColor4ub(200, 255, 0, 80); 00203 else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80); 00204 else if (constflag) UI_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION 00205 00206 return 1; 00207 } 00208 else 00209 return 0; 00210 } 00211 break; 00212 00213 case PCHAN_COLOR_SPHEREBONE_BASE: 00214 { 00215 if (bcolor) { 00216 unsigned char cp[3]; 00217 00218 if (boneflag & BONE_DRAW_ACTIVE) { 00219 VECCOPY(cp, bcolor->active); 00220 } 00221 else if (boneflag & BONE_SELECTED) { 00222 VECCOPY(cp, bcolor->select); 00223 } 00224 else { 00225 VECCOPY(cp, bcolor->solid); 00226 } 00227 00228 glColor3ubv(cp); 00229 } 00230 else { 00231 if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40); 00232 else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE); 00233 else UI_ThemeColor(TH_BONE_SOLID); 00234 } 00235 00236 return 1; 00237 } 00238 break; 00239 case PCHAN_COLOR_SPHEREBONE_END: 00240 { 00241 if (bcolor) { 00242 unsigned char cp[3]; 00243 00244 if (boneflag & BONE_DRAW_ACTIVE) { 00245 VECCOPY(cp, bcolor->active); 00246 cp_shade_color3ub(cp, 10); 00247 } 00248 else if (boneflag & BONE_SELECTED) { 00249 VECCOPY(cp, bcolor->select); 00250 cp_shade_color3ub(cp, -30); 00251 } 00252 else { 00253 VECCOPY(cp, bcolor->solid); 00254 cp_shade_color3ub(cp, -30); 00255 } 00256 00257 glColor3ubv(cp); 00258 } 00259 else { 00260 if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10); 00261 else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30); 00262 else UI_ThemeColorShade(TH_BONE_SOLID, -30); 00263 } 00264 } 00265 break; 00266 00267 case PCHAN_COLOR_LINEBONE: 00268 { 00269 /* inner part in background color or constraint */ 00270 if ( (constflag) && ((bcolor==NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) ) { 00271 if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0); 00272 else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0); 00273 else if (constflag & PCHAN_HAS_SPLINEIK) glColor3ub(200, 255, 0); 00274 else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120); 00275 else if (constflag) UI_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */ 00276 } 00277 else { 00278 if (bcolor) { 00279 char *cp= bcolor->solid; 00280 glColor4ub(cp[0], cp[1], cp[2], 204); 00281 } 00282 else 00283 UI_ThemeColorShade(TH_BACK, -30); 00284 } 00285 00286 return 1; 00287 } 00288 break; 00289 } 00290 00291 return 0; 00292 } 00293 00294 static void set_ebone_glColor(const unsigned int boneflag) 00295 { 00296 if (boneflag & BONE_DRAW_ACTIVE && boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT); 00297 else if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, 0.15f); /* unselected active */ 00298 else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20); 00299 else UI_ThemeColor(TH_WIRE); 00300 } 00301 00302 /* *************** Armature drawing, helper calls for parts ******************* */ 00303 00304 /* half the cube, in Y */ 00305 static float cube[8][3] = { 00306 {-1.0, 0.0, -1.0}, 00307 {-1.0, 0.0, 1.0}, 00308 {-1.0, 1.0, 1.0}, 00309 {-1.0, 1.0, -1.0}, 00310 { 1.0, 0.0, -1.0}, 00311 { 1.0, 0.0, 1.0}, 00312 { 1.0, 1.0, 1.0}, 00313 { 1.0, 1.0, -1.0}, 00314 }; 00315 00316 static void drawsolidcube_size(float xsize, float ysize, float zsize) 00317 { 00318 static GLuint displist=0; 00319 float n[3]; 00320 00321 glScalef(xsize, ysize, zsize); 00322 00323 n[0]=0; n[1]=0; n[2]=0; 00324 00325 if(displist==0) { 00326 displist= glGenLists(1); 00327 glNewList(displist, GL_COMPILE); 00328 00329 glBegin(GL_QUADS); 00330 n[0]= -1.0; 00331 glNormal3fv(n); 00332 glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); 00333 n[0]=0; 00334 n[1]= -1.0; 00335 glNormal3fv(n); 00336 glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); 00337 n[1]=0; 00338 n[0]= 1.0; 00339 glNormal3fv(n); 00340 glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); 00341 n[0]=0; 00342 n[1]= 1.0; 00343 glNormal3fv(n); 00344 glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); 00345 n[1]=0; 00346 n[2]= 1.0; 00347 glNormal3fv(n); 00348 glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); 00349 n[2]=0; 00350 n[2]= -1.0; 00351 glNormal3fv(n); 00352 glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); 00353 glEnd(); 00354 00355 glEndList(); 00356 } 00357 00358 glCallList(displist); 00359 } 00360 00361 static void drawcube_size(float xsize, float ysize, float zsize) 00362 { 00363 static GLuint displist=0; 00364 00365 if(displist == 0) { 00366 displist= glGenLists(1); 00367 glNewList(displist, GL_COMPILE); 00368 00369 glBegin(GL_LINE_STRIP); 00370 glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]); 00371 glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]); 00372 glVertex3fv(cube[7]); glVertex3fv(cube[4]); 00373 glEnd(); 00374 00375 glBegin(GL_LINES); 00376 glVertex3fv(cube[1]); glVertex3fv(cube[5]); 00377 glVertex3fv(cube[2]); glVertex3fv(cube[6]); 00378 glVertex3fv(cube[3]); glVertex3fv(cube[7]); 00379 glEnd(); 00380 00381 glEndList(); 00382 } 00383 00384 glScalef(xsize, ysize, zsize); 00385 glCallList(displist); 00386 00387 } 00388 00389 00390 static void draw_bonevert(void) 00391 { 00392 static GLuint displist=0; 00393 00394 if (displist == 0) { 00395 GLUquadricObj *qobj; 00396 00397 displist= glGenLists(1); 00398 glNewList(displist, GL_COMPILE); 00399 00400 glPushMatrix(); 00401 00402 qobj = gluNewQuadric(); 00403 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 00404 gluDisk(qobj, 0.0, 0.05, 16, 1); 00405 00406 glRotatef(90, 0, 1, 0); 00407 gluDisk(qobj, 0.0, 0.05, 16, 1); 00408 00409 glRotatef(90, 1, 0, 0); 00410 gluDisk(qobj, 0.0, 0.05, 16, 1); 00411 00412 gluDeleteQuadric(qobj); 00413 00414 glPopMatrix(); 00415 glEndList(); 00416 } 00417 00418 glCallList(displist); 00419 } 00420 00421 static void draw_bonevert_solid(void) 00422 { 00423 static GLuint displist=0; 00424 00425 if (displist == 0) { 00426 GLUquadricObj *qobj; 00427 00428 displist= glGenLists(1); 00429 glNewList(displist, GL_COMPILE); 00430 00431 qobj = gluNewQuadric(); 00432 gluQuadricDrawStyle(qobj, GLU_FILL); 00433 glShadeModel(GL_SMOOTH); 00434 gluSphere(qobj, 0.05, 8, 5); 00435 glShadeModel(GL_FLAT); 00436 gluDeleteQuadric(qobj); 00437 00438 glEndList(); 00439 } 00440 00441 glCallList(displist); 00442 } 00443 00444 static void draw_bone_octahedral(void) 00445 { 00446 static GLuint displist=0; 00447 00448 if (displist == 0) { 00449 float vec[6][3]; 00450 00451 displist= glGenLists(1); 00452 glNewList(displist, GL_COMPILE); 00453 00454 vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; 00455 vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; 00456 00457 vec[1][0]= 0.1f; vec[1][2]= 0.1f; vec[1][1]= 0.1f; 00458 vec[2][0]= 0.1f; vec[2][2]= -0.1f; vec[2][1]= 0.1f; 00459 vec[3][0]= -0.1f; vec[3][2]= -0.1f; vec[3][1]= 0.1f; 00460 vec[4][0]= -0.1f; vec[4][2]= 0.1f; vec[4][1]= 0.1f; 00461 00462 /* Section 1, sides */ 00463 glBegin(GL_LINE_LOOP); 00464 glVertex3fv(vec[0]); 00465 glVertex3fv(vec[1]); 00466 glVertex3fv(vec[5]); 00467 glVertex3fv(vec[3]); 00468 glVertex3fv(vec[0]); 00469 glVertex3fv(vec[4]); 00470 glVertex3fv(vec[5]); 00471 glVertex3fv(vec[2]); 00472 glEnd(); 00473 00474 /* Section 1, square */ 00475 glBegin(GL_LINE_LOOP); 00476 glVertex3fv(vec[1]); 00477 glVertex3fv(vec[2]); 00478 glVertex3fv(vec[3]); 00479 glVertex3fv(vec[4]); 00480 glEnd(); 00481 00482 glEndList(); 00483 } 00484 00485 glCallList(displist); 00486 } 00487 00488 static void draw_bone_solid_octahedral(void) 00489 { 00490 static GLuint displist=0; 00491 00492 if (displist == 0) { 00493 float vec[6][3], nor[3]; 00494 00495 displist= glGenLists(1); 00496 glNewList(displist, GL_COMPILE); 00497 00498 vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; 00499 vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; 00500 00501 vec[1][0]= 0.1f; vec[1][2]= 0.1f; vec[1][1]= 0.1f; 00502 vec[2][0]= 0.1f; vec[2][2]= -0.1f; vec[2][1]= 0.1f; 00503 vec[3][0]= -0.1f; vec[3][2]= -0.1f; vec[3][1]= 0.1f; 00504 vec[4][0]= -0.1f; vec[4][2]= 0.1f; vec[4][1]= 0.1f; 00505 00506 00507 glBegin(GL_TRIANGLES); 00508 /* bottom */ 00509 normal_tri_v3( nor,vec[2], vec[1], vec[0]); 00510 glNormal3fv(nor); 00511 glVertex3fv(vec[2]); glVertex3fv(vec[1]); glVertex3fv(vec[0]); 00512 00513 normal_tri_v3( nor,vec[3], vec[2], vec[0]); 00514 glNormal3fv(nor); 00515 glVertex3fv(vec[3]); glVertex3fv(vec[2]); glVertex3fv(vec[0]); 00516 00517 normal_tri_v3( nor,vec[4], vec[3], vec[0]); 00518 glNormal3fv(nor); 00519 glVertex3fv(vec[4]); glVertex3fv(vec[3]); glVertex3fv(vec[0]); 00520 00521 normal_tri_v3( nor,vec[1], vec[4], vec[0]); 00522 glNormal3fv(nor); 00523 glVertex3fv(vec[1]); glVertex3fv(vec[4]); glVertex3fv(vec[0]); 00524 00525 /* top */ 00526 normal_tri_v3( nor,vec[5], vec[1], vec[2]); 00527 glNormal3fv(nor); 00528 glVertex3fv(vec[5]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); 00529 00530 normal_tri_v3( nor,vec[5], vec[2], vec[3]); 00531 glNormal3fv(nor); 00532 glVertex3fv(vec[5]); glVertex3fv(vec[2]); glVertex3fv(vec[3]); 00533 00534 normal_tri_v3( nor,vec[5], vec[3], vec[4]); 00535 glNormal3fv(nor); 00536 glVertex3fv(vec[5]); glVertex3fv(vec[3]); glVertex3fv(vec[4]); 00537 00538 normal_tri_v3( nor,vec[5], vec[4], vec[1]); 00539 glNormal3fv(nor); 00540 glVertex3fv(vec[5]); glVertex3fv(vec[4]); glVertex3fv(vec[1]); 00541 00542 glEnd(); 00543 00544 glEndList(); 00545 } 00546 00547 glCallList(displist); 00548 } 00549 00550 /* *************** Armature drawing, bones ******************* */ 00551 00552 00553 static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) 00554 { 00555 /* Draw root point if we are not connected */ 00556 if ((boneflag & BONE_CONNECTED)==0) { 00557 if (id != -1) 00558 glLoadName(id | BONESEL_ROOT); 00559 00560 if(dt <= OB_WIRE) { 00561 if (armflag & ARM_EDITMODE) { 00562 if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00563 else UI_ThemeColor(TH_VERTEX); 00564 } 00565 } 00566 else { 00567 if (armflag & ARM_POSEMODE) 00568 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0); 00569 else 00570 UI_ThemeColor(TH_BONE_SOLID); 00571 } 00572 00573 if (dt > OB_WIRE) 00574 draw_bonevert_solid(); 00575 else 00576 draw_bonevert(); 00577 } 00578 00579 /* Draw tip point */ 00580 if (id != -1) 00581 glLoadName(id | BONESEL_TIP); 00582 00583 if (dt <= OB_WIRE) { 00584 if (armflag & ARM_EDITMODE) { 00585 if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00586 else UI_ThemeColor(TH_VERTEX); 00587 } 00588 } 00589 else { 00590 if (armflag & ARM_POSEMODE) 00591 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0); 00592 else 00593 UI_ThemeColor(TH_BONE_SOLID); 00594 } 00595 00596 glTranslatef(0.0f, 1.0f, 0.0f); 00597 if (dt > OB_WIRE) 00598 draw_bonevert_solid(); 00599 else 00600 draw_bonevert(); 00601 glTranslatef(0.0f, -1.0f, 0.0f); 00602 00603 } 00604 00605 /* 16 values of sin function (still same result!) */ 00606 static float si[16] = { 00607 0.00000000f, 00608 0.20129852f, 0.39435585f, 00609 0.57126821f, 0.72479278f, 00610 0.84864425f, 0.93775213f, 00611 0.98846832f, 0.99871650f, 00612 0.96807711f, 0.89780453f, 00613 0.79077573f, 0.65137248f, 00614 0.48530196f, 0.29936312f, 00615 0.10116832f 00616 }; 00617 /* 16 values of cos function (still same result!) */ 00618 static float co[16] ={ 00619 1.00000000f, 00620 0.97952994f, 0.91895781f, 00621 0.82076344f, 0.68896691f, 00622 0.52896401f, 0.34730525f, 00623 0.15142777f, -0.05064916f, 00624 -0.25065253f, -0.44039415f, 00625 -0.61210598f, -0.75875812f, 00626 -0.87434661f, -0.95413925f, 00627 -0.99486932f 00628 }; 00629 00630 00631 00632 /* smat, imat = mat & imat to draw screenaligned */ 00633 static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone) 00634 { 00635 float head, tail, dist /*, length*/; 00636 float *headvec, *tailvec, dirvec[3]; 00637 00638 /* figure out the sizes of spheres */ 00639 if (ebone) { 00640 /* this routine doesn't call get_matrix_editbone() that calculates it */ 00641 ebone->length = len_v3v3(ebone->head, ebone->tail); 00642 00643 /*length= ebone->length;*/ /*UNUSED*/ 00644 tail= ebone->rad_tail; 00645 dist= ebone->dist; 00646 if (ebone->parent && (ebone->flag & BONE_CONNECTED)) 00647 head= ebone->parent->rad_tail; 00648 else 00649 head= ebone->rad_head; 00650 headvec= ebone->head; 00651 tailvec= ebone->tail; 00652 } 00653 else { 00654 /*length= pchan->bone->length;*/ /*UNUSED*/ 00655 tail= pchan->bone->rad_tail; 00656 dist= pchan->bone->dist; 00657 if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) 00658 head= pchan->parent->bone->rad_tail; 00659 else 00660 head= pchan->bone->rad_head; 00661 headvec= pchan->pose_head; 00662 tailvec= pchan->pose_tail; 00663 } 00664 00665 /* ***** draw it ***** */ 00666 00667 /* move vector to viewspace */ 00668 sub_v3_v3v3(dirvec, tailvec, headvec); 00669 mul_mat3_m4_v3(smat, dirvec); 00670 /* clear zcomp */ 00671 dirvec[2]= 0.0f; 00672 00673 if(head != tail) { 00674 /* correcyion when viewing along the bones axis 00675 * it pops in and out but better then artifacts, [#23841] */ 00676 float view_dist= len_v2(dirvec); 00677 00678 if(head - view_dist > tail) { 00679 tailvec= headvec; 00680 tail = head; 00681 zero_v3(dirvec); 00682 dirvec[0]= 0.00001; // XXX. weak but ok 00683 } 00684 else if(tail - view_dist > head) { 00685 headvec= tailvec; 00686 head = tail; 00687 zero_v3(dirvec); 00688 dirvec[0]= 0.00001; // XXX. weak but ok 00689 } 00690 } 00691 00692 /* move vector back */ 00693 mul_mat3_m4_v3(imat, dirvec); 00694 00695 if (0.0f != normalize_v3(dirvec)) { 00696 float norvec[3], vec1[3], vec2[3], vec[3]; 00697 int a; 00698 00699 //mul_v3_fl(dirvec, head); 00700 cross_v3_v3v3(norvec, dirvec, imat[2]); 00701 00702 glBegin(GL_QUAD_STRIP); 00703 00704 for (a=0; a<16; a++) { 00705 vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0]; 00706 vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1]; 00707 vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2]; 00708 00709 vec1[0]= headvec[0] + head*vec[0]; 00710 vec1[1]= headvec[1] + head*vec[1]; 00711 vec1[2]= headvec[2] + head*vec[2]; 00712 vec2[0]= headvec[0] + (head+dist)*vec[0]; 00713 vec2[1]= headvec[1] + (head+dist)*vec[1]; 00714 vec2[2]= headvec[2] + (head+dist)*vec[2]; 00715 00716 glColor4ub(255, 255, 255, 50); 00717 glVertex3fv(vec1); 00718 //glColor4ub(255, 255, 255, 0); 00719 glVertex3fv(vec2); 00720 } 00721 00722 for (a=15; a>=0; a--) { 00723 vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0]; 00724 vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1]; 00725 vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2]; 00726 00727 vec1[0]= tailvec[0] + tail*vec[0]; 00728 vec1[1]= tailvec[1] + tail*vec[1]; 00729 vec1[2]= tailvec[2] + tail*vec[2]; 00730 vec2[0]= tailvec[0] + (tail+dist)*vec[0]; 00731 vec2[1]= tailvec[1] + (tail+dist)*vec[1]; 00732 vec2[2]= tailvec[2] + (tail+dist)*vec[2]; 00733 00734 //glColor4ub(255, 255, 255, 50); 00735 glVertex3fv(vec1); 00736 //glColor4ub(255, 255, 255, 0); 00737 glVertex3fv(vec2); 00738 } 00739 /* make it cyclic... */ 00740 00741 vec[0]= - *(si) * dirvec[0] + *(co) * norvec[0]; 00742 vec[1]= - *(si) * dirvec[1] + *(co) * norvec[1]; 00743 vec[2]= - *(si) * dirvec[2] + *(co) * norvec[2]; 00744 00745 vec1[0]= headvec[0] + head*vec[0]; 00746 vec1[1]= headvec[1] + head*vec[1]; 00747 vec1[2]= headvec[2] + head*vec[2]; 00748 vec2[0]= headvec[0] + (head+dist)*vec[0]; 00749 vec2[1]= headvec[1] + (head+dist)*vec[1]; 00750 vec2[2]= headvec[2] + (head+dist)*vec[2]; 00751 00752 //glColor4ub(255, 255, 255, 50); 00753 glVertex3fv(vec1); 00754 //glColor4ub(255, 255, 255, 0); 00755 glVertex3fv(vec2); 00756 00757 glEnd(); 00758 } 00759 } 00760 00761 00762 /* smat, imat = mat & imat to draw screenaligned */ 00763 static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) 00764 { 00765 float head, tail /*, length*/; 00766 float *headvec, *tailvec, dirvec[3]; 00767 00768 /* figure out the sizes of spheres */ 00769 if (ebone) { 00770 /* this routine doesn't call get_matrix_editbone() that calculates it */ 00771 ebone->length = len_v3v3(ebone->head, ebone->tail); 00772 00773 /*length= ebone->length;*/ /*UNUSED*/ 00774 tail= ebone->rad_tail; 00775 if (ebone->parent && (boneflag & BONE_CONNECTED)) 00776 head= ebone->parent->rad_tail; 00777 else 00778 head= ebone->rad_head; 00779 headvec= ebone->head; 00780 tailvec= ebone->tail; 00781 } 00782 else { 00783 /*length= pchan->bone->length;*/ /*UNUSED*/ 00784 tail= pchan->bone->rad_tail; 00785 if ((pchan->parent) && (boneflag & BONE_CONNECTED)) 00786 head= pchan->parent->bone->rad_tail; 00787 else 00788 head= pchan->bone->rad_head; 00789 headvec= pchan->pose_head; 00790 tailvec= pchan->pose_tail; 00791 } 00792 00793 /* sphere root color */ 00794 if (armflag & ARM_EDITMODE) { 00795 if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00796 else UI_ThemeColor(TH_VERTEX); 00797 } 00798 else if (armflag & ARM_POSEMODE) 00799 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 00800 00801 /* Draw root point if we are not connected */ 00802 if ((boneflag & BONE_CONNECTED)==0) { 00803 if (id != -1) 00804 glLoadName(id | BONESEL_ROOT); 00805 00806 drawcircball(GL_LINE_LOOP, headvec, head, imat); 00807 } 00808 00809 /* Draw tip point */ 00810 if (armflag & ARM_EDITMODE) { 00811 if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00812 else UI_ThemeColor(TH_VERTEX); 00813 } 00814 00815 if (id != -1) 00816 glLoadName(id | BONESEL_TIP); 00817 00818 drawcircball(GL_LINE_LOOP, tailvec, tail, imat); 00819 00820 /* base */ 00821 if (armflag & ARM_EDITMODE) { 00822 if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT); 00823 else UI_ThemeColor(TH_WIRE); 00824 } 00825 00826 sub_v3_v3v3(dirvec, tailvec, headvec); 00827 00828 /* move vector to viewspace */ 00829 mul_mat3_m4_v3(smat, dirvec); 00830 /* clear zcomp */ 00831 dirvec[2]= 0.0f; 00832 /* move vector back */ 00833 mul_mat3_m4_v3(imat, dirvec); 00834 00835 if (0.0f != normalize_v3(dirvec)) { 00836 float norvech[3], norvect[3], vec[3]; 00837 00838 VECCOPY(vec, dirvec); 00839 00840 mul_v3_fl(dirvec, head); 00841 cross_v3_v3v3(norvech, dirvec, imat[2]); 00842 00843 mul_v3_fl(vec, tail); 00844 cross_v3_v3v3(norvect, vec, imat[2]); 00845 00846 if (id != -1) 00847 glLoadName(id | BONESEL_BONE); 00848 00849 glBegin(GL_LINES); 00850 vec[0]= headvec[0] + norvech[0]; 00851 vec[1]= headvec[1] + norvech[1]; 00852 vec[2]= headvec[2] + norvech[2]; 00853 glVertex3fv(vec); 00854 vec[0]= tailvec[0] + norvect[0]; 00855 vec[1]= tailvec[1] + norvect[1]; 00856 vec[2]= tailvec[2] + norvect[2]; 00857 glVertex3fv(vec); 00858 vec[0]= headvec[0] - norvech[0]; 00859 vec[1]= headvec[1] - norvech[1]; 00860 vec[2]= headvec[2] - norvech[2]; 00861 glVertex3fv(vec); 00862 vec[0]= tailvec[0] - norvect[0]; 00863 vec[1]= tailvec[1] - norvect[1]; 00864 vec[2]= tailvec[2] - norvect[2]; 00865 glVertex3fv(vec); 00866 00867 glEnd(); 00868 } 00869 } 00870 00871 /* does wire only for outline selecting */ 00872 static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) 00873 { 00874 GLUquadricObj *qobj; 00875 float head, tail, length; 00876 float fac1, fac2; 00877 00878 glPushMatrix(); 00879 qobj = gluNewQuadric(); 00880 00881 /* figure out the sizes of spheres */ 00882 if (ebone) { 00883 length= ebone->length; 00884 tail= ebone->rad_tail; 00885 if (ebone->parent && (boneflag & BONE_CONNECTED)) 00886 head= ebone->parent->rad_tail; 00887 else 00888 head= ebone->rad_head; 00889 } 00890 else { 00891 length= pchan->bone->length; 00892 tail= pchan->bone->rad_tail; 00893 if (pchan->parent && (boneflag & BONE_CONNECTED)) 00894 head= pchan->parent->bone->rad_tail; 00895 else 00896 head= pchan->bone->rad_head; 00897 } 00898 00899 /* move to z-axis space */ 00900 glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); 00901 00902 if (dt==OB_SOLID) { 00903 /* set up solid drawing */ 00904 glEnable(GL_COLOR_MATERIAL); 00905 glEnable(GL_LIGHTING); 00906 00907 gluQuadricDrawStyle(qobj, GLU_FILL); 00908 glShadeModel(GL_SMOOTH); 00909 } 00910 else { 00911 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 00912 } 00913 00914 /* sphere root color */ 00915 if (armflag & ARM_EDITMODE) { 00916 if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00917 else UI_ThemeColorShade(TH_BONE_SOLID, -30); 00918 } 00919 else if (armflag & ARM_POSEMODE) 00920 set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag); 00921 else if (dt==OB_SOLID) 00922 UI_ThemeColorShade(TH_BONE_SOLID, -30); 00923 00924 /* Draw root point if we are not connected */ 00925 if ((boneflag & BONE_CONNECTED)==0) { 00926 if (id != -1) 00927 glLoadName(id | BONESEL_ROOT); 00928 gluSphere(qobj, head, 16, 10); 00929 } 00930 00931 /* Draw tip point */ 00932 if (armflag & ARM_EDITMODE) { 00933 if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT); 00934 else UI_ThemeColorShade(TH_BONE_SOLID, -30); 00935 } 00936 00937 if (id != -1) 00938 glLoadName(id | BONESEL_TIP); 00939 00940 glTranslatef(0.0f, 0.0f, length); 00941 gluSphere(qobj, tail, 16, 10); 00942 glTranslatef(0.0f, 0.0f, -length); 00943 00944 /* base */ 00945 if (armflag & ARM_EDITMODE) { 00946 if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT); 00947 else UI_ThemeColor(TH_BONE_SOLID); 00948 } 00949 else if (armflag & ARM_POSEMODE) 00950 set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag); 00951 else if (dt == OB_SOLID) 00952 UI_ThemeColor(TH_BONE_SOLID); 00953 00954 fac1= (length-head)/length; 00955 fac2= (length-tail)/length; 00956 00957 if (length > (head+tail)) { 00958 if (id != -1) 00959 glLoadName (id | BONESEL_BONE); 00960 00961 glEnable(GL_POLYGON_OFFSET_FILL); 00962 glPolygonOffset(-1.0f, -1.0f); 00963 00964 glTranslatef(0.0f, 0.0f, head); 00965 gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1); 00966 glTranslatef(0.0f, 0.0f, -head); 00967 00968 glDisable(GL_POLYGON_OFFSET_FILL); 00969 00970 /* draw sphere on extrema */ 00971 glTranslatef(0.0f, 0.0f, length-tail); 00972 gluSphere(qobj, fac2*tail + (1.0f-fac2)*head, 16, 10); 00973 glTranslatef(0.0f, 0.0f, -length+tail); 00974 00975 glTranslatef(0.0f, 0.0f, head); 00976 gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10); 00977 } 00978 else { 00979 /* 1 sphere in center */ 00980 glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0f); 00981 gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10); 00982 } 00983 00984 /* restore */ 00985 if (dt==OB_SOLID) { 00986 glShadeModel(GL_FLAT); 00987 glDisable(GL_LIGHTING); 00988 glDisable(GL_COLOR_MATERIAL); 00989 } 00990 00991 glPopMatrix(); 00992 gluDeleteQuadric(qobj); 00993 } 00994 00995 static GLubyte bm_dot6[]= {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0}; 00996 static GLubyte bm_dot8[]= {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C}; 00997 00998 static GLubyte bm_dot5[]= {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0}; 00999 static GLubyte bm_dot7[]= {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38}; 01000 01001 01002 static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) 01003 { 01004 float length; 01005 01006 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 01007 01008 if (pchan) 01009 length= pchan->bone->length; 01010 else 01011 length= ebone->length; 01012 01013 glPushMatrix(); 01014 glScalef(length, length, length); 01015 01016 /* this chunk not in object mode */ 01017 if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) { 01018 glLineWidth(4.0f); 01019 if (armflag & ARM_POSEMODE) 01020 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 01021 else if (armflag & ARM_EDITMODE) { 01022 UI_ThemeColor(TH_WIRE); 01023 } 01024 01025 /* Draw root point if we are not connected */ 01026 if ((boneflag & BONE_CONNECTED)==0) { 01027 if (G.f & G_PICKSEL) { // no bitmap in selection mode, crashes 3d cards... 01028 glLoadName (id | BONESEL_ROOT); 01029 glBegin(GL_POINTS); 01030 glVertex3f(0.0f, 0.0f, 0.0f); 01031 glEnd(); 01032 } 01033 else { 01034 glRasterPos3f(0.0f, 0.0f, 0.0f); 01035 glBitmap(8, 8, 4, 4, 0, 0, bm_dot8); 01036 } 01037 } 01038 01039 if (id != -1) 01040 glLoadName((GLuint) id|BONESEL_BONE); 01041 01042 glBegin(GL_LINES); 01043 glVertex3f(0.0f, 0.0f, 0.0f); 01044 glVertex3f(0.0f, 1.0f, 0.0f); 01045 glEnd(); 01046 01047 /* tip */ 01048 if (G.f & G_PICKSEL) { 01049 /* no bitmap in selection mode, crashes 3d cards... */ 01050 glLoadName(id | BONESEL_TIP); 01051 glBegin(GL_POINTS); 01052 glVertex3f(0.0f, 1.0f, 0.0f); 01053 glEnd(); 01054 } 01055 else { 01056 glRasterPos3f(0.0f, 1.0f, 0.0f); 01057 glBitmap(8, 8, 4, 4, 0, 0, bm_dot7); 01058 } 01059 01060 /* further we send no names */ 01061 if (id != -1) 01062 glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */ 01063 01064 if (armflag & ARM_POSEMODE) 01065 set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag); 01066 } 01067 01068 glLineWidth(2.0); 01069 01070 /*Draw root point if we are not connected */ 01071 if ((boneflag & BONE_CONNECTED)==0) { 01072 if ((G.f & G_PICKSEL)==0) { 01073 /* no bitmap in selection mode, crashes 3d cards... */ 01074 if (armflag & ARM_EDITMODE) { 01075 if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT); 01076 else UI_ThemeColor(TH_VERTEX); 01077 } 01078 glRasterPos3f(0.0f, 0.0f, 0.0f); 01079 glBitmap(8, 8, 4, 4, 0, 0, bm_dot6); 01080 } 01081 } 01082 01083 if (armflag & ARM_EDITMODE) { 01084 if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT); 01085 else UI_ThemeColorShade(TH_BACK, -30); 01086 } 01087 glBegin(GL_LINES); 01088 glVertex3f(0.0f, 0.0f, 0.0f); 01089 glVertex3f(0.0f, 1.0f, 0.0f); 01090 glEnd(); 01091 01092 /* tip */ 01093 if ((G.f & G_PICKSEL)==0) { 01094 /* no bitmap in selection mode, crashes 3d cards... */ 01095 if (armflag & ARM_EDITMODE) { 01096 if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT); 01097 else UI_ThemeColor(TH_VERTEX); 01098 } 01099 glRasterPos3f(0.0f, 1.0f, 0.0f); 01100 glBitmap(8, 8, 4, 4, 0, 0, bm_dot5); 01101 } 01102 01103 glLineWidth(1.0); 01104 01105 glPopMatrix(); 01106 } 01107 01108 static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) 01109 { 01110 int segments= 0; 01111 01112 if (pchan) 01113 segments= pchan->bone->segments; 01114 01115 if ((segments > 1) && (pchan)) { 01116 float dlen= length/(float)segments; 01117 Mat4 *bbone= b_bone_spline_setup(pchan, 0); 01118 int a; 01119 01120 for (a=0; a<segments; a++, bbone++) { 01121 glPushMatrix(); 01122 glMultMatrixf(bbone->mat); 01123 if (dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth); 01124 else drawcube_size(xwidth, dlen, zwidth); 01125 glPopMatrix(); 01126 } 01127 } 01128 else { 01129 glPushMatrix(); 01130 if (dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth); 01131 else drawcube_size(xwidth, length, zwidth); 01132 glPopMatrix(); 01133 } 01134 } 01135 01136 static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) 01137 { 01138 float xwidth, length, zwidth; 01139 01140 if (pchan) { 01141 xwidth= pchan->bone->xwidth; 01142 length= pchan->bone->length; 01143 zwidth= pchan->bone->zwidth; 01144 } 01145 else { 01146 xwidth= ebone->xwidth; 01147 length= ebone->length; 01148 zwidth= ebone->zwidth; 01149 } 01150 01151 /* draw points only if... */ 01152 if (armflag & ARM_EDITMODE) { 01153 /* move to unitspace */ 01154 glPushMatrix(); 01155 glScalef(length, length, length); 01156 draw_bone_points(dt, armflag, boneflag, id); 01157 glPopMatrix(); 01158 length*= 0.95f; // make vertices visible 01159 } 01160 01161 /* colors for modes */ 01162 if (armflag & ARM_POSEMODE) { 01163 if (dt <= OB_WIRE) 01164 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 01165 else 01166 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); 01167 } 01168 else if (armflag & ARM_EDITMODE) { 01169 if (dt==OB_WIRE) { 01170 set_ebone_glColor(boneflag); 01171 } 01172 else 01173 UI_ThemeColor(TH_BONE_SOLID); 01174 } 01175 01176 if (id != -1) { 01177 glLoadName ((GLuint) id|BONESEL_BONE); 01178 } 01179 01180 /* set up solid drawing */ 01181 if (dt > OB_WIRE) { 01182 glEnable(GL_COLOR_MATERIAL); 01183 glEnable(GL_LIGHTING); 01184 01185 if (armflag & ARM_POSEMODE) 01186 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); 01187 else 01188 UI_ThemeColor(TH_BONE_SOLID); 01189 01190 draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth); 01191 01192 /* disable solid drawing */ 01193 glDisable(GL_COLOR_MATERIAL); 01194 glDisable(GL_LIGHTING); 01195 } 01196 else { 01197 /* wire */ 01198 if (armflag & ARM_POSEMODE) { 01199 if (constflag) { 01200 /* set constraint colors */ 01201 if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) { 01202 glEnable(GL_BLEND); 01203 01204 draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth); 01205 01206 glDisable(GL_BLEND); 01207 } 01208 01209 /* restore colors */ 01210 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 01211 } 01212 } 01213 01214 draw_b_bone_boxes(OB_WIRE, pchan, xwidth, length, zwidth); 01215 } 01216 } 01217 01218 static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length) 01219 { 01220 01221 /* Draw a 3d octahedral bone, we use normalized space based on length, 01222 for glDisplayLists */ 01223 01224 glScalef(length, length, length); 01225 01226 /* set up solid drawing */ 01227 if (dt > OB_WIRE) { 01228 glEnable(GL_COLOR_MATERIAL); 01229 glEnable(GL_LIGHTING); 01230 UI_ThemeColor(TH_BONE_SOLID); 01231 } 01232 01233 /* colors for posemode */ 01234 if (armflag & ARM_POSEMODE) { 01235 if (dt <= OB_WIRE) 01236 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 01237 else 01238 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); 01239 } 01240 01241 01242 draw_bone_points(dt, armflag, boneflag, id); 01243 01244 /* now draw the bone itself */ 01245 if (id != -1) { 01246 glLoadName((GLuint) id|BONESEL_BONE); 01247 } 01248 01249 /* wire? */ 01250 if (dt <= OB_WIRE) { 01251 /* colors */ 01252 if (armflag & ARM_EDITMODE) { 01253 set_ebone_glColor(boneflag); 01254 } 01255 else if (armflag & ARM_POSEMODE) { 01256 if (constflag) { 01257 /* draw constraint colors */ 01258 if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) { 01259 glEnable(GL_BLEND); 01260 01261 draw_bone_solid_octahedral(); 01262 01263 glDisable(GL_BLEND); 01264 } 01265 01266 /* restore colors */ 01267 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag); 01268 } 01269 } 01270 draw_bone_octahedral(); 01271 } 01272 else { 01273 /* solid */ 01274 if (armflag & ARM_POSEMODE) 01275 set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag); 01276 else 01277 UI_ThemeColor(TH_BONE_SOLID); 01278 draw_bone_solid_octahedral(); 01279 } 01280 01281 /* disable solid drawing */ 01282 if (dt > OB_WIRE) { 01283 glDisable(GL_COLOR_MATERIAL); 01284 glDisable(GL_LIGHTING); 01285 } 01286 } 01287 01288 static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length) 01289 { 01290 if(ob==NULL) return; 01291 01292 glScalef(length, length, length); 01293 01294 /* colors for posemode */ 01295 if (armflag & ARM_POSEMODE) { 01296 set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, 0); 01297 } 01298 01299 if (id != -1) { 01300 glLoadName((GLuint) id|BONESEL_BONE); 01301 } 01302 01303 draw_object_instance(scene, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE); 01304 } 01305 01306 01307 static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) 01308 { 01309 bConstraint *con; 01310 bPoseChannel *parchan; 01311 01312 for (con= pchan->constraints.first; con; con= con->next) { 01313 if (con->enforce == 0.0f) 01314 continue; 01315 01316 switch (con->type) { 01317 case CONSTRAINT_TYPE_KINEMATIC: 01318 { 01319 bKinematicConstraint *data = (bKinematicConstraint*)con->data; 01320 int segcount= 0; 01321 01322 /* if only_temp, only draw if it is a temporary ik-chain */ 01323 if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP)) 01324 continue; 01325 01326 setlinestyle(3); 01327 glBegin(GL_LINES); 01328 01329 /* exclude tip from chain? */ 01330 if ((data->flag & CONSTRAINT_IK_TIP)==0) 01331 parchan= pchan->parent; 01332 else 01333 parchan= pchan; 01334 01335 glVertex3fv(parchan->pose_tail); 01336 01337 /* Find the chain's root */ 01338 while (parchan->parent) { 01339 segcount++; 01340 if(segcount==data->rootbone || segcount>255) break; // 255 is weak 01341 parchan= parchan->parent; 01342 } 01343 if (parchan) 01344 glVertex3fv(parchan->pose_head); 01345 01346 glEnd(); 01347 setlinestyle(0); 01348 } 01349 break; 01350 case CONSTRAINT_TYPE_SPLINEIK: 01351 { 01352 bSplineIKConstraint *data = (bSplineIKConstraint*)con->data; 01353 int segcount= 0; 01354 01355 setlinestyle(3); 01356 glBegin(GL_LINES); 01357 01358 parchan= pchan; 01359 glVertex3fv(parchan->pose_tail); 01360 01361 /* Find the chain's root */ 01362 while (parchan->parent) { 01363 segcount++; 01364 // FIXME: revise the breaking conditions 01365 if(segcount==data->chainlen || segcount>255) break; // 255 is weak 01366 parchan= parchan->parent; 01367 } 01368 if (parchan) // XXX revise the breaking conditions to only stop at the tail? 01369 glVertex3fv(parchan->pose_head); 01370 01371 glEnd(); 01372 setlinestyle(0); 01373 } 01374 break; 01375 } 01376 } 01377 } 01378 01379 static void bgl_sphere_project(float ax, float az) 01380 { 01381 float dir[3], sine, q3; 01382 01383 sine= 1.0f - ax*ax - az*az; 01384 q3= (sine < 0.0f)? 0.0f: (float)(2.0*sqrt(sine)); 01385 01386 dir[0]= -az*q3; 01387 dir[1]= 1.0f - 2.0f*sine; 01388 dir[2]= ax*q3; 01389 01390 glVertex3fv(dir); 01391 } 01392 01393 static void draw_dof_ellipse(float ax, float az) 01394 { 01395 static float staticSine[16] = { 01396 0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f, 01397 0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f, 01398 0.743144825477f, 0.809016994375f, 0.866025403784f, 01399 0.913545457643f, 0.951056516295f, 0.978147600734f, 01400 0.994521895368f, 1.0f 01401 }; 01402 01403 int i, j, n=16; 01404 float x, z, px, pz; 01405 01406 glEnable(GL_BLEND); 01407 glDepthMask(0); 01408 01409 glColor4ub(70, 70, 70, 50); 01410 01411 glBegin(GL_QUADS); 01412 pz= 0.0f; 01413 for(i=1; i<n; i++) { 01414 z= staticSine[i]; 01415 01416 px= 0.0f; 01417 for(j=1; j<n-i+1; j++) { 01418 x = staticSine[j]; 01419 01420 if(j == n-i) { 01421 glEnd(); 01422 glBegin(GL_TRIANGLES); 01423 bgl_sphere_project(ax*px, az*z); 01424 bgl_sphere_project(ax*px, az*pz); 01425 bgl_sphere_project(ax*x, az*pz); 01426 glEnd(); 01427 glBegin(GL_QUADS); 01428 } 01429 else { 01430 bgl_sphere_project(ax*x, az*z); 01431 bgl_sphere_project(ax*x, az*pz); 01432 bgl_sphere_project(ax*px, az*pz); 01433 bgl_sphere_project(ax*px, az*z); 01434 } 01435 01436 px= x; 01437 } 01438 pz= z; 01439 } 01440 glEnd(); 01441 01442 glDisable(GL_BLEND); 01443 glDepthMask(1); 01444 01445 glColor3ub(0, 0, 0); 01446 01447 glBegin(GL_LINE_STRIP); 01448 for (i=0; i<n; i++) 01449 bgl_sphere_project(staticSine[n-i-1]*ax, staticSine[i]*az); 01450 glEnd(); 01451 } 01452 01453 static void draw_pose_dofs(Object *ob) 01454 { 01455 bArmature *arm= ob->data; 01456 bPoseChannel *pchan; 01457 Bone *bone; 01458 01459 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01460 bone= pchan->bone; 01461 01462 if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { 01463 if (bone->flag & BONE_SELECTED) { 01464 if (bone->layer & arm->layer) { 01465 if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) { 01466 if (ED_pose_channel_in_IK_chain(ob, pchan)) { 01467 float corner[4][3], posetrans[3], mat[4][4]; 01468 float phi=0.0f, theta=0.0f, scale; 01469 int a, i; 01470 01471 /* in parent-bone pose, but own restspace */ 01472 glPushMatrix(); 01473 01474 VECCOPY(posetrans, pchan->pose_mat[3]); 01475 glTranslatef(posetrans[0], posetrans[1], posetrans[2]); 01476 01477 if (pchan->parent) { 01478 copy_m4_m4(mat, pchan->parent->pose_mat); 01479 mat[3][0]= mat[3][1]= mat[3][2]= 0.0f; 01480 glMultMatrixf(mat); 01481 } 01482 01483 copy_m4_m3(mat, pchan->bone->bone_mat); 01484 glMultMatrixf(mat); 01485 01486 scale= bone->length*pchan->size[1]; 01487 glScalef(scale, scale, scale); 01488 01489 if (pchan->ikflag & BONE_IK_XLIMIT) { 01490 if (pchan->ikflag & BONE_IK_ZLIMIT) { 01491 float amin[3], amax[3]; 01492 01493 for (i=0; i<3; i++) { 01494 /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ 01495 amin[i]= (float)sin(pchan->limitmin[i]*0.5f); 01496 amax[i]= (float)sin(pchan->limitmax[i]*0.5f); 01497 } 01498 01499 glScalef(1.0f, -1.0f, 1.0f); 01500 if ((amin[0] != 0.0f) && (amin[2] != 0.0f)) 01501 draw_dof_ellipse(amin[0], amin[2]); 01502 if ((amin[0] != 0.0f) && (amax[2] != 0.0f)) 01503 draw_dof_ellipse(amin[0], amax[2]); 01504 if ((amax[0] != 0.0f) && (amin[2] != 0.0f)) 01505 draw_dof_ellipse(amax[0], amin[2]); 01506 if ((amax[0] != 0.0f) && (amax[2] != 0.0f)) 01507 draw_dof_ellipse(amax[0], amax[2]); 01508 glScalef(1.0f, -1.0f, 1.0f); 01509 } 01510 } 01511 01512 /* arcs */ 01513 if (pchan->ikflag & BONE_IK_ZLIMIT) { 01514 /* OpenGL requires rotations in degrees; so we're taking the average angle here */ 01515 theta= RAD2DEGF(0.5f * (pchan->limitmin[2]+pchan->limitmax[2])); 01516 glRotatef(theta, 0.0f, 0.0f, 1.0f); 01517 01518 glColor3ub(50, 50, 255); // blue, Z axis limit 01519 glBegin(GL_LINE_STRIP); 01520 for (a=-16; a<=16; a++) { 01521 float fac= ((float)a)/16.0f * 0.5f; /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ 01522 01523 phi= fac * (pchan->limitmax[2] - pchan->limitmin[2]); 01524 01525 i= (a == -16) ? 0 : 1; 01526 corner[i][0]= (float)sin(phi); 01527 corner[i][1]= (float)cos(phi); 01528 corner[i][2]= 0.0f; 01529 glVertex3fv(corner[i]); 01530 } 01531 glEnd(); 01532 01533 glRotatef(-theta, 0.0f, 0.0f, 1.0f); 01534 } 01535 01536 if (pchan->ikflag & BONE_IK_XLIMIT) { 01537 /* OpenGL requires rotations in degrees; so we're taking the average angle here */ 01538 theta= RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0])); 01539 glRotatef(theta, 1.0f, 0.0f, 0.0f); 01540 01541 glColor3ub(255, 50, 50); // Red, X axis limit 01542 glBegin(GL_LINE_STRIP); 01543 for (a=-16; a<=16; a++) { 01544 float fac= ((float)a)/16.0f * 0.5f; /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ 01545 phi= (float)(0.5*M_PI) + fac * (pchan->limitmax[0] - pchan->limitmin[0]); 01546 01547 i= (a == -16) ? 2 : 3; 01548 corner[i][0]= 0.0f; 01549 corner[i][1]= (float)sin(phi); 01550 corner[i][2]= (float)cos(phi); 01551 glVertex3fv(corner[i]); 01552 } 01553 glEnd(); 01554 01555 glRotatef(-theta, 1.0f, 0.0f, 0.0f); 01556 } 01557 01558 /* out of cone, out of bone */ 01559 glPopMatrix(); 01560 } 01561 } 01562 } 01563 } 01564 } 01565 } 01566 } 01567 01568 static void bone_matrix_translate_y(float mat[][4], float y) 01569 { 01570 float trans[3]; 01571 01572 VECCOPY(trans, mat[1]); 01573 mul_v3_fl(trans, y); 01574 add_v3_v3(mat[3], trans); 01575 } 01576 01577 /* assumes object is Armature with pose */ 01578 static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, const short is_ghost, const short is_outline) 01579 { 01580 RegionView3D *rv3d= ar->regiondata; 01581 Object *ob= base->object; 01582 bArmature *arm= ob->data; 01583 bPoseChannel *pchan; 01584 Bone *bone; 01585 GLfloat tmp; 01586 float smat[4][4], imat[4][4], bmat[4][4]; 01587 int index= -1; 01588 short do_dashed= 3, draw_wire= 0; 01589 short flag, constflag; 01590 01591 /* being set below */ 01592 arm->layer_used= 0; 01593 01594 /* hacky... prevent outline select from drawing dashed helplines */ 01595 glGetFloatv(GL_LINE_WIDTH, &tmp); 01596 if (tmp > 1.1f) do_dashed &= ~1; 01597 if (v3d->flag & V3D_HIDE_HELPLINES) do_dashed &= ~2; 01598 01599 /* precalc inverse matrix for drawing screen aligned */ 01600 if (arm->drawtype==ARM_ENVELOPE) { 01601 /* precalc inverse matrix for drawing screen aligned */ 01602 copy_m4_m4(smat, rv3d->viewmatob); 01603 mul_mat3_m4_fl(smat, 1.0f/len_v3(ob->obmat[0])); 01604 invert_m4_m4(imat, smat); 01605 01606 /* and draw blended distances */ 01607 if (arm->flag & ARM_POSEMODE) { 01608 glEnable(GL_BLEND); 01609 //glShadeModel(GL_SMOOTH); 01610 01611 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 01612 01613 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01614 bone= pchan->bone; 01615 if (bone) { 01616 /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] 01617 * NOTE: this is the only case with NO_DEFORM==0 flag, as this is for envelope influence drawing 01618 */ 01619 if ( (bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))==0 && 01620 ((G.f & G_PICKSEL)==0 || (bone->flag & BONE_UNSELECTABLE)==0) ) 01621 { 01622 if (bone->flag & (BONE_SELECTED)) { 01623 if (bone->layer & arm->layer) 01624 draw_sphere_bone_dist(smat, imat, pchan, NULL); 01625 } 01626 } 01627 } 01628 } 01629 01630 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 01631 glDisable(GL_BLEND); 01632 //glShadeModel(GL_FLAT); 01633 } 01634 } 01635 01636 /* little speedup, also make sure transparent only draws once */ 01637 glCullFace(GL_BACK); 01638 glEnable(GL_CULL_FACE); 01639 01640 /* if solid we draw that first, with selection codes, but without names, axes etc */ 01641 if (dt > OB_WIRE) { 01642 if (arm->flag & ARM_POSEMODE) 01643 index= base->selcol; 01644 01645 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01646 bone= pchan->bone; 01647 arm->layer_used |= bone->layer; 01648 01649 /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ 01650 if ( (bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0 && 01651 ((G.f & G_PICKSEL)==0 || (bone->flag & BONE_UNSELECTABLE)==0) ) 01652 { 01653 if (bone->layer & arm->layer) { 01654 int use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM); 01655 glPushMatrix(); 01656 01657 if(use_custom && pchan->custom_tx) { 01658 glMultMatrixf(pchan->custom_tx->pose_mat); 01659 } 01660 else { 01661 glMultMatrixf(pchan->pose_mat); 01662 } 01663 01664 /* catch exception for bone with hidden parent */ 01665 flag= bone->flag; 01666 if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) 01667 flag &= ~BONE_CONNECTED; 01668 01669 /* set temporary flag for drawing bone as active, but only if selected */ 01670 if (bone == arm->act_bone) 01671 flag |= BONE_DRAW_ACTIVE; 01672 01673 /* set color-set to use */ 01674 set_pchan_colorset(ob, pchan); 01675 01676 if (use_custom) { 01677 /* if drawwire, don't try to draw in solid */ 01678 if (pchan->bone->flag & BONE_DRAWWIRE) 01679 draw_wire= 1; 01680 else 01681 draw_custom_bone(scene, v3d, rv3d, pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length); 01682 } 01683 else if (arm->drawtype==ARM_LINE) 01684 ; /* nothing in solid */ 01685 else if (arm->drawtype==ARM_ENVELOPE) 01686 draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); 01687 else if (arm->drawtype==ARM_B_BONE) 01688 draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); 01689 else 01690 draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); 01691 01692 glPopMatrix(); 01693 } 01694 } 01695 01696 if (index!= -1) 01697 index+= 0x10000; // pose bones count in higher 2 bytes only 01698 } 01699 01700 /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet, 01701 * stick bones and/or wire custom-shapes are drawn in next loop 01702 */ 01703 if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) { 01704 /* object tag, for bordersel optim */ 01705 glLoadName(index & 0xFFFF); 01706 index= -1; 01707 } 01708 } 01709 01710 /* draw custom bone shapes as wireframes */ 01711 if ( !(arm->flag & ARM_NO_CUSTOM) && 01712 ((draw_wire) || (dt <= OB_WIRE)) ) 01713 { 01714 if (arm->flag & ARM_POSEMODE) 01715 index= base->selcol; 01716 01717 /* only draw custom bone shapes that need to be drawn as wires */ 01718 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01719 bone= pchan->bone; 01720 01721 /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ 01722 if ( (bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0 && 01723 ((G.f & G_PICKSEL)==0 || (bone->flag & BONE_UNSELECTABLE)==0) ) 01724 { 01725 if (bone->layer & arm->layer) { 01726 if (pchan->custom) { 01727 if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) { 01728 glPushMatrix(); 01729 01730 if(pchan->custom_tx) { 01731 glMultMatrixf(pchan->custom_tx->pose_mat); 01732 } 01733 else { 01734 glMultMatrixf(pchan->pose_mat); 01735 } 01736 01737 /* prepare colors */ 01738 if(is_ghost) { 01739 /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ 01740 } 01741 else if (arm->flag & ARM_POSEMODE) 01742 set_pchan_colorset(ob, pchan); 01743 else { 01744 if ((scene->basact)==base) { 01745 if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); 01746 else UI_ThemeColor(TH_WIRE); 01747 } 01748 else { 01749 if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_SELECT); 01750 else UI_ThemeColor(TH_WIRE); 01751 } 01752 } 01753 01754 /* catch exception for bone with hidden parent */ 01755 flag= bone->flag; 01756 if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) 01757 flag &= ~BONE_CONNECTED; 01758 01759 /* set temporary flag for drawing bone as active, but only if selected */ 01760 if (bone == arm->act_bone) 01761 flag |= BONE_DRAW_ACTIVE; 01762 01763 draw_custom_bone(scene, v3d, rv3d, pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length); 01764 01765 glPopMatrix(); 01766 } 01767 } 01768 } 01769 } 01770 01771 if (index != -1) 01772 index+= 0x10000; // pose bones count in higher 2 bytes only 01773 } 01774 /* stick bones have not been drawn yet so dont clear object selection in this case */ 01775 if ((arm->drawtype != ARM_LINE) && draw_wire) { 01776 /* object tag, for bordersel optim */ 01777 glLoadName(index & 0xFFFF); 01778 index= -1; 01779 } 01780 } 01781 01782 /* wire draw over solid only in posemode */ 01783 if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) { 01784 /* draw line check first. we do selection indices */ 01785 if (arm->drawtype==ARM_LINE) { 01786 if (arm->flag & ARM_POSEMODE) 01787 index= base->selcol; 01788 } 01789 /* if solid && posemode, we draw again with polygonoffset */ 01790 else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) { 01791 bglPolygonOffset(rv3d->dist, 1.0); 01792 } 01793 else { 01794 /* and we use selection indices if not done yet */ 01795 if (arm->flag & ARM_POSEMODE) 01796 index= base->selcol; 01797 } 01798 01799 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01800 bone= pchan->bone; 01801 arm->layer_used |= bone->layer; 01802 01803 /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ 01804 if ( (bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0 && 01805 ((G.f & G_PICKSEL)==0 || (bone->flag & BONE_UNSELECTABLE)==0) ) 01806 { 01807 if (bone->layer & arm->layer) { 01808 if ((do_dashed & 1) && (pchan->parent)) { 01809 /* Draw a line from our root to the parent's tip 01810 * - only if V3D_HIDE_HELPLINES is enabled... 01811 */ 01812 if ( (do_dashed & 2) && ((bone->flag & BONE_CONNECTED)==0) ) { 01813 if (arm->flag & ARM_POSEMODE) { 01814 glLoadName(index & 0xFFFF); // object tag, for bordersel optim 01815 UI_ThemeColor(TH_WIRE); 01816 } 01817 setlinestyle(3); 01818 glBegin(GL_LINES); 01819 glVertex3fv(pchan->pose_head); 01820 glVertex3fv(pchan->parent->pose_tail); 01821 glEnd(); 01822 setlinestyle(0); 01823 } 01824 01825 /* Draw a line to IK root bone 01826 * - only if temporary chain (i.e. "autoik") 01827 */ 01828 if (arm->flag & ARM_POSEMODE) { 01829 if (pchan->constflag & PCHAN_HAS_IK) { 01830 if (bone->flag & BONE_SELECTED) { 01831 if (pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0); 01832 else glColor3ub(200, 200, 50); // add theme! 01833 01834 glLoadName(index & 0xFFFF); 01835 pchan_draw_IK_root_lines(pchan, !(do_dashed & 2)); 01836 } 01837 } 01838 else if (pchan->constflag & PCHAN_HAS_SPLINEIK) { 01839 if (bone->flag & BONE_SELECTED) { 01840 glColor3ub(150, 200, 50); // add theme! 01841 01842 glLoadName(index & 0xFFFF); 01843 pchan_draw_IK_root_lines(pchan, !(do_dashed & 2)); 01844 } 01845 } 01846 } 01847 } 01848 01849 glPushMatrix(); 01850 if (arm->drawtype != ARM_ENVELOPE) 01851 glMultMatrixf(pchan->pose_mat); 01852 01853 /* catch exception for bone with hidden parent */ 01854 flag= bone->flag; 01855 if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) 01856 flag &= ~BONE_CONNECTED; 01857 01858 /* set temporary flag for drawing bone as active, but only if selected */ 01859 if (bone == arm->act_bone) 01860 flag |= BONE_DRAW_ACTIVE; 01861 01862 /* extra draw service for pose mode */ 01863 constflag= pchan->constflag; 01864 if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) 01865 constflag |= PCHAN_HAS_ACTION; 01866 01867 /* set color-set to use */ 01868 set_pchan_colorset(ob, pchan); 01869 01870 if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) 01871 ; // custom bone shapes should not be drawn here! 01872 else if (arm->drawtype==ARM_ENVELOPE) { 01873 if (dt < OB_SOLID) 01874 draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL); 01875 } 01876 else if (arm->drawtype==ARM_LINE) 01877 draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); 01878 else if (arm->drawtype==ARM_B_BONE) 01879 draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); 01880 else 01881 draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); 01882 01883 glPopMatrix(); 01884 } 01885 } 01886 01887 /* pose bones count in higher 2 bytes only */ 01888 if (index != -1) 01889 index+= 0x10000; 01890 } 01891 /* restore things */ 01892 if ((arm->drawtype!=ARM_LINE)&& (dt>OB_WIRE) && (arm->flag & ARM_POSEMODE)) 01893 bglPolygonOffset(rv3d->dist, 0.0); 01894 } 01895 01896 /* restore */ 01897 glDisable(GL_CULL_FACE); 01898 01899 /* draw DoFs */ 01900 if (arm->flag & ARM_POSEMODE) 01901 draw_pose_dofs(ob); 01902 01903 /* finally names and axes */ 01904 if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES) && is_outline == 0) { 01905 /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ 01906 if ((G.f & G_PICKSEL) == 0) { 01907 float vec[3]; 01908 01909 unsigned char col[4]; 01910 float col_f[4]; 01911 glGetFloatv(GL_CURRENT_COLOR, col_f); /* incase this is not set below */ 01912 rgb_float_to_byte(col_f, col); 01913 col[3]= 255; 01914 01915 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 01916 01917 for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { 01918 if ((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) { 01919 if (pchan->bone->layer & arm->layer) { 01920 if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) { 01921 bone= pchan->bone; 01922 UI_GetThemeColor3ubv((bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); 01923 } 01924 else if (dt > OB_WIRE) { 01925 UI_GetThemeColor3ubv(TH_TEXT, col); 01926 } 01927 01928 /* Draw names of bone */ 01929 if (arm->flag & ARM_DRAWNAMES) { 01930 mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail); 01931 view3d_cached_text_draw_add(vec, pchan->name, 10, 0, col); 01932 } 01933 01934 /* Draw additional axes on the bone tail */ 01935 if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) { 01936 glPushMatrix(); 01937 copy_m4_m4(bmat, pchan->pose_mat); 01938 bone_matrix_translate_y(bmat, pchan->bone->length); 01939 glMultMatrixf(bmat); 01940 01941 glColor3ubv(col); 01942 drawaxes(pchan->bone->length*0.25f, OB_ARROWS); 01943 01944 glPopMatrix(); 01945 } 01946 } 01947 } 01948 } 01949 01950 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 01951 } 01952 } 01953 } 01954 01955 /* in editmode, we don't store the bone matrix... */ 01956 static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) 01957 { 01958 float delta[3]; 01959 float mat[3][3]; 01960 01961 /* Compose the parent transforms (i.e. their translations) */ 01962 sub_v3_v3v3(delta, eBone->tail, eBone->head); 01963 01964 eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); 01965 01966 vec_roll_to_mat3(delta, eBone->roll, mat); 01967 copy_m4_m3(bmat, mat); 01968 01969 add_v3_v3(bmat[3], eBone->head); 01970 } 01971 01972 static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) 01973 { 01974 RegionView3D *rv3d= ar->regiondata; 01975 EditBone *eBone; 01976 bArmature *arm= ob->data; 01977 float smat[4][4], imat[4][4], bmat[4][4]; 01978 unsigned int index; 01979 int flag; 01980 01981 /* being set in code below */ 01982 arm->layer_used= 0; 01983 01984 /* envelope (deform distance) */ 01985 if(arm->drawtype==ARM_ENVELOPE) { 01986 /* precalc inverse matrix for drawing screen aligned */ 01987 copy_m4_m4(smat, rv3d->viewmatob); 01988 mul_mat3_m4_fl(smat, 1.0f/len_v3(ob->obmat[0])); 01989 invert_m4_m4(imat, smat); 01990 01991 /* and draw blended distances */ 01992 glEnable(GL_BLEND); 01993 //glShadeModel(GL_SMOOTH); 01994 01995 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 01996 01997 for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { 01998 if (eBone->layer & arm->layer) { 01999 if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) { 02000 if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL)) 02001 draw_sphere_bone_dist(smat, imat, NULL, eBone); 02002 } 02003 } 02004 } 02005 02006 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 02007 glDisable(GL_BLEND); 02008 //glShadeModel(GL_FLAT); 02009 } 02010 02011 /* if solid we draw it first */ 02012 if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) { 02013 for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) { 02014 if (eBone->layer & arm->layer) { 02015 if ((eBone->flag & BONE_HIDDEN_A)==0) { 02016 glPushMatrix(); 02017 get_matrix_editbone(eBone, bmat); 02018 glMultMatrixf(bmat); 02019 02020 /* catch exception for bone with hidden parent */ 02021 flag= eBone->flag; 02022 if ( (eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) 02023 flag &= ~BONE_CONNECTED; 02024 02025 /* set temporary flag for drawing bone as active, but only if selected */ 02026 if (eBone == arm->act_edbone) 02027 flag |= BONE_DRAW_ACTIVE; 02028 02029 if (arm->drawtype==ARM_ENVELOPE) 02030 draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); 02031 else if(arm->drawtype==ARM_B_BONE) 02032 draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); 02033 else { 02034 draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); 02035 } 02036 02037 glPopMatrix(); 02038 } 02039 } 02040 } 02041 } 02042 02043 /* if wire over solid, set offset */ 02044 index= -1; 02045 glLoadName(-1); 02046 if (arm->drawtype==ARM_LINE) { 02047 if(G.f & G_PICKSEL) 02048 index= 0; 02049 } 02050 else if (dt > OB_WIRE) 02051 bglPolygonOffset(rv3d->dist, 1.0f); 02052 else if (arm->flag & ARM_EDITMODE) 02053 index= 0; /* do selection codes */ 02054 02055 for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { 02056 arm->layer_used |= eBone->layer; 02057 if (eBone->layer & arm->layer) { 02058 if ((eBone->flag & BONE_HIDDEN_A)==0) { 02059 02060 /* catch exception for bone with hidden parent */ 02061 flag= eBone->flag; 02062 if ( (eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) 02063 flag &= ~BONE_CONNECTED; 02064 02065 /* set temporary flag for drawing bone as active, but only if selected */ 02066 if (eBone == arm->act_edbone) 02067 flag |= BONE_DRAW_ACTIVE; 02068 02069 if (arm->drawtype == ARM_ENVELOPE) { 02070 if (dt < OB_SOLID) 02071 draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone); 02072 } 02073 else { 02074 glPushMatrix(); 02075 get_matrix_editbone(eBone, bmat); 02076 glMultMatrixf(bmat); 02077 02078 if (arm->drawtype == ARM_LINE) 02079 draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); 02080 else if (arm->drawtype == ARM_B_BONE) 02081 draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); 02082 else 02083 draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); 02084 02085 glPopMatrix(); 02086 } 02087 02088 /* offset to parent */ 02089 if (eBone->parent) { 02090 UI_ThemeColor(TH_WIRE); 02091 glLoadName (-1); // -1 here is OK! 02092 setlinestyle(3); 02093 02094 glBegin(GL_LINES); 02095 glVertex3fv(eBone->parent->tail); 02096 glVertex3fv(eBone->head); 02097 glEnd(); 02098 02099 setlinestyle(0); 02100 } 02101 } 02102 } 02103 if(index!=-1) index++; 02104 } 02105 02106 /* restore */ 02107 if(index!=-1) glLoadName(-1); 02108 if (arm->drawtype==ARM_LINE); 02109 else if (dt>OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f); 02110 02111 /* finally names and axes */ 02112 if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) { 02113 // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing 02114 if ((G.f & G_PICKSEL) == 0) { 02115 float vec[3]; 02116 unsigned char col[4]; 02117 col[3]= 255; 02118 02119 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 02120 02121 for (eBone=arm->edbo->first; eBone; eBone=eBone->next) { 02122 if(eBone->layer & arm->layer) { 02123 if ((eBone->flag & BONE_HIDDEN_A)==0) { 02124 02125 UI_GetThemeColor3ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); 02126 02127 /* Draw name */ 02128 if (arm->flag & ARM_DRAWNAMES) { 02129 mid_v3_v3v3(vec, eBone->head, eBone->tail); 02130 glRasterPos3fv(vec); 02131 view3d_cached_text_draw_add(vec, eBone->name, 10, 0, col); 02132 } 02133 /* Draw additional axes */ 02134 if (arm->flag & ARM_DRAWAXES) { 02135 glPushMatrix(); 02136 get_matrix_editbone(eBone, bmat); 02137 bone_matrix_translate_y(bmat, eBone->length); 02138 glMultMatrixf(bmat); 02139 02140 glColor3ubv(col); 02141 drawaxes(eBone->length*0.25f, OB_ARROWS); 02142 02143 glPopMatrix(); 02144 } 02145 02146 } 02147 } 02148 } 02149 02150 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 02151 } 02152 } 02153 } 02154 02155 /* ****************************** Armature Visualisation ******************************** */ 02156 02157 /* ---------- Paths --------- */ 02158 02159 /* draw bone paths 02160 * - in view space 02161 */ 02162 static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) 02163 { 02164 bAnimVizSettings *avs= &ob->pose->avs; 02165 bArmature *arm= ob->data; 02166 bPoseChannel *pchan; 02167 02168 /* setup drawing environment for paths */ 02169 draw_motion_paths_init(v3d, ar); 02170 02171 /* draw paths where they exist and they releated bone is visible */ 02172 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 02173 if ((pchan->bone->layer & arm->layer) && (pchan->mpath)) 02174 draw_motion_path_instance(scene, ob, pchan, avs, pchan->mpath); 02175 } 02176 02177 /* cleanup after drawing */ 02178 draw_motion_paths_cleanup(v3d); 02179 } 02180 02181 02182 /* ---------- Ghosts --------- */ 02183 02184 /* helper function for ghost drawing - sets/removes flags for temporarily 02185 * hiding unselected bones while drawing ghosts 02186 */ 02187 static void ghost_poses_tag_unselected(Object *ob, short unset) 02188 { 02189 bArmature *arm= ob->data; 02190 bPose *pose= ob->pose; 02191 bPoseChannel *pchan; 02192 02193 /* don't do anything if no hiding any bones */ 02194 if ((arm->flag & ARM_GHOST_ONLYSEL)==0) 02195 return; 02196 02197 /* loop over all pchans, adding/removing tags as appropriate */ 02198 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { 02199 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { 02200 if (unset) { 02201 /* remove tags from all pchans if cleaning up */ 02202 pchan->bone->flag &= ~BONE_HIDDEN_PG; 02203 } 02204 else { 02205 /* set tags on unselected pchans only */ 02206 if ((pchan->bone->flag & BONE_SELECTED)==0) 02207 pchan->bone->flag |= BONE_HIDDEN_PG; 02208 } 02209 } 02210 } 02211 } 02212 02213 /* draw ghosts that occur within a frame range 02214 * note: object should be in posemode 02215 */ 02216 static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base) 02217 { 02218 Object *ob= base->object; 02219 AnimData *adt= BKE_animdata_from_id(&ob->id); 02220 bArmature *arm= ob->data; 02221 bPose *posen, *poseo; 02222 float start, end, stepsize, range, colfac; 02223 int cfrao, flago, ipoflago; 02224 02225 start = (float)arm->ghostsf; 02226 end = (float)arm->ghostef; 02227 if (end <= start) 02228 return; 02229 02230 stepsize= (float)(arm->ghostsize); 02231 range= (float)(end - start); 02232 02233 /* store values */ 02234 ob->mode &= ~OB_MODE_POSE; 02235 cfrao= CFRA; 02236 flago= arm->flag; 02237 arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); 02238 ipoflago= ob->ipoflag; 02239 ob->ipoflag |= OB_DISABLE_PATH; 02240 02241 /* copy the pose */ 02242 poseo= ob->pose; 02243 copy_pose(&posen, ob->pose, 1); 02244 ob->pose= posen; 02245 armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ 02246 ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ 02247 02248 glEnable(GL_BLEND); 02249 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 02250 02251 /* draw from first frame of range to last */ 02252 for (CFRA= (int)start; CFRA < end; CFRA += (int)stepsize) { 02253 colfac = (end - (float)CFRA) / range; 02254 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); 02255 02256 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); 02257 where_is_pose(scene, ob); 02258 draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); 02259 } 02260 glDisable(GL_BLEND); 02261 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 02262 02263 ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ 02264 free_pose(posen); 02265 02266 /* restore */ 02267 CFRA= cfrao; 02268 ob->pose= poseo; 02269 arm->flag= flago; 02270 armature_rebuild_pose(ob, ob->data); 02271 ob->mode |= OB_MODE_POSE; 02272 ob->ipoflag= ipoflago; 02273 } 02274 02275 /* draw ghosts on keyframes in action within range 02276 * - object should be in posemode 02277 */ 02278 static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base) 02279 { 02280 Object *ob= base->object; 02281 AnimData *adt= BKE_animdata_from_id(&ob->id); 02282 bAction *act= (adt) ? adt->action : NULL; 02283 bArmature *arm= ob->data; 02284 bPose *posen, *poseo; 02285 DLRBT_Tree keys; 02286 ActKeyColumn *ak, *akn; 02287 float start, end, range, colfac, i; 02288 int cfrao, flago; 02289 02290 start = (float)arm->ghostsf; 02291 end = (float)arm->ghostef; 02292 if (end <= start) 02293 return; 02294 02295 /* get keyframes - then clip to only within range */ 02296 BLI_dlrbTree_init(&keys); 02297 action_to_keylist(adt, act, &keys, NULL); 02298 BLI_dlrbTree_linkedlist_sync(&keys); 02299 02300 range= 0; 02301 for (ak= keys.first; ak; ak= akn) { 02302 akn= ak->next; 02303 02304 if ((ak->cfra < start) || (ak->cfra > end)) 02305 BLI_freelinkN((ListBase *)&keys, ak); 02306 else 02307 range++; 02308 } 02309 if (range == 0) return; 02310 02311 /* store values */ 02312 ob->mode &= ~OB_MODE_POSE; 02313 cfrao= CFRA; 02314 flago= arm->flag; 02315 arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); 02316 ob->ipoflag |= OB_DISABLE_PATH; 02317 02318 /* copy the pose */ 02319 poseo= ob->pose; 02320 copy_pose(&posen, ob->pose, 1); 02321 ob->pose= posen; 02322 armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ 02323 ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ 02324 02325 glEnable(GL_BLEND); 02326 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 02327 02328 /* draw from first frame of range to last */ 02329 for (ak=keys.first, i=0; ak; ak=ak->next, i++) { 02330 colfac = i/range; 02331 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); 02332 02333 CFRA= (int)ak->cfra; 02334 02335 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); 02336 where_is_pose(scene, ob); 02337 draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); 02338 } 02339 glDisable(GL_BLEND); 02340 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 02341 02342 ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ 02343 BLI_dlrbTree_free(&keys); 02344 free_pose(posen); 02345 02346 /* restore */ 02347 CFRA= cfrao; 02348 ob->pose= poseo; 02349 arm->flag= flago; 02350 armature_rebuild_pose(ob, ob->data); 02351 ob->mode |= OB_MODE_POSE; 02352 } 02353 02354 /* draw ghosts around current frame 02355 * - object is supposed to be armature in posemode 02356 */ 02357 static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) 02358 { 02359 Object *ob= base->object; 02360 AnimData *adt= BKE_animdata_from_id(&ob->id); 02361 bArmature *arm= ob->data; 02362 bPose *posen, *poseo; 02363 float cur, start, end, stepsize, range, colfac, actframe, ctime; 02364 int cfrao, flago; 02365 02366 /* pre conditions, get an action with sufficient frames */ 02367 if ELEM(NULL, adt, adt->action) 02368 return; 02369 02370 calc_action_range(adt->action, &start, &end, 0); 02371 if (start == end) 02372 return; 02373 02374 stepsize= (float)(arm->ghostsize); 02375 range= (float)(arm->ghostep)*stepsize + 0.5f; /* plus half to make the for loop end correct */ 02376 02377 /* store values */ 02378 ob->mode &= ~OB_MODE_POSE; 02379 cfrao= CFRA; 02380 actframe= BKE_nla_tweakedit_remap(adt, (float)CFRA, 0); 02381 flago= arm->flag; 02382 arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); 02383 02384 /* copy the pose */ 02385 poseo= ob->pose; 02386 copy_pose(&posen, ob->pose, 1); 02387 ob->pose= posen; 02388 armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ 02389 ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ 02390 02391 glEnable(GL_BLEND); 02392 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); 02393 02394 /* draw from darkest blend to lowest */ 02395 for(cur= stepsize; cur<range; cur+=stepsize) { 02396 ctime= cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */ 02397 colfac= ctime/range; 02398 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); 02399 02400 /* only within action range */ 02401 if (actframe+ctime >= start && actframe+ctime <= end) { 02402 CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP); 02403 02404 if (CFRA != cfrao) { 02405 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); 02406 where_is_pose(scene, ob); 02407 draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); 02408 } 02409 } 02410 02411 ctime= cur + (float)fmod((float)cfrao, stepsize) - stepsize+1.0f; /* ensures consistent stepping */ 02412 colfac= ctime/range; 02413 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac))); 02414 02415 /* only within action range */ 02416 if ((actframe-ctime >= start) && (actframe-ctime <= end)) { 02417 CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP); 02418 02419 if (CFRA != cfrao) { 02420 BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); 02421 where_is_pose(scene, ob); 02422 draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); 02423 } 02424 } 02425 } 02426 glDisable(GL_BLEND); 02427 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); 02428 02429 ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ 02430 free_pose(posen); 02431 02432 /* restore */ 02433 CFRA= cfrao; 02434 ob->pose= poseo; 02435 arm->flag= flago; 02436 armature_rebuild_pose(ob, ob->data); 02437 ob->mode |= OB_MODE_POSE; 02438 } 02439 02440 /* ********************************** Armature Drawing - Main ************************* */ 02441 02442 /* called from drawobject.c, return 1 if nothing was drawn */ 02443 int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline) 02444 { 02445 Object *ob= base->object; 02446 bArmature *arm= ob->data; 02447 int retval= 0; 02448 02449 if(v3d->flag2 & V3D_RENDER_OVERRIDE) 02450 return 1; 02451 02452 if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) { 02453 /* we use color for solid lighting */ 02454 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); 02455 glEnable(GL_COLOR_MATERIAL); 02456 glColor3ub(255,255,255); // clear spec 02457 glDisable(GL_COLOR_MATERIAL); 02458 02459 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 02460 glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting... 02461 } 02462 02463 /* arm->flag is being used to detect mode... */ 02464 /* editmode? */ 02465 if(arm->edbo) { 02466 arm->flag |= ARM_EDITMODE; 02467 draw_ebones(v3d, ar, ob, dt); 02468 arm->flag &= ~ARM_EDITMODE; 02469 } 02470 else{ 02471 /* Draw Pose */ 02472 if(ob->pose && ob->pose->chanbase.first) { 02473 /* drawing posemode selection indices or colors only in these cases */ 02474 if(!(base->flag & OB_FROMDUPLI)) { 02475 if(G.f & G_PICKSEL) { 02476 #if 0 /* nifty but actually confusing to allow bone selection out of posemode */ 02477 if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { 02478 if(ob==modifiers_isDeformedByArmature(OBACT)) 02479 arm->flag |= ARM_POSEMODE; 02480 } 02481 else 02482 #endif 02483 if(ob->mode & OB_MODE_POSE) { 02484 arm->flag |= ARM_POSEMODE; 02485 } 02486 } 02487 else if(ob->mode & OB_MODE_POSE) { 02488 if (arm->ghosttype == ARM_GHOST_RANGE) { 02489 draw_ghost_poses_range(scene, v3d, ar, base); 02490 } 02491 else if (arm->ghosttype == ARM_GHOST_KEYS) { 02492 draw_ghost_poses_keys(scene, v3d, ar, base); 02493 } 02494 else if (arm->ghosttype == ARM_GHOST_CUR) { 02495 if (arm->ghostep) 02496 draw_ghost_poses(scene, v3d, ar, base); 02497 } 02498 if ((flag & DRAW_SCENESET)==0) { 02499 if(ob==OBACT) 02500 arm->flag |= ARM_POSEMODE; 02501 else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { 02502 if(ob==modifiers_isDeformedByArmature(OBACT)) 02503 arm->flag |= ARM_POSEMODE; 02504 } 02505 draw_pose_paths(scene, v3d, ar, ob); 02506 } 02507 } 02508 } 02509 draw_pose_bones(scene, v3d, ar, base, dt, FALSE, is_outline); 02510 arm->flag &= ~ARM_POSEMODE; 02511 02512 if(ob->mode & OB_MODE_POSE) 02513 UI_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */ 02514 } 02515 else retval= 1; 02516 } 02517 /* restore */ 02518 glFrontFace(GL_CCW); 02519 02520 return retval; 02521 } 02522 02523 /* *************** END Armature drawing ******************* */ 02524 02525