~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/blender/src/drawarmature.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: drawarmature.c 16902 2008-10-03 19:34:49Z blendix $
 
3
 *
 
4
 * ***** BEGIN GPL LICENSE BLOCK *****
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version. 
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software Foundation,
 
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 *
 
20
 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
 
21
 * All rights reserved.
 
22
 *
 
23
 * The Original Code is: all of this file.
 
24
 *
 
25
 * Contributor(s): none yet.
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
 */
 
29
 
 
30
#include <stdlib.h>
 
31
#include <string.h>
 
32
#include <math.h>
 
33
 
 
34
#ifdef HAVE_CONFIG_H
 
35
#include <config.h>
 
36
#endif
 
37
 
 
38
#include "MEM_guardedalloc.h"
 
39
 
 
40
#include "BMF_Api.h"
 
41
 
 
42
#include "DNA_action_types.h"
 
43
#include "DNA_armature_types.h"
 
44
#include "DNA_constraint_types.h"
 
45
#include "DNA_ID.h"
 
46
#include "DNA_nla_types.h"
 
47
#include "DNA_object_types.h"
 
48
#include "DNA_scene_types.h"
 
49
#include "DNA_screen_types.h"
 
50
#include "DNA_space_types.h"
 
51
#include "DNA_view3d_types.h"
 
52
#include "DNA_userdef_types.h"
 
53
 
 
54
#include "BLI_blenlib.h"
 
55
#include "BLI_arithb.h"
 
56
 
 
57
#include "BKE_action.h"
 
58
#include "BKE_armature.h"
 
59
#include "BKE_constraint.h"
 
60
#include "BKE_depsgraph.h"
 
61
#include "BKE_DerivedMesh.h"
 
62
#include "BKE_global.h"
 
63
#include "BKE_main.h"
 
64
#include "BKE_object.h"
 
65
#include "BKE_ipo.h"
 
66
#include "BKE_utildefines.h"
 
67
 
 
68
#include "BIF_editaction.h"
 
69
#include "BIF_editarmature.h"
 
70
#include "BIF_gl.h"
 
71
#include "BIF_glutil.h"
 
72
#include "BIF_graphics.h"
 
73
#include "BIF_interface.h"
 
74
#include "BIF_poseobject.h"
 
75
#include "BIF_mywindow.h"
 
76
#include "BIF_resources.h"
 
77
#include "BIF_screen.h"
 
78
 
 
79
#include "BDR_editobject.h"
 
80
#include "BDR_drawobject.h"
 
81
#include "BDR_drawaction.h"
 
82
 
 
83
#include "BSE_edit.h"
 
84
#include "BSE_view.h"
 
85
 
 
86
#include "mydevice.h"
 
87
#include "blendef.h"
 
88
#include "nla.h"
 
89
 
 
90
 
 
91
/* *************** Armature Drawing - Coloring API ***************************** */
 
92
 
 
93
/* global here is reset before drawing each bone */
 
94
static ThemeWireColor *bcolor= NULL;
 
95
 
 
96
/* values of colCode for set_pchan_glcolor */
 
97
enum {
 
98
        PCHAN_COLOR_NORMAL      = 0,            /* normal drawing */
 
99
        PCHAN_COLOR_SOLID,                              /* specific case where "solid" color is needed */
 
100
        PCHAN_COLOR_CONSTS,                             /* "constraint" colors (which may/may-not be suppressed) */
 
101
        
 
102
        PCHAN_COLOR_SPHEREBONE_BASE,    /* for the 'stick' of sphere (envelope) bones */
 
103
        PCHAN_COLOR_SPHEREBONE_END,             /* for the ends of sphere (envelope) bones */
 
104
        PCHAN_COLOR_LINEBONE                    /* for the middle of line-bones */
 
105
};      
 
106
 
 
107
/* This function sets the color-set for coloring a certain bone */
 
108
static void set_pchan_colorset (Object *ob, bPoseChannel *pchan)
 
109
{
 
110
        bPose *pose= (ob) ? ob->pose : NULL;
 
111
        bArmature *arm= (ob) ? ob->data : NULL;
 
112
        bActionGroup *grp= NULL;
 
113
        short color_index= 0;
 
114
        
 
115
        /* sanity check */
 
116
        if (ELEM4(NULL, ob, arm, pose, pchan)) {
 
117
                bcolor= NULL;
 
118
                return;
 
119
        }
 
120
        
 
121
        /* only try to set custom color if enabled for armature */
 
122
        if (arm->flag & ARM_COL_CUSTOM) {       
 
123
                /* currently, a bone can only use a custom color set if it's group (if it has one),
 
124
                 * has been set to use one
 
125
                 */
 
126
                if (pchan->agrp_index) {
 
127
                        grp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
 
128
                        if (grp)
 
129
                                color_index= grp->customCol;
 
130
                }
 
131
        }
 
132
        
 
133
        /* bcolor is a pointer to the color set to use. If NULL, then the default
 
134
         * color set (based on the theme colors for 3d-view) is used. 
 
135
         */
 
136
        if (color_index > 0) {
 
137
                bTheme *btheme= U.themes.first;
 
138
                bcolor= &btheme->tarm[(color_index - 1)];
 
139
        }
 
140
        else if (color_index == -1) {
 
141
                /* use the group's own custom color set */
 
142
                bcolor= (grp)? &grp->cs : NULL;
 
143
        }
 
144
        else 
 
145
                bcolor= NULL;
 
146
}
 
147
 
 
148
/* This function is for brightening/darkening a given color (like BIF_ThemeColorShade()) */
 
149
static void cp_shade_color3ub (char cp[], int offset)
 
150
{
 
151
        int r, g, b;
 
152
        
 
153
        r= offset + (int) cp[0];
 
154
        CLAMP(r, 0, 255);
 
155
        g= offset + (int) cp[1];
 
156
        CLAMP(g, 0, 255);
 
157
        b= offset + (int) cp[2];
 
158
        CLAMP(b, 0, 255);
 
159
        
 
160
        cp[0]= r;
 
161
        cp[1]= g;
 
162
        cp[2]= b;
 
163
}
 
164
 
 
165
/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
 
166
static short set_pchan_glColor (short colCode, int armflag, int boneflag, int constflag)
 
167
{
 
168
        switch (colCode) {
 
169
        case PCHAN_COLOR_NORMAL:
 
170
        {
 
171
                if (bcolor) {
 
172
                        char cp[3];
 
173
                        
 
174
                        if (boneflag & BONE_ACTIVE) {
 
175
                                VECCOPY(cp, bcolor->active);
 
176
                        }
 
177
                        else if (boneflag & BONE_SELECTED) {
 
178
                                VECCOPY(cp, bcolor->select);
 
179
                        }
 
180
                        else {
 
181
                                /* a bit darker than solid */
 
182
                                VECCOPY(cp, bcolor->solid);
 
183
                                cp_shade_color3ub(cp, -50);
 
184
                        }
 
185
                        
 
186
                        glColor3ub(cp[0], cp[1], cp[2]);
 
187
                }
 
188
                else {
 
189
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
 
190
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
 
191
                        else BIF_ThemeColor(TH_WIRE);
 
192
                }
 
193
                
 
194
                return 1;
 
195
        }
 
196
                break;
 
197
        
 
198
        case PCHAN_COLOR_SOLID:
 
199
        {
 
200
                if (bcolor) {
 
201
                        char *cp= bcolor->solid;
 
202
                        glColor3ub(cp[0], cp[1], cp[2]);
 
203
                }
 
204
                else 
 
205
                        BIF_ThemeColor(TH_BONE_SOLID);
 
206
                        
 
207
                return 1;
 
208
        }
 
209
                break;
 
210
                
 
211
        case PCHAN_COLOR_CONSTS:
 
212
        {
 
213
                if ( (bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS) ) {
 
214
                        if (constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
 
215
                        else if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
 
216
                        else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
 
217
                        else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
 
218
                        else if (constflag) BIF_ThemeColor4(TH_BONE_POSE);      // PCHAN_HAS_ACTION 
 
219
                        
 
220
                        return 1;
 
221
                }
 
222
                else 
 
223
                        return 0;
 
224
        }
 
225
                break;
 
226
                
 
227
        case PCHAN_COLOR_SPHEREBONE_BASE:
 
228
        {
 
229
                if (bcolor) {
 
230
                        char cp[3];
 
231
                        
 
232
                        if (boneflag & BONE_ACTIVE) {
 
233
                                VECCOPY(cp, bcolor->active);
 
234
                        }
 
235
                        else if (boneflag & BONE_SELECTED) {
 
236
                                VECCOPY(cp, bcolor->select);
 
237
                        }
 
238
                        else {
 
239
                                VECCOPY(cp, bcolor->solid);
 
240
                        }
 
241
                        
 
242
                        glColor3ub(cp[0], cp[1], cp[2]);
 
243
                }
 
244
                else {
 
245
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
 
246
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
 
247
                        else BIF_ThemeColor(TH_BONE_SOLID);
 
248
                }
 
249
                
 
250
                return 1;
 
251
        }
 
252
                break;
 
253
        case PCHAN_COLOR_SPHEREBONE_END:
 
254
        {
 
255
                if (bcolor) {
 
256
                        char cp[3];
 
257
                        
 
258
                        if (boneflag & BONE_ACTIVE) {
 
259
                                VECCOPY(cp, bcolor->active);
 
260
                                cp_shade_color3ub(cp, 10);
 
261
                        }
 
262
                        else if (boneflag & BONE_SELECTED) {
 
263
                                VECCOPY(cp, bcolor->select);
 
264
                                cp_shade_color3ub(cp, -30);
 
265
                        }
 
266
                        else {
 
267
                                VECCOPY(cp, bcolor->solid);
 
268
                                cp_shade_color3ub(cp, -30);
 
269
                        }
 
270
                        
 
271
                        glColor3ub(cp[0], cp[1], cp[2]);
 
272
                }
 
273
                else {
 
274
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
 
275
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
 
276
                        else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
 
277
                }
 
278
        }
 
279
                break;
 
280
                
 
281
        case PCHAN_COLOR_LINEBONE:
 
282
        {
 
283
                /* inner part in background color or constraint */
 
284
                if ( (constflag) && ((bcolor==NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) ) {
 
285
                        if (constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
 
286
                        else if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
 
287
                        else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
 
288
                        else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
 
289
                        else if (constflag) BIF_ThemeColor(TH_BONE_POSE);       /* PCHAN_HAS_ACTION */ 
 
290
                }
 
291
                else {
 
292
                        if (bcolor) {
 
293
                                char *cp= bcolor->solid;
 
294
                                glColor4ub(cp[0], cp[1], cp[2], 0.8);   
 
295
                        }
 
296
                        else
 
297
                                BIF_ThemeColorShade(TH_BACK, -30);
 
298
                }
 
299
                
 
300
                return 1;
 
301
        }
 
302
                break;
 
303
        }
 
304
        
 
305
        return 0;
 
306
}
 
307
 
 
308
 
 
309
/* *************** Armature drawing, helper calls for parts ******************* */
 
310
 
 
311
/* half the cube, in Y */
 
312
static float cube[8][3] = {
 
313
{-1.0,  0.0, -1.0},
 
314
{-1.0,  0.0,  1.0},
 
315
{-1.0,  1.0,  1.0},
 
316
{-1.0,  1.0, -1.0},
 
317
{ 1.0,  0.0, -1.0},
 
318
{ 1.0,  0.0,  1.0},
 
319
{ 1.0,  1.0,  1.0},
 
320
{ 1.0,  1.0, -1.0},
 
321
};
 
322
 
 
323
static void drawsolidcube_size(float xsize, float ysize, float zsize)
 
324
{
 
325
        static GLuint displist=0;
 
326
        float n[3];
 
327
        
 
328
        glScalef(xsize, ysize, zsize);
 
329
        
 
330
        n[0]=0; n[1]=0; n[2]=0;
 
331
 
 
332
        if(displist==0) {
 
333
                displist= glGenLists(1);
 
334
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
335
 
 
336
                glBegin(GL_QUADS);
 
337
                n[0]= -1.0;
 
338
                glNormal3fv(n); 
 
339
                glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
 
340
                n[0]=0;
 
341
                n[1]= -1.0;
 
342
                glNormal3fv(n); 
 
343
                glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
 
344
                n[1]=0;
 
345
                n[0]= 1.0;
 
346
                glNormal3fv(n); 
 
347
                glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
 
348
                n[0]=0;
 
349
                n[1]= 1.0;
 
350
                glNormal3fv(n); 
 
351
                glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
 
352
                n[1]=0;
 
353
                n[2]= 1.0;
 
354
                glNormal3fv(n); 
 
355
                glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
 
356
                n[2]=0;
 
357
                n[2]= -1.0;
 
358
                glNormal3fv(n); 
 
359
                glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
 
360
                glEnd();
 
361
 
 
362
                glEndList();
 
363
        }
 
364
        else glCallList(displist);
 
365
        
 
366
}
 
367
 
 
368
static void drawcube_size(float xsize, float ysize, float zsize)
 
369
{
 
370
        static GLuint displist=0;
 
371
        
 
372
        glScalef(xsize, ysize, zsize);
 
373
        
 
374
        if(displist == 0) {
 
375
                displist= glGenLists(1);
 
376
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
377
                
 
378
                glBegin(GL_LINE_STRIP);
 
379
                glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
 
380
                glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
 
381
                glVertex3fv(cube[7]); glVertex3fv(cube[4]);
 
382
                glEnd();
 
383
                
 
384
                glBegin(GL_LINES);
 
385
                glVertex3fv(cube[1]); glVertex3fv(cube[5]);
 
386
                glVertex3fv(cube[2]); glVertex3fv(cube[6]);
 
387
                glVertex3fv(cube[3]); glVertex3fv(cube[7]);
 
388
                glEnd();
 
389
                
 
390
                glEndList();
 
391
        }
 
392
        else glCallList(displist);
 
393
        
 
394
}
 
395
 
 
396
 
 
397
static void draw_bonevert(void)
 
398
{
 
399
        static GLuint displist=0;
 
400
        
 
401
        if (displist == 0) {
 
402
                GLUquadricObj   *qobj;
 
403
                
 
404
                displist= glGenLists(1);
 
405
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
406
                        
 
407
                glPushMatrix();
 
408
                
 
409
                qobj    = gluNewQuadric(); 
 
410
                gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
 
411
                gluDisk(qobj, 0.0,  0.05, 16, 1);
 
412
                
 
413
                glRotatef(90, 0, 1, 0);
 
414
                gluDisk(qobj, 0.0,  0.05, 16, 1);
 
415
                
 
416
                glRotatef(90, 1, 0, 0);
 
417
                gluDisk(qobj, 0.0,  0.05, 16, 1);
 
418
                
 
419
                gluDeleteQuadric(qobj);  
 
420
                
 
421
                glPopMatrix();
 
422
                glEndList();
 
423
        }
 
424
        else 
 
425
                glCallList(displist);
 
426
}
 
427
 
 
428
static void draw_bonevert_solid(void)
 
429
{
 
430
        static GLuint displist=0;
 
431
        
 
432
        if (displist == 0) {
 
433
                GLUquadricObj   *qobj;
 
434
                
 
435
                displist= glGenLists(1);
 
436
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
437
                
 
438
                qobj    = gluNewQuadric();
 
439
                gluQuadricDrawStyle(qobj, GLU_FILL); 
 
440
                glShadeModel(GL_SMOOTH);
 
441
                gluSphere( qobj, 0.05, 8, 5);
 
442
                glShadeModel(GL_FLAT);
 
443
                gluDeleteQuadric(qobj);  
 
444
                
 
445
                glEndList();
 
446
        }
 
447
        else 
 
448
                glCallList(displist);
 
449
}
 
450
 
 
451
static void draw_bone_octahedral()
 
452
{
 
453
        static GLuint displist=0;
 
454
        
 
455
        if (displist == 0) {
 
456
                float vec[6][3];        
 
457
                
 
458
                displist= glGenLists(1);
 
459
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
460
                
 
461
                vec[0][0]= vec[0][1]= vec[0][2]= 0.0;
 
462
                vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0;
 
463
                
 
464
                vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1;
 
465
                vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1;
 
466
                vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1;
 
467
                vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1;
 
468
                
 
469
                /*      Section 1, sides */
 
470
                glBegin(GL_LINE_LOOP);
 
471
                glVertex3fv(vec[0]);
 
472
                glVertex3fv(vec[1]);
 
473
                glVertex3fv(vec[5]);
 
474
                glVertex3fv(vec[3]);
 
475
                glVertex3fv(vec[0]);
 
476
                glVertex3fv(vec[4]);
 
477
                glVertex3fv(vec[5]);
 
478
                glVertex3fv(vec[2]);
 
479
                glEnd();
 
480
                
 
481
                /*      Section 1, square */
 
482
                glBegin(GL_LINE_LOOP);
 
483
                glVertex3fv(vec[1]);
 
484
                glVertex3fv(vec[2]);
 
485
                glVertex3fv(vec[3]);
 
486
                glVertex3fv(vec[4]);
 
487
                glEnd();
 
488
                
 
489
                glEndList();
 
490
        }
 
491
        else 
 
492
                glCallList(displist);
 
493
}       
 
494
 
 
495
static void draw_bone_solid_octahedral(void)
 
496
{
 
497
        static GLuint displist=0;
 
498
        
 
499
        if (displist == 0) {
 
500
                float vec[6][3], nor[3];        
 
501
                
 
502
                displist= glGenLists(1);
 
503
                glNewList(displist, GL_COMPILE_AND_EXECUTE);
 
504
                
 
505
                vec[0][0]= vec[0][1]= vec[0][2]= 0.0;
 
506
                vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0;
 
507
                
 
508
                vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1;
 
509
                vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1;
 
510
                vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1;
 
511
                vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1;
 
512
                
 
513
                
 
514
                glBegin(GL_TRIANGLES);
 
515
                /* bottom */
 
516
                CalcNormFloat(vec[2], vec[1], vec[0], nor);
 
517
                glNormal3fv(nor);
 
518
                glVertex3fv(vec[2]);glVertex3fv(vec[1]);glVertex3fv(vec[0]);
 
519
                
 
520
                CalcNormFloat(vec[3], vec[2], vec[0], nor);
 
521
                glNormal3fv(nor);
 
522
                glVertex3fv(vec[3]);glVertex3fv(vec[2]);glVertex3fv(vec[0]);
 
523
                
 
524
                CalcNormFloat(vec[4], vec[3], vec[0], nor);
 
525
                glNormal3fv(nor);
 
526
                glVertex3fv(vec[4]);glVertex3fv(vec[3]);glVertex3fv(vec[0]);
 
527
 
 
528
                CalcNormFloat(vec[1], vec[4], vec[0], nor);
 
529
                glNormal3fv(nor);
 
530
                glVertex3fv(vec[1]);glVertex3fv(vec[4]);glVertex3fv(vec[0]);
 
531
 
 
532
                /* top */
 
533
                CalcNormFloat(vec[5], vec[1], vec[2], nor);
 
534
                glNormal3fv(nor);
 
535
                glVertex3fv(vec[5]);glVertex3fv(vec[1]);glVertex3fv(vec[2]);
 
536
                
 
537
                CalcNormFloat(vec[5], vec[2], vec[3], nor);
 
538
                glNormal3fv(nor);
 
539
                glVertex3fv(vec[5]);glVertex3fv(vec[2]);glVertex3fv(vec[3]);
 
540
                
 
541
                CalcNormFloat(vec[5], vec[3], vec[4], nor);
 
542
                glNormal3fv(nor);
 
543
                glVertex3fv(vec[5]);glVertex3fv(vec[3]);glVertex3fv(vec[4]);
 
544
                
 
545
                CalcNormFloat(vec[5], vec[4], vec[1], nor);
 
546
                glNormal3fv(nor);
 
547
                glVertex3fv(vec[5]);glVertex3fv(vec[4]);glVertex3fv(vec[1]);
 
548
                
 
549
                glEnd();
 
550
                
 
551
                glEndList();
 
552
        }
 
553
        else 
 
554
                glCallList(displist);
 
555
}       
 
556
 
 
557
/* *************** Armature drawing, bones ******************* */
 
558
 
 
559
 
 
560
static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id)
 
561
{
 
562
        /*      Draw root point if we are not connected */
 
563
        if ((boneflag & BONE_CONNECTED)==0) {
 
564
                if (id != -1)
 
565
                        glLoadName(id | BONESEL_ROOT);
 
566
                
 
567
                if(dt <= OB_WIRE) {
 
568
                        if (armflag & ARM_EDITMODE) {
 
569
                                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
570
                                else BIF_ThemeColor(TH_VERTEX);
 
571
                        }
 
572
                }
 
573
                else {
 
574
                        if (armflag & ARM_POSEMODE) 
 
575
                                set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
 
576
                        else
 
577
                                BIF_ThemeColor(TH_BONE_SOLID);
 
578
                }
 
579
                
 
580
                if (dt > OB_WIRE) 
 
581
                        draw_bonevert_solid();
 
582
                else 
 
583
                        draw_bonevert();
 
584
        }
 
585
        
 
586
        /*      Draw tip point */
 
587
        if (id != -1)
 
588
                glLoadName(id | BONESEL_TIP);
 
589
        
 
590
        if (dt <= OB_WIRE) {
 
591
                if (armflag & ARM_EDITMODE) {
 
592
                        if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
593
                        else BIF_ThemeColor(TH_VERTEX);
 
594
                }
 
595
        }
 
596
        else {
 
597
                if (armflag & ARM_POSEMODE) 
 
598
                        set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
 
599
                else
 
600
                        BIF_ThemeColor(TH_BONE_SOLID);
 
601
        }
 
602
        
 
603
        glTranslatef(0.0, 1.0, 0.0);
 
604
        if (dt > OB_WIRE) 
 
605
                draw_bonevert_solid();
 
606
        else 
 
607
                draw_bonevert();
 
608
        glTranslatef(0.0, -1.0, 0.0);
 
609
        
 
610
}
 
611
 
 
612
/* 16 values of sin function (still same result!) */
 
613
static float si[16] = {
 
614
        0.00000000,
 
615
        0.20129852, 0.39435585,
 
616
        0.57126821, 0.72479278,
 
617
        0.84864425, 0.93775213,
 
618
        0.98846832, 0.99871650,
 
619
        0.96807711, 0.89780453,
 
620
        0.79077573, 0.65137248,
 
621
        0.48530196, 0.29936312,
 
622
        0.10116832
 
623
};
 
624
/* 16 values of cos function (still same result!) */
 
625
static float co[16] ={
 
626
        1.00000000,
 
627
        0.97952994, 0.91895781,
 
628
        0.82076344, 0.68896691,
 
629
        0.52896401, 0.34730525,
 
630
        0.15142777, -0.05064916,
 
631
        -0.25065253, -0.44039415,
 
632
        -0.61210598, -0.75875812,
 
633
        -0.87434661, -0.95413925,
 
634
        -0.99486932
 
635
};
 
636
 
 
637
 
 
638
 
 
639
/* smat, imat = mat & imat to draw screenaligned */
 
640
static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag, bPoseChannel *pchan, EditBone *ebone)
 
641
{
 
642
        float head, tail, length, dist;
 
643
        float *headvec, *tailvec, dirvec[3];
 
644
        
 
645
        /* figure out the sizes of spheres */
 
646
        if (ebone) {
 
647
                /* this routine doesn't call set_matrix_editbone() that calculates it */
 
648
                ebone->length = VecLenf(ebone->head, ebone->tail);
 
649
                
 
650
                length= ebone->length;
 
651
                tail= ebone->rad_tail;
 
652
                dist= ebone->dist;
 
653
                if (ebone->parent && (ebone->flag & BONE_CONNECTED))
 
654
                        head= ebone->parent->rad_tail;
 
655
                else
 
656
                        head= ebone->rad_head;
 
657
                headvec= ebone->head;
 
658
                tailvec= ebone->tail;
 
659
        }
 
660
        else {
 
661
                length= pchan->bone->length;
 
662
                tail= pchan->bone->rad_tail;
 
663
                dist= pchan->bone->dist;
 
664
                if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED))
 
665
                        head= pchan->parent->bone->rad_tail;
 
666
                else
 
667
                        head= pchan->bone->rad_head;
 
668
                headvec= pchan->pose_head;
 
669
                tailvec= pchan->pose_tail;
 
670
        }
 
671
        
 
672
        /* ***** draw it ***** */
 
673
        
 
674
        /* move vector to viewspace */
 
675
        VecSubf(dirvec, tailvec, headvec);
 
676
        Mat4Mul3Vecfl(smat, dirvec);
 
677
        /* clear zcomp */
 
678
        dirvec[2]= 0.0;
 
679
        /* move vector back */
 
680
        Mat4Mul3Vecfl(imat, dirvec);
 
681
        
 
682
        if (0.0f != Normalize(dirvec)) {
 
683
                float norvec[3], vec1[3], vec2[3], vec[3];
 
684
                int a;
 
685
                
 
686
                //VecMulf(dirvec, head);
 
687
                Crossf(norvec, dirvec, imat[2]);
 
688
                
 
689
                glBegin(GL_QUAD_STRIP);
 
690
                
 
691
                for (a=0; a<16; a++) {
 
692
                        vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0];
 
693
                        vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1];
 
694
                        vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2];
 
695
                        
 
696
                        vec1[0]= headvec[0] + head*vec[0];
 
697
                        vec1[1]= headvec[1] + head*vec[1];
 
698
                        vec1[2]= headvec[2] + head*vec[2];
 
699
                        vec2[0]= headvec[0] + (head+dist)*vec[0];
 
700
                        vec2[1]= headvec[1] + (head+dist)*vec[1];
 
701
                        vec2[2]= headvec[2] + (head+dist)*vec[2];
 
702
                        
 
703
                        glColor4ub(255, 255, 255, 50);
 
704
                        glVertex3fv(vec1);
 
705
                        //glColor4ub(255, 255, 255, 0);
 
706
                        glVertex3fv(vec2);
 
707
                }
 
708
                
 
709
                for (a=15; a>=0; a--) {
 
710
                        vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0];
 
711
                        vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1];
 
712
                        vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2];
 
713
                        
 
714
                        vec1[0]= tailvec[0] + tail*vec[0];
 
715
                        vec1[1]= tailvec[1] + tail*vec[1];
 
716
                        vec1[2]= tailvec[2] + tail*vec[2];
 
717
                        vec2[0]= tailvec[0] + (tail+dist)*vec[0];
 
718
                        vec2[1]= tailvec[1] + (tail+dist)*vec[1];
 
719
                        vec2[2]= tailvec[2] + (tail+dist)*vec[2];
 
720
                        
 
721
                        //glColor4ub(255, 255, 255, 50);
 
722
                        glVertex3fv(vec1);
 
723
                        //glColor4ub(255, 255, 255, 0);
 
724
                        glVertex3fv(vec2);
 
725
                }
 
726
                /* make it cyclic... */
 
727
                
 
728
                vec[0]= - *(si) * dirvec[0] + *(co) * norvec[0];
 
729
                vec[1]= - *(si) * dirvec[1] + *(co) * norvec[1];
 
730
                vec[2]= - *(si) * dirvec[2] + *(co) * norvec[2];
 
731
                
 
732
                vec1[0]= headvec[0] + head*vec[0];
 
733
                vec1[1]= headvec[1] + head*vec[1];
 
734
                vec1[2]= headvec[2] + head*vec[2];
 
735
                vec2[0]= headvec[0] + (head+dist)*vec[0];
 
736
                vec2[1]= headvec[1] + (head+dist)*vec[1];
 
737
                vec2[2]= headvec[2] + (head+dist)*vec[2];
 
738
                
 
739
                //glColor4ub(255, 255, 255, 50);
 
740
                glVertex3fv(vec1);
 
741
                //glColor4ub(255, 255, 255, 0);
 
742
                glVertex3fv(vec2);
 
743
                
 
744
                glEnd();
 
745
        }
 
746
}
 
747
 
 
748
 
 
749
/* smat, imat = mat & imat to draw screenaligned */
 
750
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)
 
751
{
 
752
        float head, tail, length;
 
753
        float *headvec, *tailvec, dirvec[3];
 
754
        
 
755
        /* figure out the sizes of spheres */
 
756
        if (ebone) {
 
757
                /* this routine doesn't call set_matrix_editbone() that calculates it */
 
758
                ebone->length = VecLenf(ebone->head, ebone->tail);
 
759
                
 
760
                length= ebone->length;
 
761
                tail= ebone->rad_tail;
 
762
                if (ebone->parent && (boneflag & BONE_CONNECTED))
 
763
                        head= ebone->parent->rad_tail;
 
764
                else
 
765
                        head= ebone->rad_head;
 
766
                headvec= ebone->head;
 
767
                tailvec= ebone->tail;
 
768
        }
 
769
        else {
 
770
                length= pchan->bone->length;
 
771
                tail= pchan->bone->rad_tail;
 
772
                if ((pchan->parent) && (boneflag & BONE_CONNECTED))
 
773
                        head= pchan->parent->bone->rad_tail;
 
774
                else
 
775
                        head= pchan->bone->rad_head;
 
776
                headvec= pchan->pose_head;
 
777
                tailvec= pchan->pose_tail;
 
778
        }
 
779
        
 
780
        /* sphere root color */
 
781
        if (armflag & ARM_EDITMODE) {
 
782
                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
783
                else BIF_ThemeColor(TH_VERTEX);
 
784
        }
 
785
        else if (armflag & ARM_POSEMODE)
 
786
                set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
787
        
 
788
        /*      Draw root point if we are not connected */
 
789
        if ((boneflag & BONE_CONNECTED)==0) {
 
790
                if (id != -1)
 
791
                        glLoadName(id | BONESEL_ROOT);
 
792
                
 
793
                drawcircball(GL_LINE_LOOP, headvec, head, imat);
 
794
        }
 
795
        
 
796
        /*      Draw tip point */
 
797
        if (armflag & ARM_EDITMODE) {
 
798
                if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
799
                else BIF_ThemeColor(TH_VERTEX);
 
800
        }
 
801
        
 
802
        if (id != -1)
 
803
                glLoadName(id | BONESEL_TIP);
 
804
        
 
805
        drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
 
806
        
 
807
        /* base */
 
808
        if (armflag & ARM_EDITMODE) {
 
809
                if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
 
810
                else BIF_ThemeColor(TH_WIRE);
 
811
        }
 
812
        
 
813
        VecSubf(dirvec, tailvec, headvec);
 
814
        
 
815
        /* move vector to viewspace */
 
816
        Mat4Mul3Vecfl(smat, dirvec);
 
817
        /* clear zcomp */
 
818
        dirvec[2]= 0.0;
 
819
        /* move vector back */
 
820
        Mat4Mul3Vecfl(imat, dirvec);
 
821
        
 
822
        if (0.0f != Normalize(dirvec)) {
 
823
                float norvech[3], norvect[3], vec[3];
 
824
                
 
825
                VECCOPY(vec, dirvec);
 
826
                
 
827
                VecMulf(dirvec, head);
 
828
                Crossf(norvech, dirvec, imat[2]);
 
829
                
 
830
                VecMulf(vec, tail);
 
831
                Crossf(norvect, vec, imat[2]);
 
832
                
 
833
                if (id != -1)
 
834
                        glLoadName(id | BONESEL_BONE);
 
835
                
 
836
                glBegin(GL_LINES);
 
837
                vec[0]= headvec[0] + norvech[0];
 
838
                vec[1]= headvec[1] + norvech[1];
 
839
                vec[2]= headvec[2] + norvech[2];
 
840
                glVertex3fv(vec);
 
841
                vec[0]= tailvec[0] + norvect[0];
 
842
                vec[1]= tailvec[1] + norvect[1];
 
843
                vec[2]= tailvec[2] + norvect[2];
 
844
                glVertex3fv(vec);
 
845
                vec[0]= headvec[0] - norvech[0];
 
846
                vec[1]= headvec[1] - norvech[1];
 
847
                vec[2]= headvec[2] - norvech[2];
 
848
                glVertex3fv(vec);
 
849
                vec[0]= tailvec[0] - norvect[0];
 
850
                vec[1]= tailvec[1] - norvect[1];
 
851
                vec[2]= tailvec[2] - norvect[2];
 
852
                glVertex3fv(vec);
 
853
                
 
854
                glEnd();
 
855
        }
 
856
}
 
857
 
 
858
/* does wire only for outline selecting */
 
859
static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
 
860
{
 
861
        GLUquadricObj   *qobj;
 
862
        float head, tail, length;
 
863
        float fac1, fac2;
 
864
        
 
865
        glPushMatrix();
 
866
        qobj    = gluNewQuadric();
 
867
 
 
868
        /* figure out the sizes of spheres */
 
869
        if (ebone) {
 
870
                length= ebone->length;
 
871
                tail= ebone->rad_tail;
 
872
                if (ebone->parent && (boneflag & BONE_CONNECTED))
 
873
                        head= ebone->parent->rad_tail;
 
874
                else
 
875
                        head= ebone->rad_head;
 
876
        }
 
877
        else {
 
878
                length= pchan->bone->length;
 
879
                tail= pchan->bone->rad_tail;
 
880
                if (pchan->parent && (boneflag & BONE_CONNECTED))
 
881
                        head= pchan->parent->bone->rad_tail;
 
882
                else
 
883
                        head= pchan->bone->rad_head;
 
884
        }
 
885
        
 
886
        /* move to z-axis space */
 
887
        glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
 
888
 
 
889
        if (dt==OB_SOLID) {
 
890
                /* set up solid drawing */
 
891
                glEnable(GL_COLOR_MATERIAL);
 
892
                glEnable(GL_LIGHTING);
 
893
                
 
894
                gluQuadricDrawStyle(qobj, GLU_FILL); 
 
895
                glShadeModel(GL_SMOOTH);
 
896
        }
 
897
        else {
 
898
                gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
 
899
        }
 
900
        
 
901
        /* sphere root color */
 
902
        if (armflag & ARM_EDITMODE) {
 
903
                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
904
                else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
 
905
        }
 
906
        else if (armflag & ARM_POSEMODE)
 
907
                set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, armflag, boneflag, constflag);
 
908
        else if (dt==OB_SOLID) 
 
909
                BIF_ThemeColorShade(TH_BONE_SOLID, -30);
 
910
        
 
911
        /*      Draw root point if we are not connected */
 
912
        if ((boneflag & BONE_CONNECTED)==0) {
 
913
                if (id != -1)
 
914
                        glLoadName(id | BONESEL_ROOT);
 
915
                gluSphere(qobj, head, 16, 10);
 
916
        }
 
917
        
 
918
        /*      Draw tip point */
 
919
        if (armflag & ARM_EDITMODE) {
 
920
                if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
921
                else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
 
922
        }
 
923
 
 
924
        if (id != -1)
 
925
                glLoadName(id | BONESEL_TIP);
 
926
        
 
927
        glTranslatef(0.0, 0.0, length);
 
928
        gluSphere(qobj, tail, 16, 10);
 
929
        glTranslatef(0.0, 0.0, -length);
 
930
        
 
931
        /* base */
 
932
        if (armflag & ARM_EDITMODE) {
 
933
                if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
 
934
                else BIF_ThemeColor(TH_BONE_SOLID);
 
935
        }
 
936
        else if (armflag & ARM_POSEMODE)
 
937
                set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, armflag, boneflag, constflag);
 
938
        else if (dt == OB_SOLID)
 
939
                BIF_ThemeColor(TH_BONE_SOLID);
 
940
        
 
941
        fac1= (length-head)/length;
 
942
        fac2= (length-tail)/length;
 
943
        
 
944
        if (length > (head+tail)) {
 
945
                if (id != -1)
 
946
                        glLoadName (id | BONESEL_BONE);
 
947
                
 
948
                glEnable(GL_POLYGON_OFFSET_FILL);
 
949
                glPolygonOffset(-1.0, -1.0);
 
950
                
 
951
                glTranslatef(0.0f, 0.0f, head);
 
952
                gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1);
 
953
                glTranslatef(0.0f, 0.0f, -head);
 
954
                
 
955
                glDisable(GL_POLYGON_OFFSET_FILL);
 
956
                
 
957
                /* draw sphere on extrema */
 
958
                glTranslatef(0.0f, 0.0f, length-tail);
 
959
                gluSphere(qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
 
960
                glTranslatef(0.0f, 0.0f, -length+tail);
 
961
                
 
962
                glTranslatef(0.0f, 0.0f, head);
 
963
                gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
 
964
        }
 
965
        else {          
 
966
                /* 1 sphere in center */
 
967
                glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0);
 
968
                gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
 
969
        }
 
970
        
 
971
        /* restore */
 
972
        if (dt==OB_SOLID) {
 
973
                glShadeModel(GL_FLAT);
 
974
                glDisable(GL_LIGHTING);
 
975
                glDisable(GL_COLOR_MATERIAL);
 
976
        }
 
977
        
 
978
        glPopMatrix();
 
979
        gluDeleteQuadric(qobj);  
 
980
}
 
981
 
 
982
static GLubyte bm_dot6[]= {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0}; 
 
983
static GLubyte bm_dot8[]= {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C}; 
 
984
 
 
985
static GLubyte bm_dot5[]= {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0}; 
 
986
static GLubyte bm_dot7[]= {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38}; 
 
987
 
 
988
 
 
989
static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
 
990
{
 
991
        float length;
 
992
        
 
993
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
994
        
 
995
        if (pchan) 
 
996
                length= pchan->bone->length;
 
997
        else 
 
998
                length= ebone->length;
 
999
        
 
1000
        glPushMatrix();
 
1001
        glScalef(length, length, length);
 
1002
        
 
1003
        /* this chunk not in object mode */
 
1004
        if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
 
1005
                glLineWidth(4.0);
 
1006
                if (armflag & ARM_POSEMODE)
 
1007
                        set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
1008
                else if (armflag & ARM_EDITMODE) {
 
1009
                        BIF_ThemeColor(TH_WIRE);
 
1010
                }
 
1011
                
 
1012
                /*      Draw root point if we are not connected */
 
1013
                if ((boneflag & BONE_CONNECTED)==0) {
 
1014
                        if (G.f & G_PICKSEL) {  // no bitmap in selection mode, crashes 3d cards...
 
1015
                                glLoadName (id | BONESEL_ROOT);
 
1016
                                glBegin(GL_POINTS);
 
1017
                                glVertex3f(0.0f, 0.0f, 0.0f);
 
1018
                                glEnd();
 
1019
                        }
 
1020
                        else {
 
1021
                                glRasterPos3f(0.0f, 0.0f, 0.0f);
 
1022
                                glBitmap(8, 8, 4, 4, 0, 0, bm_dot8);
 
1023
                        }
 
1024
                }
 
1025
                
 
1026
                if (id != -1)
 
1027
                        glLoadName((GLuint) id|BONESEL_BONE);
 
1028
                
 
1029
                glBegin(GL_LINES);
 
1030
                glVertex3f(0.0f, 0.0f, 0.0f);
 
1031
                glVertex3f(0.0f, 1.0f, 0.0f);
 
1032
                glEnd();
 
1033
                
 
1034
                /* tip */
 
1035
                if (G.f & G_PICKSEL) {  
 
1036
                        /* no bitmap in selection mode, crashes 3d cards... */
 
1037
                        glLoadName(id | BONESEL_TIP);
 
1038
                        glBegin(GL_POINTS);
 
1039
                        glVertex3f(0.0f, 1.0f, 0.0f);
 
1040
                        glEnd();
 
1041
                }
 
1042
                else {
 
1043
                        glRasterPos3f(0.0f, 1.0f, 0.0f);
 
1044
                        glBitmap(8, 8, 4, 4, 0, 0, bm_dot7);
 
1045
                }
 
1046
                
 
1047
                /* further we send no names */
 
1048
                if (id != -1)
 
1049
                        glLoadName(id & 0xFFFF);        /* object tag, for bordersel optim */
 
1050
                
 
1051
                if (armflag & ARM_POSEMODE)
 
1052
                        set_pchan_glColor(PCHAN_COLOR_LINEBONE, armflag, boneflag, constflag);
 
1053
        }
 
1054
        
 
1055
        glLineWidth(2.0);
 
1056
        
 
1057
        /*Draw root point if we are not connected */
 
1058
        if ((boneflag & BONE_CONNECTED)==0) {
 
1059
                if ((G.f & G_PICKSEL)==0) {     
 
1060
                        /* no bitmap in selection mode, crashes 3d cards... */
 
1061
                        if (armflag & ARM_EDITMODE) {
 
1062
                                if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
1063
                                else BIF_ThemeColor(TH_VERTEX);
 
1064
                        }
 
1065
                        glRasterPos3f(0.0f, 0.0f, 0.0f);
 
1066
                        glBitmap(8, 8, 4, 4, 0, 0, bm_dot6);
 
1067
                }
 
1068
        }
 
1069
        
 
1070
        if (armflag & ARM_EDITMODE) {
 
1071
                if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT);
 
1072
                else BIF_ThemeColorShade(TH_BACK, -30);
 
1073
        }
 
1074
        glBegin(GL_LINES);
 
1075
        glVertex3f(0.0f, 0.0f, 0.0f);
 
1076
        glVertex3f(0.0f, 1.0f, 0.0f);
 
1077
        glEnd();
 
1078
        
 
1079
        /* tip */
 
1080
        if ((G.f & G_PICKSEL)==0) {     
 
1081
                /* no bitmap in selection mode, crashes 3d cards... */
 
1082
                if (armflag & ARM_EDITMODE) {
 
1083
                        if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
 
1084
                        else BIF_ThemeColor(TH_VERTEX);
 
1085
                }
 
1086
                glRasterPos3f(0.0f, 1.0f, 0.0f);
 
1087
                glBitmap(8, 8, 4, 4, 0, 0, bm_dot5);
 
1088
        }
 
1089
        
 
1090
        glLineWidth(1.0);
 
1091
        
 
1092
        glPopMatrix();
 
1093
}
 
1094
 
 
1095
static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth)
 
1096
{
 
1097
        int segments= 0;
 
1098
        
 
1099
        if (pchan) 
 
1100
                segments= pchan->bone->segments;
 
1101
        
 
1102
        if ((segments > 1) && (pchan)) {
 
1103
                float dlen= length/(float)segments;
 
1104
                Mat4 *bbone= b_bone_spline_setup(pchan, 0);
 
1105
                int a;
 
1106
                
 
1107
                for (a=0; a<segments; a++, bbone++) {
 
1108
                        glPushMatrix();
 
1109
                        glMultMatrixf(bbone->mat);
 
1110
                        if (dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
 
1111
                        else drawcube_size(xwidth, dlen, zwidth);
 
1112
                        glPopMatrix();
 
1113
                }
 
1114
        }
 
1115
        else {
 
1116
                glPushMatrix();
 
1117
                if (dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
 
1118
                else drawcube_size(xwidth, length, zwidth);
 
1119
                glPopMatrix();
 
1120
        }
 
1121
}
 
1122
 
 
1123
static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
 
1124
{
 
1125
        float xwidth, length, zwidth;
 
1126
        
 
1127
        if (pchan) {
 
1128
                xwidth= pchan->bone->xwidth;
 
1129
                length= pchan->bone->length;
 
1130
                zwidth= pchan->bone->zwidth;
 
1131
        }
 
1132
        else {
 
1133
                xwidth= ebone->xwidth;
 
1134
                length= ebone->length;
 
1135
                zwidth= ebone->zwidth;
 
1136
        }
 
1137
        
 
1138
        /* draw points only if... */
 
1139
        if (armflag & ARM_EDITMODE) {
 
1140
                /* move to unitspace */
 
1141
                glPushMatrix();
 
1142
                glScalef(length, length, length);
 
1143
                draw_bone_points(dt, armflag, boneflag, id);
 
1144
                glPopMatrix();
 
1145
                length*= 0.95f; // make vertices visible
 
1146
        }
 
1147
 
 
1148
        /* colors for modes */
 
1149
        if (armflag & ARM_POSEMODE) {
 
1150
                if (dt <= OB_WIRE)
 
1151
                        set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
1152
                else 
 
1153
                        set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
 
1154
        }
 
1155
        else if (armflag & ARM_EDITMODE) {
 
1156
                if (dt==OB_WIRE) {
 
1157
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
 
1158
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
 
1159
                        else BIF_ThemeColor(TH_WIRE);
 
1160
                }
 
1161
                else 
 
1162
                        BIF_ThemeColor(TH_BONE_SOLID);
 
1163
        }
 
1164
        
 
1165
        if (id != -1) {
 
1166
                glLoadName ((GLuint) id|BONESEL_BONE);
 
1167
        }
 
1168
        
 
1169
        /* set up solid drawing */
 
1170
        if (dt > OB_WIRE) {
 
1171
                glEnable(GL_COLOR_MATERIAL);
 
1172
                glEnable(GL_LIGHTING);
 
1173
                
 
1174
                if (armflag & ARM_POSEMODE)
 
1175
                        set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
 
1176
                else
 
1177
                        BIF_ThemeColor(TH_BONE_SOLID);
 
1178
                
 
1179
                draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
 
1180
                
 
1181
                /* disable solid drawing */
 
1182
                glDisable(GL_COLOR_MATERIAL);
 
1183
                glDisable(GL_LIGHTING);
 
1184
        }
 
1185
        else {  
 
1186
                /* wire */
 
1187
                if (armflag & ARM_POSEMODE) {
 
1188
                        if (constflag) {
 
1189
                                /* set constraint colors */
 
1190
                                if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {
 
1191
                                        glEnable(GL_BLEND);
 
1192
                                        
 
1193
                                        draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
 
1194
                                        
 
1195
                                        glDisable(GL_BLEND);
 
1196
                                }
 
1197
                                
 
1198
                                /* restore colors */
 
1199
                                set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
1200
                        }
 
1201
                }               
 
1202
                
 
1203
                draw_b_bone_boxes(OB_WIRE, pchan, xwidth, length, zwidth);              
 
1204
        }
 
1205
}
 
1206
 
 
1207
static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length)
 
1208
{
 
1209
        
 
1210
        /*      Draw a 3d octahedral bone, we use normalized space based on length,
 
1211
            for glDisplayLists */
 
1212
        
 
1213
        glScalef(length, length, length);
 
1214
 
 
1215
        /* set up solid drawing */
 
1216
        if (dt > OB_WIRE) {
 
1217
                glEnable(GL_COLOR_MATERIAL);
 
1218
                glEnable(GL_LIGHTING);
 
1219
                BIF_ThemeColor(TH_BONE_SOLID);
 
1220
        }
 
1221
        
 
1222
        /* colors for posemode */
 
1223
        if (armflag & ARM_POSEMODE) {
 
1224
                if (dt <= OB_WIRE)
 
1225
                        set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
1226
                else 
 
1227
                        set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
 
1228
        }
 
1229
        
 
1230
        
 
1231
        draw_bone_points(dt, armflag, boneflag, id);
 
1232
        
 
1233
        /* now draw the bone itself */
 
1234
        if (id != -1) {
 
1235
                glLoadName((GLuint) id|BONESEL_BONE);
 
1236
        }
 
1237
        
 
1238
        /* wire? */
 
1239
        if (dt <= OB_WIRE) {
 
1240
                /* colors */
 
1241
                if (armflag & ARM_EDITMODE) {
 
1242
                        if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
 
1243
                        else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
 
1244
                        else BIF_ThemeColor(TH_WIRE);
 
1245
                }
 
1246
                else if (armflag & ARM_POSEMODE) {
 
1247
                        if (constflag) {
 
1248
                                /* draw constraint colors */
 
1249
                                if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {      
 
1250
                                        glEnable(GL_BLEND);
 
1251
                                        
 
1252
                                        draw_bone_solid_octahedral();
 
1253
                                        
 
1254
                                        glDisable(GL_BLEND);
 
1255
                                }
 
1256
                                
 
1257
                                /* restore colors */
 
1258
                                set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
 
1259
                        }
 
1260
                }               
 
1261
                draw_bone_octahedral();
 
1262
        }
 
1263
        else {  
 
1264
                /* solid */
 
1265
                if (armflag & ARM_POSEMODE)
 
1266
                        set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
 
1267
                else
 
1268
                        BIF_ThemeColor(TH_BONE_SOLID);
 
1269
                draw_bone_solid_octahedral();
 
1270
        }
 
1271
 
 
1272
        /* disable solid drawing */
 
1273
        if (dt > OB_WIRE) {
 
1274
                glDisable(GL_COLOR_MATERIAL);
 
1275
                glDisable(GL_LIGHTING);
 
1276
        }
 
1277
}
 
1278
 
 
1279
static void draw_custom_bone(Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length)
 
1280
{
 
1281
        if(ob==NULL) return;
 
1282
        
 
1283
        glScalef(length, length, length);
 
1284
        
 
1285
        /* colors for posemode */
 
1286
        if (armflag & ARM_POSEMODE) {
 
1287
                set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, 0);
 
1288
        }
 
1289
        
 
1290
        if (id != -1) {
 
1291
                glLoadName((GLuint) id|BONESEL_BONE);
 
1292
        }
 
1293
        
 
1294
        draw_object_instance(ob, dt, armflag & ARM_POSEMODE);
 
1295
}
 
1296
 
 
1297
 
 
1298
static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
 
1299
{
 
1300
        bConstraint *con;
 
1301
        bPoseChannel *parchan;
 
1302
        
 
1303
        for (con= pchan->constraints.first; con; con= con->next) {
 
1304
                if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) {
 
1305
                        bKinematicConstraint *data = (bKinematicConstraint*)con->data;
 
1306
                        int segcount= 0;
 
1307
                        
 
1308
                        /* if only_temp, only draw if it is a temporary ik-chain */
 
1309
                        if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP))
 
1310
                                continue;
 
1311
                        
 
1312
                        setlinestyle(3);
 
1313
                        glBegin(GL_LINES);
 
1314
                        
 
1315
                        /* exclude tip from chain? */
 
1316
                        if ((data->flag & CONSTRAINT_IK_TIP)==0)
 
1317
                                parchan= pchan->parent;
 
1318
                        else
 
1319
                                parchan= pchan;
 
1320
                        
 
1321
                        glVertex3fv(parchan->pose_tail);
 
1322
                        
 
1323
                        /* Find the chain's root */
 
1324
                        while (parchan->parent) {
 
1325
                                segcount++;
 
1326
                                if(segcount==data->rootbone || segcount>255) break; // 255 is weak
 
1327
                                parchan= parchan->parent;
 
1328
                        }
 
1329
                        if (parchan)
 
1330
                                glVertex3fv(parchan->pose_head);
 
1331
                        
 
1332
                        glEnd();
 
1333
                        setlinestyle(0);
 
1334
                }
 
1335
        }
 
1336
}
 
1337
 
 
1338
static void bgl_sphere_project(float ax, float az)
 
1339
{
 
1340
        float dir[3], sine, q3;
 
1341
 
 
1342
        sine= 1.0f-ax*ax-az*az;
 
1343
        q3= (sine < 0.0f)? 0.0f: 2.0f*sqrt(sine);
 
1344
 
 
1345
        dir[0]= -az*q3;
 
1346
        dir[1]= 1.0f-2.0f*sine;
 
1347
        dir[2]= ax*q3;
 
1348
 
 
1349
        glVertex3fv(dir);
 
1350
}
 
1351
 
 
1352
static void draw_dof_ellipse(float ax, float az)
 
1353
{
 
1354
        static float staticSine[16] = {
 
1355
                0.0, 0.104528463268, 0.207911690818, 0.309016994375,
 
1356
                0.406736643076, 0.5, 0.587785252292, 0.669130606359,
 
1357
                0.743144825477, 0.809016994375, 0.866025403784,
 
1358
                0.913545457643, 0.951056516295, 0.978147600734,
 
1359
                0.994521895368, 1.0
 
1360
        };
 
1361
 
 
1362
        int i, j, n=16;
 
1363
        float x, z, px, pz;
 
1364
 
 
1365
        glEnable(GL_BLEND);
 
1366
        glDepthMask(0);
 
1367
 
 
1368
        glColor4ub(70, 70, 70, 50);
 
1369
 
 
1370
        glBegin(GL_QUADS);
 
1371
        pz= 0.0f;
 
1372
        for(i=1; i<n; i++) {
 
1373
                z= staticSine[i];
 
1374
 
 
1375
                px= 0.0f;
 
1376
                for(j=1; j<n-i+1; j++) {
 
1377
                        x = staticSine[j];
 
1378
 
 
1379
                        if(j == n-i) {
 
1380
                                glEnd();
 
1381
                                glBegin(GL_TRIANGLES);
 
1382
                                bgl_sphere_project(ax*px, az*z);
 
1383
                                bgl_sphere_project(ax*px, az*pz);
 
1384
                                bgl_sphere_project(ax*x, az*pz);
 
1385
                                glEnd();
 
1386
                                glBegin(GL_QUADS);
 
1387
                        }
 
1388
                        else {
 
1389
                                bgl_sphere_project(ax*x, az*z);
 
1390
                                bgl_sphere_project(ax*x, az*pz);
 
1391
                                bgl_sphere_project(ax*px, az*pz);
 
1392
                                bgl_sphere_project(ax*px, az*z);
 
1393
                        }
 
1394
 
 
1395
                        px= x;
 
1396
                }
 
1397
                pz= z;
 
1398
        }
 
1399
        glEnd();
 
1400
 
 
1401
        glDisable(GL_BLEND);
 
1402
        glDepthMask(1);
 
1403
 
 
1404
        glColor3ub(0, 0, 0);
 
1405
 
 
1406
        glBegin(GL_LINE_STRIP);
 
1407
        for (i=0; i<n; i++)
 
1408
                bgl_sphere_project(staticSine[n-i-1]*ax, staticSine[i]*az);
 
1409
        glEnd();
 
1410
}
 
1411
 
 
1412
static void draw_pose_dofs(Object *ob)
 
1413
{
 
1414
        bArmature *arm= ob->data;
 
1415
        bPoseChannel *pchan;
 
1416
        Bone *bone;
 
1417
        
 
1418
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
1419
                bone= pchan->bone;
 
1420
                
 
1421
                if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
 
1422
                        if (bone->flag & BONE_SELECTED) {
 
1423
                                if (bone->layer & arm->layer) {
 
1424
                                        if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) {
 
1425
                                                if (pose_channel_in_IK_chain(ob, pchan)) {
 
1426
                                                        float corner[4][3], posetrans[3], mat[4][4];
 
1427
                                                        float phi=0.0f, theta=0.0f, scale;
 
1428
                                                        int a, i;
 
1429
                                                        
 
1430
                                                        /* in parent-bone pose, but own restspace */
 
1431
                                                        glPushMatrix();
 
1432
                                                        
 
1433
                                                        VECCOPY(posetrans, pchan->pose_mat[3]);
 
1434
                                                        glTranslatef(posetrans[0], posetrans[1], posetrans[2]);
 
1435
                                                        
 
1436
                                                        if (pchan->parent) {
 
1437
                                                                Mat4CpyMat4(mat, pchan->parent->pose_mat);
 
1438
                                                                mat[3][0]= mat[3][1]= mat[3][2]= 0.0f;
 
1439
                                                                glMultMatrixf(mat);
 
1440
                                                        }
 
1441
                                                        
 
1442
                                                        Mat4CpyMat3(mat, pchan->bone->bone_mat);
 
1443
                                                        glMultMatrixf(mat);
 
1444
                                                        
 
1445
                                                        scale= bone->length*pchan->size[1];
 
1446
                                                        glScalef(scale, scale, scale);
 
1447
                                                        
 
1448
                                                        if (pchan->ikflag & BONE_IK_XLIMIT) {
 
1449
                                                                if (pchan->ikflag & BONE_IK_ZLIMIT) {
 
1450
                                                                        float amin[3], amax[3];
 
1451
                                                                        
 
1452
                                                                        for (i=0; i<3; i++) {
 
1453
                                                                                amin[i]= sin(pchan->limitmin[i]*M_PI/360.0);
 
1454
                                                                                amax[i]= sin(pchan->limitmax[i]*M_PI/360.0);
 
1455
                                                                        }
 
1456
                                                                        
 
1457
                                                                        glScalef(1.0, -1.0, 1.0);
 
1458
                                                                        if (amin[0] != 0.0 && amin[2] != 0.0)
 
1459
                                                                                draw_dof_ellipse(amin[0], amin[2]);
 
1460
                                                                        if (amin[0] != 0.0 && amax[2] != 0.0)
 
1461
                                                                                draw_dof_ellipse(amin[0], amax[2]);
 
1462
                                                                        if (amax[0] != 0.0 && amin[2] != 0.0)
 
1463
                                                                                draw_dof_ellipse(amax[0], amin[2]);
 
1464
                                                                        if (amax[0] != 0.0 && amax[2] != 0.0)
 
1465
                                                                                draw_dof_ellipse(amax[0], amax[2]);
 
1466
                                                                        glScalef(1.0, -1.0, 1.0);
 
1467
                                                                }
 
1468
                                                        }
 
1469
                                                        
 
1470
                                                        /* arcs */
 
1471
                                                        if (pchan->ikflag & BONE_IK_ZLIMIT) {
 
1472
                                                                theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]);
 
1473
                                                                glRotatef(theta, 0.0f, 0.0f, 1.0f);
 
1474
                                                                
 
1475
                                                                glColor3ub(50, 50, 255);        // blue, Z axis limit
 
1476
                                                                glBegin(GL_LINE_STRIP);
 
1477
                                                                for (a=-16; a<=16; a++) {
 
1478
                                                                        float fac= ((float)a)/16.0f;
 
1479
                                                                        phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]);
 
1480
                                                                        
 
1481
                                                                        i= (a == -16) ? 0 : 1;
 
1482
                                                                        corner[i][0]= sin(phi);
 
1483
                                                                        corner[i][1]= cos(phi);
 
1484
                                                                        corner[i][2]= 0.0f;
 
1485
                                                                        glVertex3fv(corner[i]);
 
1486
                                                                }
 
1487
                                                                glEnd();
 
1488
                                                                
 
1489
                                                                glRotatef(-theta, 0.0f, 0.0f, 1.0f);
 
1490
                                                        }                                       
 
1491
                                                        
 
1492
                                                        if (pchan->ikflag & BONE_IK_XLIMIT) {
 
1493
                                                                theta=  0.5*(pchan->limitmin[0]+pchan->limitmax[0]);
 
1494
                                                                glRotatef(theta, 1.0f, 0.0f, 0.0f);
 
1495
                                                                
 
1496
                                                                glColor3ub(255, 50, 50);        // Red, X axis limit
 
1497
                                                                glBegin(GL_LINE_STRIP);
 
1498
                                                                for (a=-16; a<=16; a++) {
 
1499
                                                                        float fac= ((float)a)/16.0f;
 
1500
                                                                        phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]);
 
1501
                                                                        
 
1502
                                                                        i= (a == -16) ? 2 : 3;
 
1503
                                                                        corner[i][0]= 0.0f;
 
1504
                                                                        corner[i][1]= sin(phi);
 
1505
                                                                        corner[i][2]= cos(phi);
 
1506
                                                                        glVertex3fv(corner[i]);
 
1507
                                                                }
 
1508
                                                                glEnd();
 
1509
                                                                
 
1510
                                                                glRotatef(-theta, 1.0f, 0.0f, 0.0f);
 
1511
                                                        }
 
1512
                                                        
 
1513
                                                        /* out of cone, out of bone */
 
1514
                                                        glPopMatrix(); 
 
1515
                                                }
 
1516
                                        }
 
1517
                                }
 
1518
                        }
 
1519
                }
 
1520
        }
 
1521
}
 
1522
 
 
1523
/* assumes object is Armature with pose */
 
1524
static void draw_pose_channels(Base *base, int dt)
 
1525
{
 
1526
        Object *ob= base->object;
 
1527
        bArmature *arm= ob->data;
 
1528
        bPoseChannel *pchan;
 
1529
        Bone *bone;
 
1530
        GLfloat tmp;
 
1531
        float smat[4][4], imat[4][4];
 
1532
        int index= -1;
 
1533
        short do_dashed= 3, draw_wire= 0;
 
1534
        short flag, constflag;
 
1535
        
 
1536
        /* hacky... prevent outline select from drawing dashed helplines */
 
1537
        glGetFloatv(GL_LINE_WIDTH, &tmp);
 
1538
        if (tmp > 1.1) do_dashed &= ~1;
 
1539
        if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed &= ~2;
 
1540
        
 
1541
        /* precalc inverse matrix for drawing screen aligned */
 
1542
        if (arm->drawtype==ARM_ENVELOPE) {
 
1543
                /* precalc inverse matrix for drawing screen aligned */
 
1544
                mygetmatrix(smat);
 
1545
                Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
 
1546
                Mat4Invert(imat, smat);
 
1547
                
 
1548
                /* and draw blended distances */
 
1549
                if (arm->flag & ARM_POSEMODE) {
 
1550
                        glEnable(GL_BLEND);
 
1551
                        //glShadeModel(GL_SMOOTH);
 
1552
                        
 
1553
                        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
1554
                        
 
1555
                        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
1556
                                bone= pchan->bone;
 
1557
                                if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) {
 
1558
                                        if (bone->flag & (BONE_SELECTED)) {
 
1559
                                                if (bone->layer & arm->layer)
 
1560
                                                        draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL);
 
1561
                                        }
 
1562
                                }
 
1563
                        }
 
1564
                        
 
1565
                        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
1566
                        glDisable(GL_BLEND);
 
1567
                        //glShadeModel(GL_FLAT);
 
1568
                }
 
1569
        }
 
1570
        
 
1571
        /* little speedup, also make sure transparent only draws once */
 
1572
        glCullFace(GL_BACK); 
 
1573
        glEnable(GL_CULL_FACE);
 
1574
        
 
1575
        /* if solid we draw that first, with selection codes, but without names, axes etc */
 
1576
        if (dt > OB_WIRE) {
 
1577
                if (arm->flag & ARM_POSEMODE) 
 
1578
                        index= base->selcol;
 
1579
                
 
1580
                for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
1581
                        bone= pchan->bone;
 
1582
                        
 
1583
                        if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) {
 
1584
                                if (bone->layer & arm->layer) {
 
1585
                                        glPushMatrix();
 
1586
                                        glMultMatrixf(pchan->pose_mat);
 
1587
                                        
 
1588
                                        /* catch exception for bone with hidden parent */
 
1589
                                        flag= bone->flag;
 
1590
                                        if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) )
 
1591
                                                flag &= ~BONE_CONNECTED;
 
1592
                                                
 
1593
                                        /* set color-set to use */
 
1594
                                        set_pchan_colorset(ob, pchan);
 
1595
                                        
 
1596
                                        if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
 
1597
                                                /* if drawwire, don't try to draw in solid */
 
1598
                                                if (pchan->bone->flag & BONE_DRAWWIRE) 
 
1599
                                                        draw_wire= 1;
 
1600
                                                else
 
1601
                                                        draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length);
 
1602
                                        }
 
1603
                                        else if (arm->drawtype==ARM_LINE)
 
1604
                                                ;       /* nothing in solid */
 
1605
                                        else if (arm->drawtype==ARM_ENVELOPE)
 
1606
                                                draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
 
1607
                                        else if (arm->drawtype==ARM_B_BONE)
 
1608
                                                draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
 
1609
                                        else
 
1610
                                                draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
 
1611
                                                
 
1612
                                        glPopMatrix();
 
1613
                                }
 
1614
                        }
 
1615
                        
 
1616
                        if (index!= -1) 
 
1617
                                index+= 0x10000;        // pose bones count in higher 2 bytes only
 
1618
                }
 
1619
                
 
1620
                /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet,
 
1621
                 * stick bones and/or wire custom-shapes are drawn in next loop 
 
1622
                 */
 
1623
                if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) {
 
1624
                        /* object tag, for bordersel optim */
 
1625
                        glLoadName(index & 0xFFFF);     
 
1626
                        index= -1;
 
1627
                }
 
1628
        }
 
1629
        
 
1630
        /* draw custom bone shapes as wireframes */
 
1631
        if ( !(arm->flag & ARM_NO_CUSTOM) &&
 
1632
                 ((draw_wire) || (dt <= OB_WIRE)) ) 
 
1633
        {
 
1634
                if (arm->flag & ARM_POSEMODE)
 
1635
                        index= base->selcol;
 
1636
                        
 
1637
                /* only draw custom bone shapes that need to be drawn as wires */
 
1638
                for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
1639
                        bone= pchan->bone;
 
1640
                        
 
1641
                        if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
 
1642
                                if (bone->layer & arm->layer) {
 
1643
                                        if (pchan->custom) {
 
1644
                                                if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
 
1645
                                                        glPushMatrix();
 
1646
                                                        glMultMatrixf(pchan->pose_mat);
 
1647
                                                        
 
1648
                                                        /* prepare colors */
 
1649
                                                        if (arm->flag & ARM_POSEMODE)   
 
1650
                                                                set_pchan_colorset(ob, pchan);
 
1651
                                                        else {
 
1652
                                                                if ((G.scene->basact)==base) {
 
1653
                                                                        if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_ACTIVE);
 
1654
                                                                        else BIF_ThemeColor(TH_WIRE);
 
1655
                                                                }
 
1656
                                                                else {
 
1657
                                                                        if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_SELECT);
 
1658
                                                                        else BIF_ThemeColor(TH_WIRE);
 
1659
                                                                }
 
1660
                                                        }
 
1661
                                                                
 
1662
                                                        /* catch exception for bone with hidden parent */
 
1663
                                                        flag= bone->flag;
 
1664
                                                        if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
 
1665
                                                                flag &= ~BONE_CONNECTED;
 
1666
                                                        
 
1667
                                                        draw_custom_bone(pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length);
 
1668
                                                        
 
1669
                                                        glPopMatrix();
 
1670
                                                }
 
1671
                                        }
 
1672
                                }
 
1673
                        }
 
1674
                        
 
1675
                        if (index != -1) 
 
1676
                                index+= 0x10000;        // pose bones count in higher 2 bytes only
 
1677
                }
 
1678
                
 
1679
                if (draw_wire) {
 
1680
                        /* object tag, for bordersel optim */
 
1681
                        glLoadName(index & 0xFFFF);     
 
1682
                        index= -1;
 
1683
                }
 
1684
        }
 
1685
        
 
1686
        /* wire draw over solid only in posemode */
 
1687
        if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) {
 
1688
                /* draw line check first. we do selection indices */
 
1689
                if (arm->drawtype==ARM_LINE) {
 
1690
                        if (arm->flag & ARM_POSEMODE) 
 
1691
                                index= base->selcol;
 
1692
                }
 
1693
                /* if solid && posemode, we draw again with polygonoffset */
 
1694
                else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) {
 
1695
                        bglPolygonOffset(1.0);
 
1696
                }
 
1697
                else {
 
1698
                        /* and we use selection indices if not done yet */
 
1699
                        if (arm->flag & ARM_POSEMODE) 
 
1700
                                index= base->selcol;
 
1701
                }
 
1702
                
 
1703
                for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
1704
                        bone= pchan->bone;
 
1705
                        
 
1706
                        if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
 
1707
                                if (bone->layer & arm->layer) {
 
1708
                                        if ((do_dashed & 1) && (bone->parent)) {
 
1709
                                                /* Draw a line from our root to the parent's tip 
 
1710
                                                 *      - only if V3D_HIDE_HELPLINES is enabled...
 
1711
                                                 */
 
1712
                                                if ( (do_dashed & 2) && ((bone->flag & BONE_CONNECTED)==0) ) {
 
1713
                                                        if (arm->flag & ARM_POSEMODE) {
 
1714
                                                                glLoadName(index & 0xFFFF);     // object tag, for bordersel optim
 
1715
                                                                BIF_ThemeColor(TH_WIRE);
 
1716
                                                        }
 
1717
                                                        setlinestyle(3);
 
1718
                                                        glBegin(GL_LINES);
 
1719
                                                        glVertex3fv(pchan->pose_head);
 
1720
                                                        glVertex3fv(pchan->parent->pose_tail);
 
1721
                                                        glEnd();
 
1722
                                                        setlinestyle(0);
 
1723
                                                }
 
1724
                                                
 
1725
                                                /* Draw a line to IK root bone 
 
1726
                                                 *      - only if temporary chain (i.e. "autoik")
 
1727
                                                 */
 
1728
                                                if (arm->flag & ARM_POSEMODE) {
 
1729
                                                        if (pchan->constflag & PCHAN_HAS_IK) {
 
1730
                                                                if (bone->flag & BONE_SELECTED) {
 
1731
                                                                        if (pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
 
1732
                                                                        else glColor3ub(200, 200, 50);  // add theme!
 
1733
                                                                        
 
1734
                                                                        glLoadName(index & 0xFFFF);
 
1735
                                                                        pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
 
1736
                                                                }
 
1737
                                                        }
 
1738
                                                }
 
1739
                                        }
 
1740
                                        
 
1741
                                        glPushMatrix();
 
1742
                                        if (arm->drawtype != ARM_ENVELOPE)
 
1743
                                                glMultMatrixf(pchan->pose_mat);
 
1744
                                        
 
1745
                                        /* catch exception for bone with hidden parent */
 
1746
                                        flag= bone->flag;
 
1747
                                        if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
 
1748
                                                flag &= ~BONE_CONNECTED;
 
1749
                                        
 
1750
                                        /* extra draw service for pose mode */
 
1751
                                        constflag= pchan->constflag;
 
1752
                                        if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
 
1753
                                                constflag |= PCHAN_HAS_ACTION;
 
1754
                                        if (pchan->flag & POSE_STRIDE)
 
1755
                                                constflag |= PCHAN_HAS_STRIDE;
 
1756
                                                
 
1757
                                        /* set color-set to use */
 
1758
                                        set_pchan_colorset(ob, pchan);
 
1759
                                        
 
1760
                                        if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM))
 
1761
                                                ; // custom bone shapes should not be drawn here!
 
1762
                                        else if (arm->drawtype==ARM_ENVELOPE) {
 
1763
                                                if (dt < OB_SOLID)
 
1764
                                                        draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL);
 
1765
                                        }
 
1766
                                        else if (arm->drawtype==ARM_LINE)
 
1767
                                                draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
 
1768
                                        else if (arm->drawtype==ARM_B_BONE)
 
1769
                                                draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
 
1770
                                        else
 
1771
                                                draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
 
1772
                                        
 
1773
                                        glPopMatrix();
 
1774
                                }
 
1775
                        }
 
1776
                        
 
1777
                        /* pose bones count in higher 2 bytes only */
 
1778
                        if (index != -1) 
 
1779
                                index+= 0x10000;        
 
1780
                }
 
1781
                /* restore things */
 
1782
                if ((arm->drawtype!=ARM_LINE)&& (dt>OB_WIRE) && (arm->flag & ARM_POSEMODE))
 
1783
                        bglPolygonOffset(0.0);
 
1784
        }       
 
1785
        
 
1786
        /* restore */
 
1787
        glDisable(GL_CULL_FACE);
 
1788
        
 
1789
        /* draw DoFs */
 
1790
        if (arm->flag & ARM_POSEMODE)
 
1791
                draw_pose_dofs(ob);
 
1792
 
 
1793
        /* finally names and axes */
 
1794
        if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
 
1795
                /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
 
1796
                if ((G.f & G_PICKSEL) == 0) {
 
1797
                        float vec[3];
 
1798
                        
 
1799
                        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
1800
                        
 
1801
                        for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
 
1802
                                if ((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) {
 
1803
                                        if (pchan->bone->layer & arm->layer) {
 
1804
                                                if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) {
 
1805
                                                        bone= pchan->bone;
 
1806
                                                        
 
1807
                                                        if (bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
 
1808
                                                        else BIF_ThemeColor(TH_TEXT);
 
1809
                                                }
 
1810
                                                else if (dt > OB_WIRE)
 
1811
                                                        BIF_ThemeColor(TH_TEXT);
 
1812
                                                
 
1813
                                                /*      Draw names of bone      */
 
1814
                                                if (arm->flag & ARM_DRAWNAMES) {
 
1815
                                                        VecMidf(vec, pchan->pose_head, pchan->pose_tail);
 
1816
                                                        glRasterPos3fv(vec);
 
1817
                                                        BMF_DrawString(G.font, " ");
 
1818
                                                        BMF_DrawString(G.font, pchan->name);
 
1819
                                                }       
 
1820
                                                
 
1821
                                                /*      Draw additional axes on the bone tail  */
 
1822
                                                if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) {
 
1823
                                                        glPushMatrix();
 
1824
                                                        glMultMatrixf(pchan->pose_mat);
 
1825
                                                        glTranslatef(0.0f, pchan->bone->length, 0.0f);
 
1826
                                                        drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS);
 
1827
                                                        glPopMatrix();
 
1828
                                                }
 
1829
                                        }
 
1830
                                }
 
1831
                        }
 
1832
                        
 
1833
                        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
1834
                }
 
1835
        }
 
1836
}
 
1837
 
 
1838
/* in editmode, we don't store the bone matrix... */
 
1839
static void set_matrix_editbone(EditBone *eBone)
 
1840
{
 
1841
        float           delta[3],offset[3];
 
1842
        float           mat[3][3], bmat[4][4];
 
1843
        
 
1844
        /* Compose the parent transforms (i.e. their translations) */
 
1845
        VECCOPY(offset, eBone->head);
 
1846
        
 
1847
        glTranslatef(offset[0],offset[1],offset[2]);
 
1848
        
 
1849
        VecSubf(delta, eBone->tail, eBone->head);       
 
1850
        
 
1851
        eBone->length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
 
1852
        
 
1853
        vec_roll_to_mat3(delta, eBone->roll, mat);
 
1854
        Mat4CpyMat3(bmat, mat);
 
1855
                
 
1856
        glMultMatrixf(bmat);
 
1857
        
 
1858
}
 
1859
 
 
1860
static void draw_ebones(Object *ob, int dt)
 
1861
{
 
1862
        EditBone *eBone;
 
1863
        bArmature *arm= ob->data;
 
1864
        float smat[4][4], imat[4][4];
 
1865
        unsigned int index;
 
1866
        int flag;
 
1867
        
 
1868
        /* envelope (deform distance) */
 
1869
        if(arm->drawtype==ARM_ENVELOPE) {
 
1870
                /* precalc inverse matrix for drawing screen aligned */
 
1871
                mygetmatrix(smat);
 
1872
                Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
 
1873
                Mat4Invert(imat, smat);
 
1874
                
 
1875
                /* and draw blended distances */
 
1876
                glEnable(GL_BLEND);
 
1877
                //glShadeModel(GL_SMOOTH);
 
1878
                
 
1879
                if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
1880
 
 
1881
                for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
 
1882
                        if (eBone->layer & arm->layer) {
 
1883
                                if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) {
 
1884
                                        if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
 
1885
                                                draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone);
 
1886
                                }
 
1887
                        }
 
1888
                }
 
1889
                
 
1890
                if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
1891
                glDisable(GL_BLEND);
 
1892
                //glShadeModel(GL_FLAT);
 
1893
        }
 
1894
        
 
1895
        /* if solid we draw it first */
 
1896
        if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) {
 
1897
                index= 0;
 
1898
                for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
 
1899
                        if (eBone->layer & arm->layer) {
 
1900
                                if ((eBone->flag & BONE_HIDDEN_A)==0) {
 
1901
                                        glPushMatrix();
 
1902
                                        set_matrix_editbone(eBone);
 
1903
                                        
 
1904
                                        /* catch exception for bone with hidden parent */
 
1905
                                        flag= eBone->flag;
 
1906
                                        if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
 
1907
                                                flag &= ~BONE_CONNECTED;
 
1908
                                        
 
1909
                                        if (arm->drawtype==ARM_ENVELOPE)
 
1910
                                                draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
 
1911
                                        else if(arm->drawtype==ARM_B_BONE)
 
1912
                                                draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
 
1913
                                        else {
 
1914
                                                draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
 
1915
                                        }
 
1916
                                        
 
1917
                                        glPopMatrix();
 
1918
                                }
 
1919
                        }
 
1920
                }
 
1921
        }
 
1922
        
 
1923
        /* if wire over solid, set offset */
 
1924
        index= -1;
 
1925
        glLoadName(-1);
 
1926
        if (arm->drawtype==ARM_LINE) {
 
1927
                if(G.f & G_PICKSEL)
 
1928
                        index= 0;
 
1929
        }
 
1930
        else if (dt > OB_WIRE) 
 
1931
                bglPolygonOffset(1.0);
 
1932
        else if (arm->flag & ARM_EDITMODE) 
 
1933
                index= 0;       /* do selection codes */
 
1934
        
 
1935
        for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
 
1936
                if (eBone->layer & arm->layer) {
 
1937
                        if ((eBone->flag & BONE_HIDDEN_A)==0) {
 
1938
                                
 
1939
                                /* catch exception for bone with hidden parent */
 
1940
                                flag= eBone->flag;
 
1941
                                if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
 
1942
                                        flag &= ~BONE_CONNECTED;
 
1943
                                
 
1944
                                if (arm->drawtype == ARM_ENVELOPE) {
 
1945
                                        if (dt < OB_SOLID)
 
1946
                                                draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
 
1947
                                }
 
1948
                                else {
 
1949
                                        glPushMatrix();
 
1950
                                        set_matrix_editbone(eBone);
 
1951
                                        
 
1952
                                        if (arm->drawtype == ARM_LINE) 
 
1953
                                                draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
 
1954
                                        else if (arm->drawtype == ARM_B_BONE)
 
1955
                                                draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
 
1956
                                        else
 
1957
                                                draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
 
1958
                                        
 
1959
                                        glPopMatrix();
 
1960
                                }
 
1961
                                
 
1962
                                /* offset to parent */
 
1963
                                if (eBone->parent) {
 
1964
                                        BIF_ThemeColor(TH_WIRE);
 
1965
                                        glLoadName (-1);                // -1 here is OK!
 
1966
                                        setlinestyle(3);
 
1967
                                        
 
1968
                                        glBegin(GL_LINES);
 
1969
                                        glVertex3fv(eBone->parent->tail);
 
1970
                                        glVertex3fv(eBone->head);
 
1971
                                        glEnd();
 
1972
                                        
 
1973
                                        setlinestyle(0);
 
1974
                                }
 
1975
                        }
 
1976
                }
 
1977
                if(index!=-1) index++;
 
1978
        }
 
1979
        
 
1980
        /* restore */
 
1981
        if (arm->drawtype==ARM_LINE);
 
1982
        else if (dt>OB_WIRE) bglPolygonOffset(0.0);
 
1983
        
 
1984
        /* finally names and axes */
 
1985
        if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
 
1986
                // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
 
1987
                if ((G.f & G_PICKSEL) == 0) {
 
1988
                        float vec[3];
 
1989
                        
 
1990
                        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
1991
                        
 
1992
                        for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
 
1993
                                if(eBone->layer & arm->layer) {
 
1994
                                        if ((eBone->flag & BONE_HIDDEN_A)==0) {
 
1995
                                                
 
1996
                                                if (eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
 
1997
                                                else BIF_ThemeColor(TH_TEXT);
 
1998
                                                
 
1999
                                                /*      Draw name */
 
2000
                                                if (arm->flag & ARM_DRAWNAMES) {
 
2001
                                                        VecMidf(vec, eBone->head, eBone->tail);
 
2002
                                                        glRasterPos3fv(vec);
 
2003
                                                        BMF_DrawString(G.font, " ");
 
2004
                                                        BMF_DrawString(G.font, eBone->name);
 
2005
                                                }                                       
 
2006
                                                /*      Draw additional axes */
 
2007
                                                if (arm->flag & ARM_DRAWAXES) {
 
2008
                                                        glPushMatrix();
 
2009
                                                        set_matrix_editbone(eBone);
 
2010
                                                        glTranslatef(0.0f, eBone->length, 0.0f);
 
2011
                                                        drawaxes(eBone->length*0.25f, 0, OB_ARROWS);
 
2012
                                                        glPopMatrix();
 
2013
                                                }
 
2014
                                                
 
2015
                                        }
 
2016
                                }
 
2017
                        }
 
2018
                        
 
2019
                        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
2020
                }
 
2021
        }
 
2022
}
 
2023
 
 
2024
/* ****************************** Armature Visualisation ******************************** */
 
2025
 
 
2026
/* ---------- Paths --------- */
 
2027
 
 
2028
/* draw bone paths
 
2029
 *      - in view space 
 
2030
 */
 
2031
static void draw_pose_paths(Object *ob)
 
2032
{
 
2033
        bArmature *arm= ob->data;
 
2034
        bPoseChannel *pchan;
 
2035
        bAction *act;
 
2036
        bActionChannel *achan;
 
2037
        ActKeyColumn *ak;
 
2038
        ListBase keys;
 
2039
        float *fp, *fp_start;
 
2040
        int a, stepsize;
 
2041
        int sfra, efra, len;
 
2042
        
 
2043
        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
2044
        
 
2045
        glPushMatrix();
 
2046
        glLoadMatrixf(G.vd->viewmat);
 
2047
        
 
2048
        /* version patch here - cannot access frame info from file reading */
 
2049
        if (arm->pathsize == 0) arm->pathsize= 1;
 
2050
        stepsize = arm->pathsize;
 
2051
        
 
2052
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
 
2053
                if (pchan->bone->layer & arm->layer) {
 
2054
                        if (pchan->path) {
 
2055
                                /* version patch here - cannot access frame info from file reading */
 
2056
                                if ((pchan->pathsf == 0) || (pchan->pathef == 0)) {
 
2057
                                        pchan->pathsf= SFRA;
 
2058
                                        pchan->pathef= EFRA;
 
2059
                                }
 
2060
                                
 
2061
                                /* get frame ranges */
 
2062
                                if (arm->pathflag & ARM_PATH_ACFRA) {
 
2063
                                        int sind;
 
2064
                                        
 
2065
                                        /* With "Around Current", we only choose frames from around 
 
2066
                                         * the current frame to draw. However, this range is still 
 
2067
                                         * restricted by the limits of the original path.
 
2068
                                         */
 
2069
                                        sfra= CFRA - arm->pathbc;
 
2070
                                        efra= CFRA + arm->pathac;
 
2071
                                        if (sfra < pchan->pathsf) sfra= pchan->pathsf;
 
2072
                                        if (efra > pchan->pathef) efra= pchan->pathef;
 
2073
                                        
 
2074
                                        len= efra - sfra;
 
2075
                                        
 
2076
                                        sind= sfra - pchan->pathsf;
 
2077
                                        fp_start= (pchan->path + (3*sind));
 
2078
                                }
 
2079
                                else {
 
2080
                                        sfra= pchan->pathsf;
 
2081
                                        efra = sfra + pchan->pathlen;
 
2082
                                        len = pchan->pathlen;
 
2083
                                        fp_start = pchan->path;
 
2084
                                }
 
2085
                                
 
2086
                                /* draw curve-line of path */
 
2087
                                glShadeModel(GL_SMOOTH);
 
2088
                                
 
2089
                                glBegin(GL_LINE_STRIP);                                 
 
2090
                                for (a=0, fp=fp_start; a<len; a++, fp+=3) {
 
2091
                                        float intensity; /* how faint */
 
2092
                                        
 
2093
                                        /* set color
 
2094
                                         *      - more intense for active/selected bones, less intense for unselected bones
 
2095
                                         *      - black for before current frame, green for current frame, blue for after current frame
 
2096
                                         *      - intensity decreases as distance from current frame increases
 
2097
                                         */
 
2098
                                        #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min) 
 
2099
                                        if ((a+sfra) < CFRA) {
 
2100
                                                /* black - before cfra */
 
2101
                                                if (pchan->bone->flag & BONE_SELECTED) {
 
2102
                                                        // intensity= 0.5;
 
2103
                                                        intensity = SET_INTENSITY(sfra, a, CFRA, 0.25f, 0.75f);
 
2104
                                                }
 
2105
                                                else {
 
2106
                                                        //intensity= 0.8;
 
2107
                                                        intensity = SET_INTENSITY(sfra, a, CFRA, 0.68f, 0.92f);
 
2108
                                                }
 
2109
                                                BIF_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
 
2110
                                        }
 
2111
                                        else if ((a+sfra) > CFRA) {
 
2112
                                                /* blue - after cfra */
 
2113
                                                if (pchan->bone->flag & BONE_SELECTED) {
 
2114
                                                        //intensity = 0.5;
 
2115
                                                        intensity = SET_INTENSITY(CFRA, a, efra, 0.25f, 0.75f);
 
2116
                                                }
 
2117
                                                else {
 
2118
                                                        //intensity = 0.8;
 
2119
                                                        intensity = SET_INTENSITY(CFRA, a, efra, 0.68f, 0.92f);
 
2120
                                                }
 
2121
                                                BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
 
2122
                                        }
 
2123
                                        else {
 
2124
                                                /* green - on cfra */
 
2125
                                                if (pchan->bone->flag & BONE_SELECTED) {
 
2126
                                                        intensity= 0.5;
 
2127
                                                }
 
2128
                                                else {
 
2129
                                                        intensity= 0.99;
 
2130
                                                }
 
2131
                                                BIF_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
 
2132
                                        }       
 
2133
                                        
 
2134
                                        /* draw a vertex with this color */ 
 
2135
                                        glVertex3fv(fp);
 
2136
                                }
 
2137
                                
 
2138
                                glEnd();
 
2139
                                glShadeModel(GL_FLAT);
 
2140
                                
 
2141
                                glPointSize(1.0);
 
2142
                                
 
2143
                                /* draw little black point at each frame
 
2144
                                 * NOTE: this is not really visible/noticable
 
2145
                                 */
 
2146
                                glBegin(GL_POINTS);
 
2147
                                for (a=0, fp=fp_start; a<len; a++, fp+=3) 
 
2148
                                        glVertex3fv(fp);
 
2149
                                glEnd();
 
2150
                                
 
2151
                                /* Draw little white dots at each framestep value */
 
2152
                                BIF_ThemeColor(TH_TEXT_HI);
 
2153
                                glBegin(GL_POINTS);
 
2154
                                for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) 
 
2155
                                        glVertex3fv(fp);
 
2156
                                glEnd();
 
2157
                                
 
2158
                                /* Draw frame numbers at each framestep value */
 
2159
                                if (arm->pathflag & ARM_PATH_FNUMS) {
 
2160
                                        for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) {
 
2161
                                                char str[32];
 
2162
                                                
 
2163
                                                /* only draw framenum if several consecutive highlighted points don't occur on same point */
 
2164
                                                if (a == 0) {
 
2165
                                                        glRasterPos3fv(fp);
 
2166
                                                        sprintf(str, "  %d\n", (a+sfra));
 
2167
                                                        BMF_DrawString(G.font, str);
 
2168
                                                }
 
2169
                                                else if ((a > stepsize) && (a < len-stepsize)) { 
 
2170
                                                        if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) {
 
2171
                                                                glRasterPos3fv(fp);
 
2172
                                                                sprintf(str, "  %d\n", (a+sfra));
 
2173
                                                                BMF_DrawString(G.font, str);
 
2174
                                                        }
 
2175
                                                }
 
2176
                                        }
 
2177
                                }
 
2178
                                
 
2179
                                /* Keyframes - dots and numbers */
 
2180
                                if (arm->pathflag & ARM_PATH_KFRAS) {
 
2181
                                        /* build list of all keyframes in active action for pchan */
 
2182
                                        keys.first = keys.last = NULL;  
 
2183
                                        act= ob_get_action(ob);
 
2184
                                        if (act) {
 
2185
                                                achan= get_action_channel(act, pchan->name);
 
2186
                                                if (achan) 
 
2187
                                                        ipo_to_keylist(achan->ipo, &keys, NULL, NULL);
 
2188
                                        }
 
2189
                                        
 
2190
                                        /* Draw slightly-larger yellow dots at each keyframe */
 
2191
                                        BIF_ThemeColor(TH_VERTEX_SELECT);
 
2192
                                        glPointSize(5.0);
 
2193
                                        
 
2194
                                        glBegin(GL_POINTS);
 
2195
                                        for (a=0, fp=fp_start; a<len; a++, fp+=3) {
 
2196
                                                for (ak= keys.first; ak; ak= ak->next) {
 
2197
                                                        if (ak->cfra == (a+sfra))
 
2198
                                                                glVertex3fv(fp);
 
2199
                                                }
 
2200
                                        }
 
2201
                                        glEnd();
 
2202
                                        
 
2203
                                        glPointSize(1.0);
 
2204
                                        
 
2205
                                        /* Draw frame numbers of keyframes  */
 
2206
                                        if ((arm->pathflag & ARM_PATH_FNUMS) || (arm->pathflag & ARM_PATH_KFNOS)) {
 
2207
                                                for(a=0, fp=fp_start; a<len; a++, fp+=3) {
 
2208
                                                        for (ak= keys.first; ak; ak= ak->next) {
 
2209
                                                                if (ak->cfra == (a+sfra)) {
 
2210
                                                                        char str[32];
 
2211
                                                                        
 
2212
                                                                        glRasterPos3fv(fp);
 
2213
                                                                        sprintf(str, "  %d\n", (a+sfra));
 
2214
                                                                        BMF_DrawString(G.font, str);
 
2215
                                                                }
 
2216
                                                        }
 
2217
                                                }
 
2218
                                        }
 
2219
                                        
 
2220
                                        BLI_freelistN(&keys);
 
2221
                                }
 
2222
                        }
 
2223
                }
 
2224
        }
 
2225
        
 
2226
        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
2227
        glPopMatrix();
 
2228
}
 
2229
 
 
2230
 
 
2231
/* ---------- Ghosts --------- */
 
2232
 
 
2233
/* helper function for ghost drawing - sets/removes flags for temporarily 
 
2234
 * hiding unselected bones while drawing ghosts
 
2235
 */
 
2236
static void ghost_poses_tag_unselected(Object *ob, short unset)
 
2237
{
 
2238
        bArmature *arm= ob->data;
 
2239
        bPose *pose= ob->pose;
 
2240
        bPoseChannel *pchan;
 
2241
        
 
2242
        /* don't do anything if no hiding any bones */
 
2243
        if ((arm->flag & ARM_GHOST_ONLYSEL)==0)
 
2244
                return;
 
2245
                
 
2246
        /* loop over all pchans, adding/removing tags as appropriate */
 
2247
        for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
 
2248
                if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
 
2249
                        if (unset) {
 
2250
                                /* remove tags from all pchans if cleaning up */
 
2251
                                pchan->bone->flag &= ~BONE_HIDDEN_PG;
 
2252
                        }
 
2253
                        else {
 
2254
                                /* set tags on unselected pchans only */
 
2255
                                if ((pchan->bone->flag & BONE_SELECTED)==0)
 
2256
                                        pchan->bone->flag |= BONE_HIDDEN_PG;
 
2257
                        }
 
2258
                }
 
2259
        }
 
2260
}
 
2261
 
 
2262
/* draw ghosts that occur within a frame range 
 
2263
 *      note: object should be in posemode 
 
2264
 */
 
2265
static void draw_ghost_poses_range(Base *base)
 
2266
{
 
2267
        Object *ob= base->object;
 
2268
        bArmature *arm= ob->data;
 
2269
        bPose *posen, *poseo;
 
2270
        float start, end, stepsize, range, colfac;
 
2271
        int cfrao, flago, ipoflago;
 
2272
        
 
2273
        start = arm->ghostsf;
 
2274
        end = arm->ghostef;
 
2275
        if (end <= start)
 
2276
                return;
 
2277
        
 
2278
        stepsize= (float)(arm->ghostsize);
 
2279
        range= (float)(end - start);
 
2280
        
 
2281
        /* store values */
 
2282
        ob->flag &= ~OB_POSEMODE;
 
2283
        cfrao= CFRA;
 
2284
        flago= arm->flag;
 
2285
        arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
 
2286
        ipoflago= ob->ipoflag; 
 
2287
        ob->ipoflag |= OB_DISABLE_PATH;
 
2288
        
 
2289
        /* copy the pose */
 
2290
        poseo= ob->pose;
 
2291
        copy_pose(&posen, ob->pose, 1);
 
2292
        ob->pose= posen;
 
2293
        armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
 
2294
        ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
 
2295
        
 
2296
        glEnable(GL_BLEND);
 
2297
        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
2298
        
 
2299
        /* draw from first frame of range to last */
 
2300
        for (CFRA= start; CFRA<end; CFRA+=stepsize) {
 
2301
                colfac = (end-CFRA)/range;
 
2302
                BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
 
2303
                
 
2304
                do_all_pose_actions(ob);
 
2305
                where_is_pose(ob);
 
2306
                draw_pose_channels(base, OB_WIRE);
 
2307
        }
 
2308
        glDisable(GL_BLEND);
 
2309
        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
2310
 
 
2311
        ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
 
2312
        free_pose(posen);
 
2313
        
 
2314
        /* restore */
 
2315
        CFRA= cfrao;
 
2316
        ob->pose= poseo;
 
2317
        arm->flag= flago;
 
2318
        armature_rebuild_pose(ob, ob->data);
 
2319
        ob->flag |= OB_POSEMODE;
 
2320
        ob->ipoflag= ipoflago; 
 
2321
}
 
2322
 
 
2323
/* draw ghosts on keyframes in action within range 
 
2324
 *      - object should be in posemode 
 
2325
 */
 
2326
static void draw_ghost_poses_keys(Base *base)
 
2327
{
 
2328
        Object *ob= base->object;
 
2329
        bAction *act= ob_get_action(ob);
 
2330
        bArmature *arm= ob->data;
 
2331
        bPose *posen, *poseo;
 
2332
        ListBase keys= {NULL, NULL};
 
2333
        ActKeysInc aki = {0, 0, 0};
 
2334
        ActKeyColumn *ak, *akn;
 
2335
        float start, end, range, colfac, i;
 
2336
        int cfrao, flago, ipoflago;
 
2337
        
 
2338
        aki.start= start = arm->ghostsf;
 
2339
        aki.end= end = arm->ghostef;
 
2340
        if (end <= start)
 
2341
                return;
 
2342
        
 
2343
        /* get keyframes - then clip to only within range */
 
2344
        action_to_keylist(act, &keys, NULL, &aki);
 
2345
        range= 0;
 
2346
        for (ak= keys.first; ak; ak= akn) {
 
2347
                akn= ak->next;
 
2348
                
 
2349
                if ((ak->cfra < start) || (ak->cfra > end))
 
2350
                        BLI_freelinkN(&keys, ak);
 
2351
                else
 
2352
                        range++;
 
2353
        }
 
2354
        if (range == 0) return;
 
2355
        
 
2356
        /* store values */
 
2357
        ob->flag &= ~OB_POSEMODE;
 
2358
        cfrao= CFRA;
 
2359
        flago= arm->flag;
 
2360
        arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
 
2361
        ipoflago= ob->ipoflag; 
 
2362
        ob->ipoflag |= OB_DISABLE_PATH;
 
2363
        
 
2364
        /* copy the pose */
 
2365
        poseo= ob->pose;
 
2366
        copy_pose(&posen, ob->pose, 1);
 
2367
        ob->pose= posen;
 
2368
        armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
 
2369
        ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
 
2370
        
 
2371
        glEnable(GL_BLEND);
 
2372
        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
2373
        
 
2374
        /* draw from first frame of range to last */
 
2375
        for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
 
2376
                colfac = i/range;
 
2377
                BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
 
2378
                
 
2379
                CFRA= (int)ak->cfra;
 
2380
                
 
2381
                do_all_pose_actions(ob);
 
2382
                where_is_pose(ob);
 
2383
                draw_pose_channels(base, OB_WIRE);
 
2384
        }
 
2385
        glDisable(GL_BLEND);
 
2386
        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
2387
 
 
2388
        ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
 
2389
        BLI_freelistN(&keys);
 
2390
        free_pose(posen);
 
2391
        
 
2392
        /* restore */
 
2393
        CFRA= cfrao;
 
2394
        ob->pose= poseo;
 
2395
        arm->flag= flago;
 
2396
        armature_rebuild_pose(ob, ob->data);
 
2397
        ob->flag |= OB_POSEMODE;
 
2398
        ob->ipoflag= ipoflago; 
 
2399
}
 
2400
 
 
2401
/* draw ghosts around current frame
 
2402
 *      - object is supposed to be armature in posemode 
 
2403
 */
 
2404
static void draw_ghost_poses(Base *base)
 
2405
{
 
2406
        Object *ob= base->object;
 
2407
        bArmature *arm= ob->data;
 
2408
        bPose *posen, *poseo;
 
2409
        bActionStrip *strip;
 
2410
        float cur, start, end, stepsize, range, colfac, actframe, ctime;
 
2411
        int cfrao, maptime, flago, ipoflago;
 
2412
        
 
2413
        /* pre conditions, get an action with sufficient frames */
 
2414
        if (ob->action==NULL)
 
2415
                return;
 
2416
 
 
2417
        calc_action_range(ob->action, &start, &end, 0);
 
2418
        if (start == end)
 
2419
                return;
 
2420
 
 
2421
        stepsize= (float)(arm->ghostsize);
 
2422
        range= (float)(arm->ghostep)*stepsize + 0.5f;   /* plus half to make the for loop end correct */
 
2423
        
 
2424
        /* we only map time for armature when an active strip exists */
 
2425
        for (strip=ob->nlastrips.first; strip; strip=strip->next)
 
2426
                if (strip->flag & ACTSTRIP_ACTIVE)
 
2427
                        break;
 
2428
        
 
2429
        maptime= (strip!=NULL);
 
2430
        
 
2431
        /* store values */
 
2432
        ob->flag &= ~OB_POSEMODE;
 
2433
        cfrao= CFRA;
 
2434
        if (maptime) actframe= get_action_frame(ob, (float)CFRA);
 
2435
        else actframe= CFRA;
 
2436
        flago= arm->flag;
 
2437
        arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
 
2438
        ipoflago= ob->ipoflag; 
 
2439
        ob->ipoflag |= OB_DISABLE_PATH;
 
2440
        
 
2441
        /* copy the pose */
 
2442
        poseo= ob->pose;
 
2443
        copy_pose(&posen, ob->pose, 1);
 
2444
        ob->pose= posen;
 
2445
        armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
 
2446
        ghost_poses_tag_unselected(ob, 0);              /* hide unselected bones if need be */
 
2447
        
 
2448
        glEnable(GL_BLEND);
 
2449
        if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
 
2450
        
 
2451
        /* draw from darkest blend to lowest */
 
2452
        for(cur= stepsize; cur<range; cur+=stepsize) {
 
2453
                ctime= cur - fmod((float)cfrao, stepsize);      /* ensures consistant stepping */
 
2454
                colfac= ctime/range;
 
2455
                BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
 
2456
                
 
2457
                /* only within action range */
 
2458
                if (actframe+ctime >= start && actframe+ctime <= end) {
 
2459
                        if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe+ctime);
 
2460
                        else CFRA= (int)floor(actframe+ctime);
 
2461
                        
 
2462
                        if (CFRA!=cfrao) {
 
2463
                                do_all_pose_actions(ob);
 
2464
                                where_is_pose(ob);
 
2465
                                draw_pose_channels(base, OB_WIRE);
 
2466
                        }
 
2467
                }
 
2468
                
 
2469
                ctime= cur + fmod((float)cfrao, stepsize) - stepsize+1.0f;      /* ensures consistant stepping */
 
2470
                colfac= ctime/range;
 
2471
                BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
 
2472
                
 
2473
                /* only within action range */
 
2474
                if ((actframe-ctime >= start) && (actframe-ctime <= end)) {
 
2475
                        if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe-ctime);
 
2476
                        else CFRA= (int)floor(actframe-ctime);
 
2477
                        
 
2478
                        if (CFRA != cfrao) {
 
2479
                                do_all_pose_actions(ob);
 
2480
                                where_is_pose(ob);
 
2481
                                draw_pose_channels(base, OB_WIRE);
 
2482
                        }
 
2483
                }
 
2484
        }
 
2485
        glDisable(GL_BLEND);
 
2486
        if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
2487
 
 
2488
        ghost_poses_tag_unselected(ob, 1);              /* unhide unselected bones if need be */
 
2489
        free_pose(posen);
 
2490
        
 
2491
        /* restore */
 
2492
        CFRA= cfrao;
 
2493
        ob->pose= poseo;
 
2494
        arm->flag= flago;
 
2495
        armature_rebuild_pose(ob, ob->data);
 
2496
        ob->flag |= OB_POSEMODE;
 
2497
        ob->ipoflag= ipoflago; 
 
2498
}
 
2499
 
 
2500
/* ********************************** Armature Drawing - Main ************************* */
 
2501
 
 
2502
/* called from drawobject.c, return 1 if nothing was drawn */
 
2503
int draw_armature(Base *base, int dt, int flag)
 
2504
{
 
2505
        Object *ob= base->object;
 
2506
        bArmature *arm= ob->data;
 
2507
        int retval= 0;
 
2508
 
 
2509
        if(G.f & G_RENDER_SHADOW)
 
2510
                return 1;
 
2511
        
 
2512
        if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) {
 
2513
                /* we use color for solid lighting */
 
2514
                glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
 
2515
                glEnable(GL_COLOR_MATERIAL);
 
2516
                glColor3ub(0,0,0);      // clear spec
 
2517
                glDisable(GL_COLOR_MATERIAL);
 
2518
                
 
2519
                glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
 
2520
                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting...
 
2521
        }
 
2522
        
 
2523
        /* arm->flag is being used to detect mode... */
 
2524
        /* editmode? */
 
2525
        if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
 
2526
                if(ob==G.obedit) arm->flag |= ARM_EDITMODE;
 
2527
                draw_ebones(ob, dt);
 
2528
                arm->flag &= ~ARM_EDITMODE;
 
2529
        }
 
2530
        else{
 
2531
                /*      Draw Pose */
 
2532
                if(ob->pose && ob->pose->chanbase.first) {
 
2533
                        /* drawing posemode selection indices or colors only in these cases */
 
2534
                        if(!(base->flag & OB_FROMDUPLI)) {
 
2535
                                if(G.f & G_PICKSEL) {
 
2536
                                        if(ob->flag & OB_POSEMODE) 
 
2537
                                                arm->flag |= ARM_POSEMODE;
 
2538
                                }
 
2539
                                else if(ob->flag & OB_POSEMODE) {
 
2540
                                        if (arm->ghosttype == ARM_GHOST_RANGE) {
 
2541
                                                draw_ghost_poses_range(base);
 
2542
                                        }
 
2543
                                        else if (arm->ghosttype == ARM_GHOST_KEYS) {
 
2544
                                                draw_ghost_poses_keys(base);
 
2545
                                        }
 
2546
                                        else if (arm->ghosttype == ARM_GHOST_CUR) {
 
2547
                                                if (arm->ghostep)
 
2548
                                                        draw_ghost_poses(base);
 
2549
                                        }
 
2550
                                        if ((flag & DRAW_SCENESET)==0) {
 
2551
                                                if(ob==OBACT) 
 
2552
                                                        arm->flag |= ARM_POSEMODE;
 
2553
                                                else if(G.f & G_WEIGHTPAINT)
 
2554
                                                        arm->flag |= ARM_POSEMODE;
 
2555
                                        
 
2556
                                                draw_pose_paths(ob);
 
2557
                                        }
 
2558
                                }       
 
2559
                        }
 
2560
                        draw_pose_channels(base, dt);
 
2561
                        arm->flag &= ~ARM_POSEMODE; 
 
2562
                        
 
2563
                        if(ob->flag & OB_POSEMODE)
 
2564
                                BIF_ThemeColor(TH_WIRE);        /* restore, for extra draw stuff */
 
2565
                }
 
2566
                else retval= 1;
 
2567
        }
 
2568
        /* restore */
 
2569
        glFrontFace(GL_CCW);
 
2570
 
 
2571
        return retval;
 
2572
}
 
2573
 
 
2574
/* *************** END Armature drawing ******************* */
 
2575
 
 
2576