diff options
Diffstat (limited to 'source/blender/src/drawarmature.c')
-rw-r--r-- | source/blender/src/drawarmature.c | 2576 |
1 files changed, 0 insertions, 2576 deletions
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c deleted file mode 100644 index 2d41e01f7e4..00000000000 --- a/source/blender/src/drawarmature.c +++ /dev/null @@ -1,2576 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2005 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "MEM_guardedalloc.h" - -#include "BMF_Api.h" - -#include "DNA_action_types.h" -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_ID.h" -#include "DNA_nla_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_view3d_types.h" -#include "DNA_userdef_types.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_constraint.h" -#include "BKE_depsgraph.h" -#include "BKE_DerivedMesh.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_object.h" -#include "BKE_ipo.h" -#include "BKE_utildefines.h" - -#include "BIF_editaction.h" -#include "BIF_editarmature.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" -#include "BIF_graphics.h" -#include "BIF_interface.h" -#include "BIF_poseobject.h" -#include "BIF_mywindow.h" -#include "BIF_resources.h" -#include "BIF_screen.h" - -#include "BDR_editobject.h" -#include "BDR_drawobject.h" -#include "BDR_drawaction.h" - -#include "BSE_edit.h" -#include "BSE_view.h" - -#include "mydevice.h" -#include "blendef.h" -#include "nla.h" - - -/* *************** Armature Drawing - Coloring API ***************************** */ - -/* global here is reset before drawing each bone */ -static ThemeWireColor *bcolor= NULL; - -/* values of colCode for set_pchan_glcolor */ -enum { - PCHAN_COLOR_NORMAL = 0, /* normal drawing */ - PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */ - PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */ - - PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ - PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ - PCHAN_COLOR_LINEBONE /* for the middle of line-bones */ -}; - -/* This function sets the color-set for coloring a certain bone */ -static void set_pchan_colorset (Object *ob, bPoseChannel *pchan) -{ - bPose *pose= (ob) ? ob->pose : NULL; - bArmature *arm= (ob) ? ob->data : NULL; - bActionGroup *grp= NULL; - short color_index= 0; - - /* sanity check */ - if (ELEM4(NULL, ob, arm, pose, pchan)) { - bcolor= NULL; - return; - } - - /* only try to set custom color if enabled for armature */ - if (arm->flag & ARM_COL_CUSTOM) { - /* currently, a bone can only use a custom color set if it's group (if it has one), - * has been set to use one - */ - if (pchan->agrp_index) { - grp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1)); - if (grp) - color_index= grp->customCol; - } - } - - /* bcolor is a pointer to the color set to use. If NULL, then the default - * color set (based on the theme colors for 3d-view) is used. - */ - if (color_index > 0) { - bTheme *btheme= U.themes.first; - bcolor= &btheme->tarm[(color_index - 1)]; - } - else if (color_index == -1) { - /* use the group's own custom color set */ - bcolor= (grp)? &grp->cs : NULL; - } - else - bcolor= NULL; -} - -/* This function is for brightening/darkening a given color (like BIF_ThemeColorShade()) */ -static void cp_shade_color3ub (char cp[], int offset) -{ - int r, g, b; - - r= offset + (int) cp[0]; - CLAMP(r, 0, 255); - g= offset + (int) cp[1]; - CLAMP(g, 0, 255); - b= offset + (int) cp[2]; - CLAMP(b, 0, 255); - - cp[0]= r; - cp[1]= g; - cp[2]= b; -} - -/* This function sets the gl-color for coloring a certain bone (based on bcolor) */ -static short set_pchan_glColor (short colCode, int armflag, int boneflag, int constflag) -{ - switch (colCode) { - case PCHAN_COLOR_NORMAL: - { - if (bcolor) { - char cp[3]; - - if (boneflag & BONE_ACTIVE) { - VECCOPY(cp, bcolor->active); - } - else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); - } - else { - /* a bit darker than solid */ - VECCOPY(cp, bcolor->solid); - cp_shade_color3ub(cp, -50); - } - - glColor3ub(cp[0], cp[1], cp[2]); - } - else { - if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40); - else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE); - else BIF_ThemeColor(TH_WIRE); - } - - return 1; - } - break; - - case PCHAN_COLOR_SOLID: - { - if (bcolor) { - char *cp= bcolor->solid; - glColor3ub(cp[0], cp[1], cp[2]); - } - else - BIF_ThemeColor(TH_BONE_SOLID); - - return 1; - } - break; - - case PCHAN_COLOR_CONSTS: - { - if ( (bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS) ) { - if (constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80); - else if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80); - else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80); - else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80); - else if (constflag) BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION - - return 1; - } - else - return 0; - } - break; - - case PCHAN_COLOR_SPHEREBONE_BASE: - { - if (bcolor) { - char cp[3]; - - if (boneflag & BONE_ACTIVE) { - VECCOPY(cp, bcolor->active); - } - else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); - } - else { - VECCOPY(cp, bcolor->solid); - } - - glColor3ub(cp[0], cp[1], cp[2]); - } - else { - if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40); - else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE); - else BIF_ThemeColor(TH_BONE_SOLID); - } - - return 1; - } - break; - case PCHAN_COLOR_SPHEREBONE_END: - { - if (bcolor) { - char cp[3]; - - if (boneflag & BONE_ACTIVE) { - VECCOPY(cp, bcolor->active); - cp_shade_color3ub(cp, 10); - } - else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); - cp_shade_color3ub(cp, -30); - } - else { - VECCOPY(cp, bcolor->solid); - cp_shade_color3ub(cp, -30); - } - - glColor3ub(cp[0], cp[1], cp[2]); - } - else { - if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10); - else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30); - else BIF_ThemeColorShade(TH_BONE_SOLID, -30); - } - } - break; - - case PCHAN_COLOR_LINEBONE: - { - /* inner part in background color or constraint */ - if ( (constflag) && ((bcolor==NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) ) { - if (constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200); - else if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0); - else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0); - else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120); - else if (constflag) BIF_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */ - } - else { - if (bcolor) { - char *cp= bcolor->solid; - glColor4ub(cp[0], cp[1], cp[2], 0.8); - } - else - BIF_ThemeColorShade(TH_BACK, -30); - } - - return 1; - } - break; - } - - return 0; -} - - -/* *************** Armature drawing, helper calls for parts ******************* */ - -/* half the cube, in Y */ -static float cube[8][3] = { -{-1.0, 0.0, -1.0}, -{-1.0, 0.0, 1.0}, -{-1.0, 1.0, 1.0}, -{-1.0, 1.0, -1.0}, -{ 1.0, 0.0, -1.0}, -{ 1.0, 0.0, 1.0}, -{ 1.0, 1.0, 1.0}, -{ 1.0, 1.0, -1.0}, -}; - -static void drawsolidcube_size(float xsize, float ysize, float zsize) -{ - static GLuint displist=0; - float n[3]; - - glScalef(xsize, ysize, zsize); - - n[0]=0; n[1]=0; n[2]=0; - - if(displist==0) { - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - glBegin(GL_QUADS); - n[0]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); - n[0]=0; - n[1]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); - n[1]=0; - n[0]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); - n[0]=0; - n[1]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); - n[1]=0; - n[2]= 1.0; - glNormal3fv(n); - glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); - n[2]=0; - n[2]= -1.0; - glNormal3fv(n); - glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); - glEnd(); - - glEndList(); - } - else glCallList(displist); - -} - -static void drawcube_size(float xsize, float ysize, float zsize) -{ - static GLuint displist=0; - - glScalef(xsize, ysize, zsize); - - if(displist == 0) { - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - glBegin(GL_LINE_STRIP); - glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]); - glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]); - glVertex3fv(cube[7]); glVertex3fv(cube[4]); - glEnd(); - - glBegin(GL_LINES); - glVertex3fv(cube[1]); glVertex3fv(cube[5]); - glVertex3fv(cube[2]); glVertex3fv(cube[6]); - glVertex3fv(cube[3]); glVertex3fv(cube[7]); - glEnd(); - - glEndList(); - } - else glCallList(displist); - -} - - -static void draw_bonevert(void) -{ - static GLuint displist=0; - - if (displist == 0) { - GLUquadricObj *qobj; - - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - glPushMatrix(); - - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); - gluDisk(qobj, 0.0, 0.05, 16, 1); - - glRotatef(90, 0, 1, 0); - gluDisk(qobj, 0.0, 0.05, 16, 1); - - glRotatef(90, 1, 0, 0); - gluDisk(qobj, 0.0, 0.05, 16, 1); - - gluDeleteQuadric(qobj); - - glPopMatrix(); - glEndList(); - } - else - glCallList(displist); -} - -static void draw_bonevert_solid(void) -{ - static GLuint displist=0; - - if (displist == 0) { - GLUquadricObj *qobj; - - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - glShadeModel(GL_SMOOTH); - gluSphere( qobj, 0.05, 8, 5); - glShadeModel(GL_FLAT); - gluDeleteQuadric(qobj); - - glEndList(); - } - else - glCallList(displist); -} - -static void draw_bone_octahedral() -{ - static GLuint displist=0; - - if (displist == 0) { - float vec[6][3]; - - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - vec[0][0]= vec[0][1]= vec[0][2]= 0.0; - vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0; - - vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1; - vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1; - vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1; - vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1; - - /* Section 1, sides */ - glBegin(GL_LINE_LOOP); - glVertex3fv(vec[0]); - glVertex3fv(vec[1]); - glVertex3fv(vec[5]); - glVertex3fv(vec[3]); - glVertex3fv(vec[0]); - glVertex3fv(vec[4]); - glVertex3fv(vec[5]); - glVertex3fv(vec[2]); - glEnd(); - - /* Section 1, square */ - glBegin(GL_LINE_LOOP); - glVertex3fv(vec[1]); - glVertex3fv(vec[2]); - glVertex3fv(vec[3]); - glVertex3fv(vec[4]); - glEnd(); - - glEndList(); - } - else - glCallList(displist); -} - -static void draw_bone_solid_octahedral(void) -{ - static GLuint displist=0; - - if (displist == 0) { - float vec[6][3], nor[3]; - - displist= glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); - - vec[0][0]= vec[0][1]= vec[0][2]= 0.0; - vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0; - - vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1; - vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1; - vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1; - vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1; - - - glBegin(GL_TRIANGLES); - /* bottom */ - CalcNormFloat(vec[2], vec[1], vec[0], nor); - glNormal3fv(nor); - glVertex3fv(vec[2]);glVertex3fv(vec[1]);glVertex3fv(vec[0]); - - CalcNormFloat(vec[3], vec[2], vec[0], nor); - glNormal3fv(nor); - glVertex3fv(vec[3]);glVertex3fv(vec[2]);glVertex3fv(vec[0]); - - CalcNormFloat(vec[4], vec[3], vec[0], nor); - glNormal3fv(nor); - glVertex3fv(vec[4]);glVertex3fv(vec[3]);glVertex3fv(vec[0]); - - CalcNormFloat(vec[1], vec[4], vec[0], nor); - glNormal3fv(nor); - glVertex3fv(vec[1]);glVertex3fv(vec[4]);glVertex3fv(vec[0]); - - /* top */ - CalcNormFloat(vec[5], vec[1], vec[2], nor); - glNormal3fv(nor); - glVertex3fv(vec[5]);glVertex3fv(vec[1]);glVertex3fv(vec[2]); - - CalcNormFloat(vec[5], vec[2], vec[3], nor); - glNormal3fv(nor); - glVertex3fv(vec[5]);glVertex3fv(vec[2]);glVertex3fv(vec[3]); - - CalcNormFloat(vec[5], vec[3], vec[4], nor); - glNormal3fv(nor); - glVertex3fv(vec[5]);glVertex3fv(vec[3]);glVertex3fv(vec[4]); - - CalcNormFloat(vec[5], vec[4], vec[1], nor); - glNormal3fv(nor); - glVertex3fv(vec[5]);glVertex3fv(vec[4]);glVertex3fv(vec[1]); - - glEnd(); - - glEndList(); - } - else - glCallList(displist); -} - -/* *************** Armature drawing, bones ******************* */ - - -static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) -{ - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED)==0) { - if (id != -1) - glLoadName(id | BONESEL_ROOT); - - if(dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0); - else - BIF_ThemeColor(TH_BONE_SOLID); - } - - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - } - - /* Draw tip point */ - if (id != -1) - glLoadName(id | BONESEL_TIP); - - if (dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0); - else - BIF_ThemeColor(TH_BONE_SOLID); - } - - glTranslatef(0.0, 1.0, 0.0); - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - glTranslatef(0.0, -1.0, 0.0); - -} - -/* 16 values of sin function (still same result!) */ -static float si[16] = { - 0.00000000, - 0.20129852, 0.39435585, - 0.57126821, 0.72479278, - 0.84864425, 0.93775213, - 0.98846832, 0.99871650, - 0.96807711, 0.89780453, - 0.79077573, 0.65137248, - 0.48530196, 0.29936312, - 0.10116832 -}; -/* 16 values of cos function (still same result!) */ -static float co[16] ={ - 1.00000000, - 0.97952994, 0.91895781, - 0.82076344, 0.68896691, - 0.52896401, 0.34730525, - 0.15142777, -0.05064916, - -0.25065253, -0.44039415, - -0.61210598, -0.75875812, - -0.87434661, -0.95413925, - -0.99486932 -}; - - - -/* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag, bPoseChannel *pchan, EditBone *ebone) -{ - float head, tail, length, dist; - float *headvec, *tailvec, dirvec[3]; - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ - ebone->length = VecLenf(ebone->head, ebone->tail); - - length= ebone->length; - tail= ebone->rad_tail; - dist= ebone->dist; - if (ebone->parent && (ebone->flag & BONE_CONNECTED)) - head= ebone->parent->rad_tail; - else - head= ebone->rad_head; - headvec= ebone->head; - tailvec= ebone->tail; - } - else { - length= pchan->bone->length; - tail= pchan->bone->rad_tail; - dist= pchan->bone->dist; - if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) - head= pchan->parent->bone->rad_tail; - else - head= pchan->bone->rad_head; - headvec= pchan->pose_head; - tailvec= pchan->pose_tail; - } - - /* ***** draw it ***** */ - - /* move vector to viewspace */ - VecSubf(dirvec, tailvec, headvec); - Mat4Mul3Vecfl(smat, dirvec); - /* clear zcomp */ - dirvec[2]= 0.0; - /* move vector back */ - Mat4Mul3Vecfl(imat, dirvec); - - if (0.0f != Normalize(dirvec)) { - float norvec[3], vec1[3], vec2[3], vec[3]; - int a; - - //VecMulf(dirvec, head); - Crossf(norvec, dirvec, imat[2]); - - glBegin(GL_QUAD_STRIP); - - for (a=0; a<16; a++) { - vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0]; - vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1]; - vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2]; - - vec1[0]= headvec[0] + head*vec[0]; - vec1[1]= headvec[1] + head*vec[1]; - vec1[2]= headvec[2] + head*vec[2]; - vec2[0]= headvec[0] + (head+dist)*vec[0]; - vec2[1]= headvec[1] + (head+dist)*vec[1]; - vec2[2]= headvec[2] + (head+dist)*vec[2]; - - glColor4ub(255, 255, 255, 50); - glVertex3fv(vec1); - //glColor4ub(255, 255, 255, 0); - glVertex3fv(vec2); - } - - for (a=15; a>=0; a--) { - vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0]; - vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1]; - vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2]; - - vec1[0]= tailvec[0] + tail*vec[0]; - vec1[1]= tailvec[1] + tail*vec[1]; - vec1[2]= tailvec[2] + tail*vec[2]; - vec2[0]= tailvec[0] + (tail+dist)*vec[0]; - vec2[1]= tailvec[1] + (tail+dist)*vec[1]; - vec2[2]= tailvec[2] + (tail+dist)*vec[2]; - - //glColor4ub(255, 255, 255, 50); - glVertex3fv(vec1); - //glColor4ub(255, 255, 255, 0); - glVertex3fv(vec2); - } - /* make it cyclic... */ - - vec[0]= - *(si) * dirvec[0] + *(co) * norvec[0]; - vec[1]= - *(si) * dirvec[1] + *(co) * norvec[1]; - vec[2]= - *(si) * dirvec[2] + *(co) * norvec[2]; - - vec1[0]= headvec[0] + head*vec[0]; - vec1[1]= headvec[1] + head*vec[1]; - vec1[2]= headvec[2] + head*vec[2]; - vec2[0]= headvec[0] + (head+dist)*vec[0]; - vec2[1]= headvec[1] + (head+dist)*vec[1]; - vec2[2]= headvec[2] + (head+dist)*vec[2]; - - //glColor4ub(255, 255, 255, 50); - glVertex3fv(vec1); - //glColor4ub(255, 255, 255, 0); - glVertex3fv(vec2); - - glEnd(); - } -} - - -/* smat, imat = mat & imat to draw screenaligned */ -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) -{ - float head, tail, length; - float *headvec, *tailvec, dirvec[3]; - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ - ebone->length = VecLenf(ebone->head, ebone->tail); - - length= ebone->length; - tail= ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head= ebone->parent->rad_tail; - else - head= ebone->rad_head; - headvec= ebone->head; - tailvec= ebone->tail; - } - else { - length= pchan->bone->length; - tail= pchan->bone->rad_tail; - if ((pchan->parent) && (boneflag & BONE_CONNECTED)) - head= pchan->parent->bone->rad_tail; - else - head= pchan->bone->rad_head; - headvec= pchan->pose_head; - tailvec= pchan->pose_tail; - } - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED)==0) { - if (id != -1) - glLoadName(id | BONESEL_ROOT); - - drawcircball(GL_LINE_LOOP, headvec, head, imat); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - - if (id != -1) - glLoadName(id | BONESEL_TIP); - - drawcircball(GL_LINE_LOOP, tailvec, tail, imat); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT); - else BIF_ThemeColor(TH_WIRE); - } - - VecSubf(dirvec, tailvec, headvec); - - /* move vector to viewspace */ - Mat4Mul3Vecfl(smat, dirvec); - /* clear zcomp */ - dirvec[2]= 0.0; - /* move vector back */ - Mat4Mul3Vecfl(imat, dirvec); - - if (0.0f != Normalize(dirvec)) { - float norvech[3], norvect[3], vec[3]; - - VECCOPY(vec, dirvec); - - VecMulf(dirvec, head); - Crossf(norvech, dirvec, imat[2]); - - VecMulf(vec, tail); - Crossf(norvect, vec, imat[2]); - - if (id != -1) - glLoadName(id | BONESEL_BONE); - - glBegin(GL_LINES); - vec[0]= headvec[0] + norvech[0]; - vec[1]= headvec[1] + norvech[1]; - vec[2]= headvec[2] + norvech[2]; - glVertex3fv(vec); - vec[0]= tailvec[0] + norvect[0]; - vec[1]= tailvec[1] + norvect[1]; - vec[2]= tailvec[2] + norvect[2]; - glVertex3fv(vec); - vec[0]= headvec[0] - norvech[0]; - vec[1]= headvec[1] - norvech[1]; - vec[2]= headvec[2] - norvech[2]; - glVertex3fv(vec); - vec[0]= tailvec[0] - norvect[0]; - vec[1]= tailvec[1] - norvect[1]; - vec[2]= tailvec[2] - norvect[2]; - glVertex3fv(vec); - - glEnd(); - } -} - -/* does wire only for outline selecting */ -static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) -{ - GLUquadricObj *qobj; - float head, tail, length; - float fac1, fac2; - - glPushMatrix(); - qobj = gluNewQuadric(); - - /* figure out the sizes of spheres */ - if (ebone) { - length= ebone->length; - tail= ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head= ebone->parent->rad_tail; - else - head= ebone->rad_head; - } - else { - length= pchan->bone->length; - tail= pchan->bone->rad_tail; - if (pchan->parent && (boneflag & BONE_CONNECTED)) - head= pchan->parent->bone->rad_tail; - else - head= pchan->bone->rad_head; - } - - /* move to z-axis space */ - glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); - - if (dt==OB_SOLID) { - /* set up solid drawing */ - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_LIGHTING); - - gluQuadricDrawStyle(qobj, GLU_FILL); - glShadeModel(GL_SMOOTH); - } - else { - gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); - } - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColorShade(TH_BONE_SOLID, -30); - } - else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, armflag, boneflag, constflag); - else if (dt==OB_SOLID) - BIF_ThemeColorShade(TH_BONE_SOLID, -30); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED)==0) { - if (id != -1) - glLoadName(id | BONESEL_ROOT); - gluSphere(qobj, head, 16, 10); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColorShade(TH_BONE_SOLID, -30); - } - - if (id != -1) - glLoadName(id | BONESEL_TIP); - - glTranslatef(0.0, 0.0, length); - gluSphere(qobj, tail, 16, 10); - glTranslatef(0.0, 0.0, -length); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT); - else BIF_ThemeColor(TH_BONE_SOLID); - } - else if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, armflag, boneflag, constflag); - else if (dt == OB_SOLID) - BIF_ThemeColor(TH_BONE_SOLID); - - fac1= (length-head)/length; - fac2= (length-tail)/length; - - if (length > (head+tail)) { - if (id != -1) - glLoadName (id | BONESEL_BONE); - - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0, -1.0); - - glTranslatef(0.0f, 0.0f, head); - gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1); - glTranslatef(0.0f, 0.0f, -head); - - glDisable(GL_POLYGON_OFFSET_FILL); - - /* draw sphere on extrema */ - glTranslatef(0.0f, 0.0f, length-tail); - gluSphere(qobj, fac2*tail + (1.0f-fac2)*head, 16, 10); - glTranslatef(0.0f, 0.0f, -length+tail); - - glTranslatef(0.0f, 0.0f, head); - gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10); - } - else { - /* 1 sphere in center */ - glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0); - gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10); - } - - /* restore */ - if (dt==OB_SOLID) { - glShadeModel(GL_FLAT); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - } - - glPopMatrix(); - gluDeleteQuadric(qobj); -} - -static GLubyte bm_dot6[]= {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0}; -static GLubyte bm_dot8[]= {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C}; - -static GLubyte bm_dot5[]= {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0}; -static GLubyte bm_dot7[]= {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38}; - - -static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) -{ - float length; - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (pchan) - length= pchan->bone->length; - else - length= ebone->length; - - glPushMatrix(); - glScalef(length, length, length); - - /* this chunk not in object mode */ - if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) { - glLineWidth(4.0); - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - else if (armflag & ARM_EDITMODE) { - BIF_ThemeColor(TH_WIRE); - } - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED)==0) { - if (G.f & G_PICKSEL) { // no bitmap in selection mode, crashes 3d cards... - glLoadName (id | BONESEL_ROOT); - glBegin(GL_POINTS); - glVertex3f(0.0f, 0.0f, 0.0f); - glEnd(); - } - else { - glRasterPos3f(0.0f, 0.0f, 0.0f); - glBitmap(8, 8, 4, 4, 0, 0, bm_dot8); - } - } - - if (id != -1) - glLoadName((GLuint) id|BONESEL_BONE); - - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, 1.0f, 0.0f); - glEnd(); - - /* tip */ - if (G.f & G_PICKSEL) { - /* no bitmap in selection mode, crashes 3d cards... */ - glLoadName(id | BONESEL_TIP); - glBegin(GL_POINTS); - glVertex3f(0.0f, 1.0f, 0.0f); - glEnd(); - } - else { - glRasterPos3f(0.0f, 1.0f, 0.0f); - glBitmap(8, 8, 4, 4, 0, 0, bm_dot7); - } - - /* further we send no names */ - if (id != -1) - glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */ - - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_LINEBONE, armflag, boneflag, constflag); - } - - glLineWidth(2.0); - - /*Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED)==0) { - if ((G.f & G_PICKSEL)==0) { - /* no bitmap in selection mode, crashes 3d cards... */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - glRasterPos3f(0.0f, 0.0f, 0.0f); - glBitmap(8, 8, 4, 4, 0, 0, bm_dot6); - } - } - - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT); - else BIF_ThemeColorShade(TH_BACK, -30); - } - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, 1.0f, 0.0f); - glEnd(); - - /* tip */ - if ((G.f & G_PICKSEL)==0) { - /* no bitmap in selection mode, crashes 3d cards... */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); - } - glRasterPos3f(0.0f, 1.0f, 0.0f); - glBitmap(8, 8, 4, 4, 0, 0, bm_dot5); - } - - glLineWidth(1.0); - - glPopMatrix(); -} - -static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) -{ - int segments= 0; - - if (pchan) - segments= pchan->bone->segments; - - if ((segments > 1) && (pchan)) { - float dlen= length/(float)segments; - Mat4 *bbone= b_bone_spline_setup(pchan, 0); - int a; - - for (a=0; a<segments; a++, bbone++) { - glPushMatrix(); - glMultMatrixf(bbone->mat); - if (dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth); - else drawcube_size(xwidth, dlen, zwidth); - glPopMatrix(); - } - } - else { - glPushMatrix(); - if (dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth); - else drawcube_size(xwidth, length, zwidth); - glPopMatrix(); - } -} - -static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) -{ - float xwidth, length, zwidth; - - if (pchan) { - xwidth= pchan->bone->xwidth; - length= pchan->bone->length; - zwidth= pchan->bone->zwidth; - } - else { - xwidth= ebone->xwidth; - length= ebone->length; - zwidth= ebone->zwidth; - } - - /* draw points only if... */ - if (armflag & ARM_EDITMODE) { - /* move to unitspace */ - glPushMatrix(); - glScalef(length, length, length); - draw_bone_points(dt, armflag, boneflag, id); - glPopMatrix(); - length*= 0.95f; // make vertices visible - } - - /* colors for modes */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - else - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); - } - else if (armflag & ARM_EDITMODE) { - if (dt==OB_WIRE) { - if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT); - else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20); - else BIF_ThemeColor(TH_WIRE); - } - else - BIF_ThemeColor(TH_BONE_SOLID); - } - - if (id != -1) { - glLoadName ((GLuint) id|BONESEL_BONE); - } - - /* set up solid drawing */ - if (dt > OB_WIRE) { - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_LIGHTING); - - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); - else - BIF_ThemeColor(TH_BONE_SOLID); - - draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth); - - /* disable solid drawing */ - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - } - else { - /* wire */ - if (armflag & ARM_POSEMODE) { - if (constflag) { - /* set constraint colors */ - if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) { - glEnable(GL_BLEND); - - draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - } - } - - draw_b_bone_boxes(OB_WIRE, pchan, xwidth, length, zwidth); - } -} - -static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length) -{ - - /* Draw a 3d octahedral bone, we use normalized space based on length, - for glDisplayLists */ - - glScalef(length, length, length); - - /* set up solid drawing */ - if (dt > OB_WIRE) { - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_LIGHTING); - BIF_ThemeColor(TH_BONE_SOLID); - } - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - else - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); - } - - - draw_bone_points(dt, armflag, boneflag, id); - - /* now draw the bone itself */ - if (id != -1) { - glLoadName((GLuint) id|BONESEL_BONE); - } - - /* wire? */ - if (dt <= OB_WIRE) { - /* colors */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT); - else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20); - else BIF_ThemeColor(TH_WIRE); - } - else if (armflag & ARM_POSEMODE) { - if (constflag) { - /* draw constraint colors */ - if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) { - glEnable(GL_BLEND); - - draw_bone_solid_octahedral(); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag); - } - } - draw_bone_octahedral(); - } - else { - /* solid */ - if (armflag & ARM_POSEMODE) - set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag); - else - BIF_ThemeColor(TH_BONE_SOLID); - draw_bone_solid_octahedral(); - } - - /* disable solid drawing */ - if (dt > OB_WIRE) { - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - } -} - -static void draw_custom_bone(Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length) -{ - if(ob==NULL) return; - - glScalef(length, length, length); - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, 0); - } - - if (id != -1) { - glLoadName((GLuint) id|BONESEL_BONE); - } - - draw_object_instance(ob, dt, armflag & ARM_POSEMODE); -} - - -static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) -{ - bConstraint *con; - bPoseChannel *parchan; - - for (con= pchan->constraints.first; con; con= con->next) { - if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) { - bKinematicConstraint *data = (bKinematicConstraint*)con->data; - int segcount= 0; - - /* if only_temp, only draw if it is a temporary ik-chain */ - if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP)) - continue; - - setlinestyle(3); - glBegin(GL_LINES); - - /* exclude tip from chain? */ - if ((data->flag & CONSTRAINT_IK_TIP)==0) - parchan= pchan->parent; - else - parchan= pchan; - - glVertex3fv(parchan->pose_tail); - - /* Find the chain's root */ - while (parchan->parent) { - segcount++; - if(segcount==data->rootbone || segcount>255) break; // 255 is weak - parchan= parchan->parent; - } - if (parchan) - glVertex3fv(parchan->pose_head); - - glEnd(); - setlinestyle(0); - } - } -} - -static void bgl_sphere_project(float ax, float az) -{ - float dir[3], sine, q3; - - sine= 1.0f-ax*ax-az*az; - q3= (sine < 0.0f)? 0.0f: 2.0f*sqrt(sine); - - dir[0]= -az*q3; - dir[1]= 1.0f-2.0f*sine; - dir[2]= ax*q3; - - glVertex3fv(dir); -} - -static void draw_dof_ellipse(float ax, float az) -{ - static float staticSine[16] = { - 0.0, 0.104528463268, 0.207911690818, 0.309016994375, - 0.406736643076, 0.5, 0.587785252292, 0.669130606359, - 0.743144825477, 0.809016994375, 0.866025403784, - 0.913545457643, 0.951056516295, 0.978147600734, - 0.994521895368, 1.0 - }; - - int i, j, n=16; - float x, z, px, pz; - - glEnable(GL_BLEND); - glDepthMask(0); - - glColor4ub(70, 70, 70, 50); - - glBegin(GL_QUADS); - pz= 0.0f; - for(i=1; i<n; i++) { - z= staticSine[i]; - - px= 0.0f; - for(j=1; j<n-i+1; j++) { - x = staticSine[j]; - - if(j == n-i) { - glEnd(); - glBegin(GL_TRIANGLES); - bgl_sphere_project(ax*px, az*z); - bgl_sphere_project(ax*px, az*pz); - bgl_sphere_project(ax*x, az*pz); - glEnd(); - glBegin(GL_QUADS); - } - else { - bgl_sphere_project(ax*x, az*z); - bgl_sphere_project(ax*x, az*pz); - bgl_sphere_project(ax*px, az*pz); - bgl_sphere_project(ax*px, az*z); - } - - px= x; - } - pz= z; - } - glEnd(); - - glDisable(GL_BLEND); - glDepthMask(1); - - glColor3ub(0, 0, 0); - - glBegin(GL_LINE_STRIP); - for (i=0; i<n; i++) - bgl_sphere_project(staticSine[n-i-1]*ax, staticSine[i]*az); - glEnd(); -} - -static void draw_pose_dofs(Object *ob) -{ - bArmature *arm= ob->data; - bPoseChannel *pchan; - Bone *bone; - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - - if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { - if (bone->flag & BONE_SELECTED) { - if (bone->layer & arm->layer) { - if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) { - if (pose_channel_in_IK_chain(ob, pchan)) { - float corner[4][3], posetrans[3], mat[4][4]; - float phi=0.0f, theta=0.0f, scale; - int a, i; - - /* in parent-bone pose, but own restspace */ - glPushMatrix(); - - VECCOPY(posetrans, pchan->pose_mat[3]); - glTranslatef(posetrans[0], posetrans[1], posetrans[2]); - - if (pchan->parent) { - Mat4CpyMat4(mat, pchan->parent->pose_mat); - mat[3][0]= mat[3][1]= mat[3][2]= 0.0f; - glMultMatrixf(mat); - } - - Mat4CpyMat3(mat, pchan->bone->bone_mat); - glMultMatrixf(mat); - - scale= bone->length*pchan->size[1]; - glScalef(scale, scale, scale); - - if (pchan->ikflag & BONE_IK_XLIMIT) { - if (pchan->ikflag & BONE_IK_ZLIMIT) { - float amin[3], amax[3]; - - for (i=0; i<3; i++) { - amin[i]= sin(pchan->limitmin[i]*M_PI/360.0); - amax[i]= sin(pchan->limitmax[i]*M_PI/360.0); - } - - glScalef(1.0, -1.0, 1.0); - if (amin[0] != 0.0 && amin[2] != 0.0) - draw_dof_ellipse(amin[0], amin[2]); - if (amin[0] != 0.0 && amax[2] != 0.0) - draw_dof_ellipse(amin[0], amax[2]); - if (amax[0] != 0.0 && amin[2] != 0.0) - draw_dof_ellipse(amax[0], amin[2]); - if (amax[0] != 0.0 && amax[2] != 0.0) - draw_dof_ellipse(amax[0], amax[2]); - glScalef(1.0, -1.0, 1.0); - } - } - - /* arcs */ - if (pchan->ikflag & BONE_IK_ZLIMIT) { - theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]); - glRotatef(theta, 0.0f, 0.0f, 1.0f); - - glColor3ub(50, 50, 255); // blue, Z axis limit - glBegin(GL_LINE_STRIP); - for (a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f; - phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]); - - i= (a == -16) ? 0 : 1; - corner[i][0]= sin(phi); - corner[i][1]= cos(phi); - corner[i][2]= 0.0f; - glVertex3fv(corner[i]); - } - glEnd(); - - glRotatef(-theta, 0.0f, 0.0f, 1.0f); - } - - if (pchan->ikflag & BONE_IK_XLIMIT) { - theta= 0.5*(pchan->limitmin[0]+pchan->limitmax[0]); - glRotatef(theta, 1.0f, 0.0f, 0.0f); - - glColor3ub(255, 50, 50); // Red, X axis limit - glBegin(GL_LINE_STRIP); - for (a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f; - phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]); - - i= (a == -16) ? 2 : 3; - corner[i][0]= 0.0f; - corner[i][1]= sin(phi); - corner[i][2]= cos(phi); - glVertex3fv(corner[i]); - } - glEnd(); - - glRotatef(-theta, 1.0f, 0.0f, 0.0f); - } - - /* out of cone, out of bone */ - glPopMatrix(); - } - } - } - } - } - } -} - -/* assumes object is Armature with pose */ -static void draw_pose_channels(Base *base, int dt) -{ - Object *ob= base->object; - bArmature *arm= ob->data; - bPoseChannel *pchan; - Bone *bone; - GLfloat tmp; - float smat[4][4], imat[4][4]; - int index= -1; - short do_dashed= 3, draw_wire= 0; - short flag, constflag; - - /* hacky... prevent outline select from drawing dashed helplines */ - glGetFloatv(GL_LINE_WIDTH, &tmp); - if (tmp > 1.1) do_dashed &= ~1; - if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed &= ~2; - - /* precalc inverse matrix for drawing screen aligned */ - if (arm->drawtype==ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - mygetmatrix(smat); - Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0])); - Mat4Invert(imat, smat); - - /* and draw blended distances */ - if (arm->flag & ARM_POSEMODE) { - glEnable(GL_BLEND); - //glShadeModel(GL_SMOOTH); - - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) { - if (bone->flag & (BONE_SELECTED)) { - if (bone->layer & arm->layer) - draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL); - } - } - } - - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - //glShadeModel(GL_FLAT); - } - } - - /* little speedup, also make sure transparent only draws once */ - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - - /* if solid we draw that first, with selection codes, but without names, axes etc */ - if (dt > OB_WIRE) { - if (arm->flag & ARM_POSEMODE) - index= base->selcol; - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - - if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) { - if (bone->layer & arm->layer) { - glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - - /* catch exception for bone with hidden parent */ - flag= bone->flag; - if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) - flag &= ~BONE_CONNECTED; - - /* set color-set to use */ - set_pchan_colorset(ob, pchan); - - if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { - /* if drawwire, don't try to draw in solid */ - if (pchan->bone->flag & BONE_DRAWWIRE) - draw_wire= 1; - else - draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length); - } - else if (arm->drawtype==ARM_LINE) - ; /* nothing in solid */ - else if (arm->drawtype==ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - else if (arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - else - draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); - - glPopMatrix(); - } - } - - if (index!= -1) - index+= 0x10000; // pose bones count in higher 2 bytes only - } - - /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet, - * stick bones and/or wire custom-shapes are drawn in next loop - */ - if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) { - /* object tag, for bordersel optim */ - glLoadName(index & 0xFFFF); - index= -1; - } - } - - /* draw custom bone shapes as wireframes */ - if ( !(arm->flag & ARM_NO_CUSTOM) && - ((draw_wire) || (dt <= OB_WIRE)) ) - { - if (arm->flag & ARM_POSEMODE) - index= base->selcol; - - /* only draw custom bone shapes that need to be drawn as wires */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - - if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { - if (bone->layer & arm->layer) { - if (pchan->custom) { - if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) { - glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - - /* prepare colors */ - if (arm->flag & ARM_POSEMODE) - set_pchan_colorset(ob, pchan); - else { - if ((G.scene->basact)==base) { - if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_ACTIVE); - else BIF_ThemeColor(TH_WIRE); - } - else { - if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_SELECT); - else BIF_ThemeColor(TH_WIRE); - } - } - - /* catch exception for bone with hidden parent */ - flag= bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - draw_custom_bone(pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length); - - glPopMatrix(); - } - } - } - } - - if (index != -1) - index+= 0x10000; // pose bones count in higher 2 bytes only - } - - if (draw_wire) { - /* object tag, for bordersel optim */ - glLoadName(index & 0xFFFF); - index= -1; - } - } - - /* wire draw over solid only in posemode */ - if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) { - /* draw line check first. we do selection indices */ - if (arm->drawtype==ARM_LINE) { - if (arm->flag & ARM_POSEMODE) - index= base->selcol; - } - /* if solid && posemode, we draw again with polygonoffset */ - else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) { - bglPolygonOffset(1.0); - } - else { - /* and we use selection indices if not done yet */ - if (arm->flag & ARM_POSEMODE) - index= base->selcol; - } - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; - - if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) { - if (bone->layer & arm->layer) { - if ((do_dashed & 1) && (bone->parent)) { - /* Draw a line from our root to the parent's tip - * - only if V3D_HIDE_HELPLINES is enabled... - */ - if ( (do_dashed & 2) && ((bone->flag & BONE_CONNECTED)==0) ) { - if (arm->flag & ARM_POSEMODE) { - glLoadName(index & 0xFFFF); // object tag, for bordersel optim - BIF_ThemeColor(TH_WIRE); - } - setlinestyle(3); - glBegin(GL_LINES); - glVertex3fv(pchan->pose_head); - glVertex3fv(pchan->parent->pose_tail); - glEnd(); - setlinestyle(0); - } - - /* Draw a line to IK root bone - * - only if temporary chain (i.e. "autoik") - */ - if (arm->flag & ARM_POSEMODE) { - if (pchan->constflag & PCHAN_HAS_IK) { - if (bone->flag & BONE_SELECTED) { - if (pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0); - else glColor3ub(200, 200, 50); // add theme! - - glLoadName(index & 0xFFFF); - pchan_draw_IK_root_lines(pchan, !(do_dashed & 2)); - } - } - } - } - - glPushMatrix(); - if (arm->drawtype != ARM_ENVELOPE) - glMultMatrixf(pchan->pose_mat); - - /* catch exception for bone with hidden parent */ - flag= bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - /* extra draw service for pose mode */ - constflag= pchan->constflag; - if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) - constflag |= PCHAN_HAS_ACTION; - if (pchan->flag & POSE_STRIDE) - constflag |= PCHAN_HAS_STRIDE; - - /* set color-set to use */ - set_pchan_colorset(ob, pchan); - - if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) - ; // custom bone shapes should not be drawn here! - else if (arm->drawtype==ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL); - } - else if (arm->drawtype==ARM_LINE) - draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); - else if (arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); - else - draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); - - glPopMatrix(); - } - } - - /* pose bones count in higher 2 bytes only */ - if (index != -1) - index+= 0x10000; - } - /* restore things */ - if ((arm->drawtype!=ARM_LINE)&& (dt>OB_WIRE) && (arm->flag & ARM_POSEMODE)) - bglPolygonOffset(0.0); - } - - /* restore */ - glDisable(GL_CULL_FACE); - - /* draw DoFs */ - if (arm->flag & ARM_POSEMODE) - draw_pose_dofs(ob); - - /* finally names and axes */ - if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) { - /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - if ((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) { - if (pchan->bone->layer & arm->layer) { - if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) { - bone= pchan->bone; - - if (bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); - else BIF_ThemeColor(TH_TEXT); - } - else if (dt > OB_WIRE) - BIF_ThemeColor(TH_TEXT); - - /* Draw names of bone */ - if (arm->flag & ARM_DRAWNAMES) { - VecMidf(vec, pchan->pose_head, pchan->pose_tail); - glRasterPos3fv(vec); - BMF_DrawString(G.font, " "); - BMF_DrawString(G.font, pchan->name); - } - - /* Draw additional axes on the bone tail */ - if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) { - glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - glTranslatef(0.0f, pchan->bone->length, 0.0f); - drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS); - glPopMatrix(); - } - } - } - } - - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - } - } -} - -/* in editmode, we don't store the bone matrix... */ -static void set_matrix_editbone(EditBone *eBone) -{ - float delta[3],offset[3]; - float mat[3][3], bmat[4][4]; - - /* Compose the parent transforms (i.e. their translations) */ - VECCOPY(offset, eBone->head); - - glTranslatef(offset[0],offset[1],offset[2]); - - VecSubf(delta, eBone->tail, eBone->head); - - eBone->length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); - - vec_roll_to_mat3(delta, eBone->roll, mat); - Mat4CpyMat3(bmat, mat); - - glMultMatrixf(bmat); - -} - -static void draw_ebones(Object *ob, int dt) -{ - EditBone *eBone; - bArmature *arm= ob->data; - float smat[4][4], imat[4][4]; - unsigned int index; - int flag; - - /* envelope (deform distance) */ - if(arm->drawtype==ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - mygetmatrix(smat); - Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0])); - Mat4Invert(imat, smat); - - /* and draw blended distances */ - glEnable(GL_BLEND); - //glShadeModel(GL_SMOOTH); - - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) { - if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL)) - draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone); - } - } - } - - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - //glShadeModel(GL_FLAT); - } - - /* if solid we draw it first */ - if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) { - index= 0; - for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A)==0) { - glPushMatrix(); - set_matrix_editbone(eBone); - - /* catch exception for bone with hidden parent */ - flag= eBone->flag; - if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) - flag &= ~BONE_CONNECTED; - - if (arm->drawtype==ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if(arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); - } - - glPopMatrix(); - } - } - } - } - - /* if wire over solid, set offset */ - index= -1; - glLoadName(-1); - if (arm->drawtype==ARM_LINE) { - if(G.f & G_PICKSEL) - index= 0; - } - else if (dt > OB_WIRE) - bglPolygonOffset(1.0); - else if (arm->flag & ARM_EDITMODE) - index= 0; /* do selection codes */ - - for (eBone=G.edbo.first; eBone; eBone=eBone->next) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A)==0) { - - /* catch exception for bone with hidden parent */ - flag= eBone->flag; - if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) - flag &= ~BONE_CONNECTED; - - if (arm->drawtype == ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone); - } - else { - glPushMatrix(); - set_matrix_editbone(eBone); - - if (arm->drawtype == ARM_LINE) - draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else - draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); - - glPopMatrix(); - } - - /* offset to parent */ - if (eBone->parent) { - BIF_ThemeColor(TH_WIRE); - glLoadName (-1); // -1 here is OK! - setlinestyle(3); - - glBegin(GL_LINES); - glVertex3fv(eBone->parent->tail); - glVertex3fv(eBone->head); - glEnd(); - - setlinestyle(0); - } - } - } - if(index!=-1) index++; - } - - /* restore */ - if (arm->drawtype==ARM_LINE); - else if (dt>OB_WIRE) bglPolygonOffset(0.0); - - /* finally names and axes */ - if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) { - // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) { - if(eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A)==0) { - - if (eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); - else BIF_ThemeColor(TH_TEXT); - - /* Draw name */ - if (arm->flag & ARM_DRAWNAMES) { - VecMidf(vec, eBone->head, eBone->tail); - glRasterPos3fv(vec); - BMF_DrawString(G.font, " "); - BMF_DrawString(G.font, eBone->name); - } - /* Draw additional axes */ - if (arm->flag & ARM_DRAWAXES) { - glPushMatrix(); - set_matrix_editbone(eBone); - glTranslatef(0.0f, eBone->length, 0.0f); - drawaxes(eBone->length*0.25f, 0, OB_ARROWS); - glPopMatrix(); - } - - } - } - } - - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - } - } -} - -/* ****************************** Armature Visualisation ******************************** */ - -/* ---------- Paths --------- */ - -/* draw bone paths - * - in view space - */ -static void draw_pose_paths(Object *ob) -{ - bArmature *arm= ob->data; - bPoseChannel *pchan; - bAction *act; - bActionChannel *achan; - ActKeyColumn *ak; - ListBase keys; - float *fp, *fp_start; - int a, stepsize; - int sfra, efra, len; - - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - glPushMatrix(); - glLoadMatrixf(G.vd->viewmat); - - /* version patch here - cannot access frame info from file reading */ - if (arm->pathsize == 0) arm->pathsize= 1; - stepsize = arm->pathsize; - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if (pchan->bone->layer & arm->layer) { - if (pchan->path) { - /* version patch here - cannot access frame info from file reading */ - if ((pchan->pathsf == 0) || (pchan->pathef == 0)) { - pchan->pathsf= SFRA; - pchan->pathef= EFRA; - } - - /* get frame ranges */ - if (arm->pathflag & ARM_PATH_ACFRA) { - int sind; - - /* With "Around Current", we only choose frames from around - * the current frame to draw. However, this range is still - * restricted by the limits of the original path. - */ - sfra= CFRA - arm->pathbc; - efra= CFRA + arm->pathac; - if (sfra < pchan->pathsf) sfra= pchan->pathsf; - if (efra > pchan->pathef) efra= pchan->pathef; - - len= efra - sfra; - - sind= sfra - pchan->pathsf; - fp_start= (pchan->path + (3*sind)); - } - else { - sfra= pchan->pathsf; - efra = sfra + pchan->pathlen; - len = pchan->pathlen; - fp_start = pchan->path; - } - - /* draw curve-line of path */ - glShadeModel(GL_SMOOTH); - - glBegin(GL_LINE_STRIP); - for (a=0, fp=fp_start; a<len; a++, fp+=3) { - float intensity; /* how faint */ - - /* set color - * - 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.68f, 0.92f); - } - 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.68f, 0.92f); - } - BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity); - } - else { - /* green - on cfra */ - if (pchan->bone->flag & BONE_SELECTED) { - intensity= 0.5; - } - else { - intensity= 0.99; - } - BIF_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10); - } - - /* draw a vertex with this color */ - glVertex3fv(fp); - } - - glEnd(); - glShadeModel(GL_FLAT); - - glPointSize(1.0); - - /* draw little black point at each frame - * NOTE: this is not really visible/noticable - */ - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a++, fp+=3) - glVertex3fv(fp); - glEnd(); - - /* Draw little white dots at each framestep value */ - BIF_ThemeColor(TH_TEXT_HI); - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) - glVertex3fv(fp); - glEnd(); - - /* Draw frame numbers at each framestep value */ - if (arm->pathflag & ARM_PATH_FNUMS) { - for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) { - char str[32]; - - /* only draw framenum if several consecutive highlighted points don't occur on same point */ - if (a == 0) { - glRasterPos3fv(fp); - sprintf(str, " %d\n", (a+sfra)); - BMF_DrawString(G.font, str); - } - else if ((a > stepsize) && (a < len-stepsize)) { - if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) { - glRasterPos3fv(fp); - sprintf(str, " %d\n", (a+sfra)); - BMF_DrawString(G.font, str); - } - } - } - } - - /* Keyframes - dots and numbers */ - if (arm->pathflag & ARM_PATH_KFRAS) { - /* build list of all keyframes in active action for pchan */ - keys.first = keys.last = NULL; - act= ob_get_action(ob); - if (act) { - achan= get_action_channel(act, pchan->name); - if (achan) - ipo_to_keylist(achan->ipo, &keys, NULL, NULL); - } - - /* Draw slightly-larger yellow dots at each keyframe */ - BIF_ThemeColor(TH_VERTEX_SELECT); - glPointSize(5.0); - - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a++, fp+=3) { - for (ak= keys.first; ak; ak= ak->next) { - if (ak->cfra == (a+sfra)) - glVertex3fv(fp); - } - } - glEnd(); - - glPointSize(1.0); - - /* Draw frame numbers of keyframes */ - if ((arm->pathflag & ARM_PATH_FNUMS) || (arm->pathflag & ARM_PATH_KFNOS)) { - for(a=0, fp=fp_start; a<len; a++, fp+=3) { - for (ak= keys.first; ak; ak= ak->next) { - if (ak->cfra == (a+sfra)) { - char str[32]; - - glRasterPos3fv(fp); - sprintf(str, " %d\n", (a+sfra)); - BMF_DrawString(G.font, str); - } - } - } - } - - BLI_freelistN(&keys); - } - } - } - } - - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - glPopMatrix(); -} - - -/* ---------- Ghosts --------- */ - -/* helper function for ghost drawing - sets/removes flags for temporarily - * hiding unselected bones while drawing ghosts - */ -static void ghost_poses_tag_unselected(Object *ob, short unset) -{ - bArmature *arm= ob->data; - bPose *pose= ob->pose; - bPoseChannel *pchan; - - /* don't do anything if no hiding any bones */ - if ((arm->flag & ARM_GHOST_ONLYSEL)==0) - return; - - /* loop over all pchans, adding/removing tags as appropriate */ - for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (unset) { - /* remove tags from all pchans if cleaning up */ - pchan->bone->flag &= ~BONE_HIDDEN_PG; - } - else { - /* set tags on unselected pchans only */ - if ((pchan->bone->flag & BONE_SELECTED)==0) - pchan->bone->flag |= BONE_HIDDEN_PG; - } - } - } -} - -/* draw ghosts that occur within a frame range - * note: object should be in posemode - */ -static void draw_ghost_poses_range(Base *base) -{ - Object *ob= base->object; - bArmature *arm= ob->data; - bPose *posen, *poseo; - float start, end, stepsize, range, colfac; - int cfrao, flago, ipoflago; - - start = arm->ghostsf; - end = arm->ghostef; - if (end <= start) - return; - - stepsize= (float)(arm->ghostsize); - range= (float)(end - start); - - /* store values */ - ob->flag &= ~OB_POSEMODE; - cfrao= CFRA; - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - ipoflago= ob->ipoflag; - ob->ipoflag |= OB_DISABLE_PATH; - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (CFRA= start; CFRA<end; CFRA+=stepsize) { - colfac = (end-CFRA)/range; - BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac))); - - do_all_pose_actions(ob); - where_is_pose(ob); - draw_pose_channels(base, OB_WIRE); - } - glDisable(GL_BLEND); - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->flag |= OB_POSEMODE; - ob->ipoflag= ipoflago; -} - -/* draw ghosts on keyframes in action within range - * - object should be in posemode - */ -static void draw_ghost_poses_keys(Base *base) -{ - Object *ob= base->object; - bAction *act= ob_get_action(ob); - bArmature *arm= ob->data; - bPose *posen, *poseo; - ListBase keys= {NULL, NULL}; - ActKeysInc aki = {0, 0, 0}; - ActKeyColumn *ak, *akn; - float start, end, range, colfac, i; - int cfrao, flago, ipoflago; - - aki.start= start = arm->ghostsf; - aki.end= end = arm->ghostef; - if (end <= start) - return; - - /* get keyframes - then clip to only within range */ - action_to_keylist(act, &keys, NULL, &aki); - range= 0; - for (ak= keys.first; ak; ak= akn) { - akn= ak->next; - - if ((ak->cfra < start) || (ak->cfra > end)) - BLI_freelinkN(&keys, ak); - else - range++; - } - if (range == 0) return; - - /* store values */ - ob->flag &= ~OB_POSEMODE; - cfrao= CFRA; - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - ipoflago= ob->ipoflag; - ob->ipoflag |= OB_DISABLE_PATH; - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (ak=keys.first, i=0; ak; ak=ak->next, i++) { - colfac = i/range; - BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac))); - - CFRA= (int)ak->cfra; - - do_all_pose_actions(ob); - where_is_pose(ob); - draw_pose_channels(base, OB_WIRE); - } - glDisable(GL_BLEND); - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BLI_freelistN(&keys); - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->flag |= OB_POSEMODE; - ob->ipoflag= ipoflago; -} - -/* draw ghosts around current frame - * - object is supposed to be armature in posemode - */ -static void draw_ghost_poses(Base *base) -{ - Object *ob= base->object; - bArmature *arm= ob->data; - bPose *posen, *poseo; - bActionStrip *strip; - float cur, start, end, stepsize, range, colfac, actframe, ctime; - int cfrao, maptime, flago, ipoflago; - - /* pre conditions, get an action with sufficient frames */ - if (ob->action==NULL) - return; - - calc_action_range(ob->action, &start, &end, 0); - if (start == end) - return; - - stepsize= (float)(arm->ghostsize); - range= (float)(arm->ghostep)*stepsize + 0.5f; /* plus half to make the for loop end correct */ - - /* we only map time for armature when an active strip exists */ - for (strip=ob->nlastrips.first; strip; strip=strip->next) - if (strip->flag & ACTSTRIP_ACTIVE) - break; - - maptime= (strip!=NULL); - - /* store values */ - ob->flag &= ~OB_POSEMODE; - cfrao= CFRA; - if (maptime) actframe= get_action_frame(ob, (float)CFRA); - else actframe= CFRA; - flago= arm->flag; - arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES); - ipoflago= ob->ipoflag; - ob->ipoflag |= OB_DISABLE_PATH; - - /* copy the pose */ - poseo= ob->pose; - copy_pose(&posen, ob->pose, 1); - ob->pose= posen; - armature_rebuild_pose(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (G.vd->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from darkest blend to lowest */ - for(cur= stepsize; cur<range; cur+=stepsize) { - ctime= cur - fmod((float)cfrao, stepsize); /* ensures consistant stepping */ - colfac= ctime/range; - BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac))); - - /* only within action range */ - if (actframe+ctime >= start && actframe+ctime <= end) { - if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe+ctime); - else CFRA= (int)floor(actframe+ctime); - - if (CFRA!=cfrao) { - do_all_pose_actions(ob); - where_is_pose(ob); - draw_pose_channels(base, OB_WIRE); - } - } - - ctime= cur + fmod((float)cfrao, stepsize) - stepsize+1.0f; /* ensures consistant stepping */ - colfac= ctime/range; - BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac))); - - /* only within action range */ - if ((actframe-ctime >= start) && (actframe-ctime <= end)) { - if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe-ctime); - else CFRA= (int)floor(actframe-ctime); - - if (CFRA != cfrao) { - do_all_pose_actions(ob); - where_is_pose(ob); - draw_pose_channels(base, OB_WIRE); - } - } - } - glDisable(GL_BLEND); - if (G.vd->zbuf) glEnable(GL_DEPTH_TEST); - - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - free_pose(posen); - - /* restore */ - CFRA= cfrao; - ob->pose= poseo; - arm->flag= flago; - armature_rebuild_pose(ob, ob->data); - ob->flag |= OB_POSEMODE; - ob->ipoflag= ipoflago; -} - -/* ********************************** Armature Drawing - Main ************************* */ - -/* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Base *base, int dt, int flag) -{ - Object *ob= base->object; - bArmature *arm= ob->data; - int retval= 0; - - if(G.f & G_RENDER_SHADOW) - return 1; - - if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) { - /* we use color for solid lighting */ - glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); - glColor3ub(0,0,0); // clear spec - glDisable(GL_COLOR_MATERIAL); - - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting... - } - - /* arm->flag is being used to detect mode... */ - /* editmode? */ - if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { - if(ob==G.obedit) arm->flag |= ARM_EDITMODE; - draw_ebones(ob, dt); - arm->flag &= ~ARM_EDITMODE; - } - else{ - /* Draw Pose */ - if(ob->pose && ob->pose->chanbase.first) { - /* drawing posemode selection indices or colors only in these cases */ - if(!(base->flag & OB_FROMDUPLI)) { - if(G.f & G_PICKSEL) { - if(ob->flag & OB_POSEMODE) - arm->flag |= ARM_POSEMODE; - } - else if(ob->flag & OB_POSEMODE) { - if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(base); - } - else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(base); - } - else if (arm->ghosttype == ARM_GHOST_CUR) { - if (arm->ghostep) - draw_ghost_poses(base); - } - if ((flag & DRAW_SCENESET)==0) { - if(ob==OBACT) - arm->flag |= ARM_POSEMODE; - else if(G.f & G_WEIGHTPAINT) - arm->flag |= ARM_POSEMODE; - - draw_pose_paths(ob); - } - } - } - draw_pose_channels(base, dt); - arm->flag &= ~ARM_POSEMODE; - - if(ob->flag & OB_POSEMODE) - BIF_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */ - } - else retval= 1; - } - /* restore */ - glFrontFace(GL_CCW); - - return retval; -} - -/* *************** END Armature drawing ******************* */ - - |