LEFT | RIGHT |
(no file at all) | |
1 /* | 1 /* |
2 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } | 210 } |
211 } | 211 } |
212 | 212 |
213 return false; | 213 return false; |
214 } | 214 } |
215 | 215 |
216 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) | 216 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) |
217 { | 217 { |
218 if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) | 218 if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) |
219 return false; | 219 return false; |
220 | 220 » return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID); |
221 » if (G.f & G_BACKBUFSEL) | 221 } |
222 » » return false; | 222 |
223 | 223 static int check_material_alpha(Base *base, Mesh *me, int glsl) |
224 » if ((vd->flag & V3D_ZBUF_SELECT) == 0) | 224 { |
225 » » return true; | 225 » if(base->flag & OB_FROMDUPLI) |
226 | 226 » » return 0; |
227 » /* if its drawing textures with zbuf sel, then don't draw dots */ | 227 |
228 » if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE) | 228 » if(G.f & G_PICKSEL) |
229 » » return false; | 229 » » return 0; |
230 | 230 » » »······· |
231 » if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX)) | 231 » if(me->edit_mesh) |
232 » » return false; | 232 » » return 0; |
233 | |
234 » return true; | |
235 } | |
236 | |
237 /* ************************ */ | |
238 | |
239 /* check for glsl drawing */ | |
240 | |
241 bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt) | |
242 { | |
243 » if (!GPU_glsl_support()) | |
244 » » return false; | |
245 » if (G.f & G_PICKSEL) | |
246 » » return false; | |
247 » if (!check_object_draw_texture(scene, v3d, dt)) | |
248 » » return false; | |
249 » if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) | |
250 » » return false; | |
251 ········ | 233 ········ |
252 if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) | 234 return (glsl || (base->object->dtx & OB_DRAWTRANSP)); |
253 return true; | 235 } |
254 ········ | |
255 if (BKE_scene_use_new_shading_nodes(scene)) | |
256 return false; | |
257 ········ | |
258 return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID); | |
259 } | |
260 | |
261 static bool check_alpha_pass(Base *base) | |
262 { | |
263 if (base->flag & OB_FROMDUPLI) | |
264 return false; | |
265 | |
266 if (G.f & G_PICKSEL) | |
267 return false; | |
268 | |
269 if (base->object->mode & OB_MODE_ALL_PAINT) | |
270 return false; | |
271 | |
272 return (base->object->dtx & OB_DRAWTRANSP); | |
273 } | |
274 | |
275 /***/ | |
276 static const unsigned int colortab[] = { | |
277 0x0, 0x403000, 0xFFFF88 | |
278 }; | |
279 | |
280 /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed
------------------ */ | |
281 /* 32 values of sin function (still same result!) */ | |
282 #define CIRCLE_RESOL 32 | |
283 | |
284 static const float sinval[CIRCLE_RESOL] = { | |
285 0.00000000, | |
286 0.20129852, | |
287 0.39435585, | |
288 0.57126821, | |
289 0.72479278, | |
290 0.84864425, | |
291 0.93775213, | |
292 0.98846832, | |
293 0.99871650, | |
294 0.96807711, | |
295 0.89780453, | |
296 0.79077573, | |
297 0.65137248, | |
298 0.48530196, | |
299 0.29936312, | |
300 0.10116832, | |
301 -0.10116832, | |
302 -0.29936312, | |
303 -0.48530196, | |
304 -0.65137248, | |
305 -0.79077573, | |
306 -0.89780453, | |
307 -0.96807711, | |
308 -0.99871650, | |
309 -0.98846832, | |
310 -0.93775213, | |
311 -0.84864425, | |
312 -0.72479278, | |
313 -0.57126821, | |
314 -0.39435585, | |
315 -0.20129852, | |
316 0.00000000 | |
317 }; | |
318 | |
319 /* 32 values of cos function (still same result!) */ | |
320 static const float cosval[CIRCLE_RESOL] = { | |
321 1.00000000, | |
322 0.97952994, | |
323 0.91895781, | |
324 0.82076344, | |
325 0.68896691, | |
326 0.52896401, | |
327 0.34730525, | |
328 0.15142777, | |
329 -0.05064916, | |
330 -0.25065253, | |
331 -0.44039415, | |
332 -0.61210598, | |
333 -0.75875812, | |
334 -0.87434661, | |
335 -0.95413925, | |
336 -0.99486932, | |
337 -0.99486932, | |
338 -0.95413925, | |
339 -0.87434661, | |
340 -0.75875812, | |
341 -0.61210598, | |
342 -0.44039415, | |
343 -0.25065253, | |
344 -0.05064916, | |
345 0.15142777, | |
346 0.34730525, | |
347 0.52896401, | |
348 0.68896691, | |
349 0.82076344, | |
350 0.91895781, | |
351 0.97952994, | |
352 1.00000000 | |
353 }; | |
354 | |
355 static void draw_xyz_wire(const float c[3], float size, int axis) | |
356 { | |
357 float v1[3] = {0.f, 0.f, 0.f}, v2[3] = {0.f, 0.f, 0.f}; | |
358 float dim = size * 0.1f; | |
359 float dx[3], dy[3], dz[3]; | |
360 | |
361 dx[0] = dim; dx[1] = 0.f; dx[2] = 0.f; | |
362 dy[0] = 0.f; dy[1] = dim; dy[2] = 0.f; | |
363 dz[0] = 0.f; dz[1] = 0.f; dz[2] = dim; | |
364 | |
365 switch (axis) { | |
366 case 0: /* x axis */ | |
367 glBegin(GL_LINES); | |
368 ························ | |
369 /* bottom left to top right */ | |
370 sub_v3_v3v3(v1, c, dx); | |
371 sub_v3_v3(v1, dy); | |
372 add_v3_v3v3(v2, c, dx); | |
373 add_v3_v3(v2, dy); | |
374 ························ | |
375 glVertex3fv(v1); | |
376 glVertex3fv(v2); | |
377 ························ | |
378 /* top left to bottom right */ | |
379 mul_v3_fl(dy, 2.f); | |
380 add_v3_v3(v1, dy); | |
381 sub_v3_v3(v2, dy); | |
382 ························ | |
383 glVertex3fv(v1); | |
384 glVertex3fv(v2); | |
385 ························ | |
386 glEnd(); | |
387 break; | |
388 case 1: /* y axis */ | |
389 glBegin(GL_LINES); | |
390 ························ | |
391 /* bottom left to top right */ | |
392 mul_v3_fl(dx, 0.75f); | |
393 sub_v3_v3v3(v1, c, dx); | |
394 sub_v3_v3(v1, dy); | |
395 add_v3_v3v3(v2, c, dx); | |
396 add_v3_v3(v2, dy); | |
397 ························ | |
398 glVertex3fv(v1); | |
399 glVertex3fv(v2); | |
400 ························ | |
401 /* top left to center */ | |
402 mul_v3_fl(dy, 2.f); | |
403 add_v3_v3(v1, dy); | |
404 copy_v3_v3(v2, c); | |
405 ························ | |
406 glVertex3fv(v1); | |
407 glVertex3fv(v2); | |
408 ························ | |
409 glEnd(); | |
410 break; | |
411 case 2: /* z axis */ | |
412 glBegin(GL_LINE_STRIP); | |
413 ························ | |
414 /* start at top left */ | |
415 sub_v3_v3v3(v1, c, dx); | |
416 add_v3_v3v3(v1, c, dz); | |
417 ························ | |
418 glVertex3fv(v1); | |
419 ························ | |
420 mul_v3_fl(dx, 2.f); | |
421 add_v3_v3(v1, dx); | |
422 | |
423 glVertex3fv(v1); | |
424 ························ | |
425 mul_v3_fl(dz, 2.f); | |
426 sub_v3_v3(v1, dx); | |
427 sub_v3_v3(v1, dz); | |
428 ························ | |
429 glVertex3fv(v1); | |
430 ························ | |
431 add_v3_v3(v1, dx); | |
432 ················ | |
433 glVertex3fv(v1); | |
434 ························ | |
435 glEnd(); | |
436 break; | |
437 } | |
438 ········ | |
439 } | |
440 | |
441 void drawaxes(float size, char drawtype) | |
442 { | |
443 int axis; | |
444 float v1[3] = {0.0, 0.0, 0.0}; | |
445 float v2[3] = {0.0, 0.0, 0.0}; | |
446 float v3[3] = {0.0, 0.0, 0.0}; | |
447 ········ | |
448 switch (drawtype) { | |
449 | |
450 case OB_PLAINAXES: | |
451 for (axis = 0; axis < 3; axis++) { | |
452 glBegin(GL_LINES); | |
453 | |
454 v1[axis] = size; | |
455 v2[axis] = -size; | |
456 glVertex3fv(v1); | |
457 glVertex3fv(v2); | |
458 | |
459 /* reset v1 & v2 to zero */ | |
460 v1[axis] = v2[axis] = 0.0f; | |
461 | |
462 glEnd(); | |
463 } | |
464 break; | |
465 case OB_SINGLE_ARROW: | |
466 | |
467 glBegin(GL_LINES); | |
468 /* in positive z direction only */ | |
469 v1[2] = size; | |
470 glVertex3fv(v1); | |
471 glVertex3fv(v2); | |
472 glEnd(); | |
473 | |
474 /* square pyramid */ | |
475 glBegin(GL_TRIANGLES); | |
476 | |
477 v2[0] = size * 0.035f; v2[1] = size * 0.035f; | |
478 v3[0] = size * -0.035f; v3[1] = size * 0.035f; | |
479 v2[2] = v3[2] = size * 0.75f; | |
480 | |
481 for (axis = 0; axis < 4; axis++) { | |
482 if (axis % 2 == 1) { | |
483 v2[0] = -v2[0]; | |
484 v3[1] = -v3[1]; | |
485 } | |
486 else { | |
487 v2[1] = -v2[1]; | |
488 v3[0] = -v3[0]; | |
489 } | |
490 | |
491 glVertex3fv(v1); | |
492 glVertex3fv(v2); | |
493 glVertex3fv(v3); | |
494 | |
495 } | |
496 glEnd(); | |
497 | |
498 break; | |
499 case OB_CUBE: | |
500 drawcube_size(size); | |
501 break; | |
502 | |
503 case OB_CIRCLE: | |
504 drawcircle_size(size); | |
505 break; | |
506 | |
507 case OB_EMPTY_SPHERE: | |
508 draw_empty_sphere(size); | |
509 break; | |
510 | |
511 case OB_EMPTY_CONE: | |
512 draw_empty_cone(size); | |
513 break; | |
514 | |
515 case OB_ARROWS: | |
516 default: | |
517 { | |
518 for (axis = 0; axis < 3; axis++) { | |
519 const int arrow_axis = (axis == 0) ? 1 : 0; | |
520 | |
521 glBegin(GL_LINES); | |
522 | |
523 v2[axis] = size; | |
524 glVertex3fv(v1); | |
525 glVertex3fv(v2); | |
526 ································ | |
527 v1[axis] = size * 0.85f; | |
528 v1[arrow_axis] = -size * 0.08f; | |
529 glVertex3fv(v1); | |
530 glVertex3fv(v2); | |
531 ································ | |
532 v1[arrow_axis] = size * 0.08f; | |
533 glVertex3fv(v1); | |
534 glVertex3fv(v2); | |
535 | |
536 glEnd(); | |
537 ································ | |
538 v2[axis] += size * 0.125f; | |
539 | |
540 draw_xyz_wire(v2, size, axis); | |
541 | |
542 | |
543 /* reset v1 & v2 to zero */ | |
544 v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f; | |
545 } | |
546 break; | |
547 } | |
548 } | |
549 } | |
550 | |
551 | |
552 /* Function to draw an Image on a empty Object */ | |
553 static void draw_empty_image(Object *ob, const short dflag, const unsigned char
ob_wire_col[4]) | |
554 { | |
555 Image *ima = (Image *)ob->data; | |
556 ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL; | |
557 | |
558 float scale, ofs_x, ofs_y, sca_x, sca_y; | |
559 int ima_x, ima_y; | |
560 | |
561 if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) { | |
562 IMB_rect_from_float(ibuf); | |
563 } | |
564 | |
565 /* Get the buffer dimensions so we can fallback to fake ones */ | |
566 if (ibuf && ibuf->rect) { | |
567 ima_x = ibuf->x; | |
568 ima_y = ibuf->y; | |
569 } | |
570 else { | |
571 ima_x = 1; | |
572 ima_y = 1; | |
573 } | |
574 | |
575 /* Get the image aspect even if the buffer is invalid */ | |
576 if (ima) { | |
577 if (ima->aspx > ima->aspy) { | |
578 sca_x = 1.0f; | |
579 sca_y = ima->aspy / ima->aspx; | |
580 } | |
581 else if (ima->aspx < ima->aspy) { | |
582 sca_x = ima->aspx / ima->aspy; | |
583 sca_y = 1.0f; | |
584 } | |
585 else { | |
586 sca_x = 1.0f; | |
587 sca_y = 1.0f; | |
588 } | |
589 } | |
590 else { | |
591 sca_x = 1.0f; | |
592 sca_y = 1.0f; | |
593 } | |
594 | |
595 /* Calculate the scale center based on objects origin */ | |
596 ofs_x = ob->ima_ofs[0] * ima_x; | |
597 ofs_y = ob->ima_ofs[1] * ima_y; | |
598 | |
599 glMatrixMode(GL_MODELVIEW); | |
600 glPushMatrix(); | |
601 | |
602 /* Make sure we are drawing at the origin */ | |
603 glTranslatef(0.0f, 0.0f, 0.0f); | |
604 | |
605 /* Calculate Image scale */ | |
606 scale = (ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y
* sca_y)); | |
607 | |
608 /* Set the object scale */ | |
609 glScalef(scale * sca_x, scale * sca_y, 1.0f); | |
610 | |
611 if (ibuf && ibuf->rect) { | |
612 const bool use_clip = (U.glalphaclip != 1.0f); | |
613 /* Setup GL params */ | |
614 glEnable(GL_BLEND); | |
615 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
616 | |
617 if (use_clip) { | |
618 glEnable(GL_ALPHA_TEST); | |
619 glAlphaFunc(GL_GREATER, U.glalphaclip); | |
620 } | |
621 | |
622 /* Use the object color and alpha */ | |
623 glColor4fv(ob->col); | |
624 | |
625 /* Draw the Image on the screen */ | |
626 glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNE
D_BYTE, GL_LINEAR, ibuf->rect); | |
627 glPixelTransferf(GL_ALPHA_SCALE, 1.0f); | |
628 | |
629 glDisable(GL_BLEND); | |
630 | |
631 if (use_clip) { | |
632 glDisable(GL_ALPHA_TEST); | |
633 glAlphaFunc(GL_GREATER, 0.0f); | |
634 } | |
635 } | |
636 | |
637 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
638 glColor3ubv(ob_wire_col); | |
639 } | |
640 | |
641 /* Calculate the outline vertex positions */ | |
642 glBegin(GL_LINE_LOOP); | |
643 glVertex2f(ofs_x, ofs_y); | |
644 glVertex2f(ofs_x + ima_x, ofs_y); | |
645 glVertex2f(ofs_x + ima_x, ofs_y + ima_y); | |
646 glVertex2f(ofs_x, ofs_y + ima_y); | |
647 glEnd(); | |
648 | |
649 | |
650 /* Reset GL settings */ | |
651 glMatrixMode(GL_MODELVIEW); | |
652 glPopMatrix(); | |
653 | |
654 BKE_image_release_ibuf(ima, ibuf, NULL); | |
655 } | |
656 | |
657 static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
], float rad, float tmat[4][4]) | |
658 { | |
659 float vx[3], vy[3]; | |
660 float *viter = (float *)verts; | |
661 unsigned int a; | |
662 | |
663 mul_v3_v3fl(vx, tmat[0], rad); | |
664 mul_v3_v3fl(vy, tmat[1], rad); | |
665 | |
666 for (a = 0; a < CIRCLE_RESOL; a++, viter += 3) { | |
667 viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0]; | |
668 viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1]; | |
669 viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2]; | |
670 } | |
671 } | |
672 | |
673 void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]) | |
674 { | |
675 float verts[CIRCLE_RESOL][3]; | |
676 | |
677 circball_array_fill(verts, cent, rad, tmat); | |
678 | |
679 glEnableClientState(GL_VERTEX_ARRAY); | |
680 glVertexPointer(3, GL_FLOAT, 0, verts); | |
681 glDrawArrays(mode, 0, CIRCLE_RESOL); | |
682 glDisableClientState(GL_VERTEX_ARRAY); | |
683 } | |
684 | |
685 /* circle for object centers, special_color is for library or ob users */ | |
686 static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
int selstate, int special_color) | |
687 { | |
688 const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_di
a * 0.5f; | |
689 float verts[CIRCLE_RESOL][3]; | |
690 | |
691 /* using gldepthfunc guarantees that it does write z values, | |
692 * but not checks for it, so centers remain visible independent order of
drawing */ | |
693 if (v3d->zbuf) glDepthFunc(GL_ALWAYS); | |
694 glEnable(GL_BLEND); | |
695 ········ | |
696 if (special_color) { | |
697 if (selstate == ACTIVE || selstate == SELECT) glColor4ub(0x88, 0
xFF, 0xFF, 155); | |
698 | |
699 else glColor4ub(0x55, 0xCC, 0xCC, 155); | |
700 } | |
701 else { | |
702 if (selstate == ACTIVE) UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -8
0); | |
703 else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT,
0, -80); | |
704 else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSF
ORM, 0, -80); | |
705 } | |
706 | |
707 circball_array_fill(verts, co, size, rv3d->viewinv); | |
708 | |
709 /* enable vertex array */ | |
710 glEnableClientState(GL_VERTEX_ARRAY); | |
711 glVertexPointer(3, GL_FLOAT, 0, verts); | |
712 | |
713 /* 1. draw filled, blended polygon */ | |
714 glDrawArrays(GL_POLYGON, 0, CIRCLE_RESOL); | |
715 | |
716 /* 2. draw outline */ | |
717 UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30); | |
718 glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL); | |
719 | |
720 /* finish up */ | |
721 glDisableClientState(GL_VERTEX_ARRAY); | |
722 | |
723 glDisable(GL_BLEND); | |
724 | |
725 if (v3d->zbuf) glDepthFunc(GL_LEQUAL); | |
726 } | |
727 | |
728 /* *********** text drawing for object/particles/armature ************* */ | |
729 static ListBase CachedText[3]; | |
730 static int CachedTextLevel = 0; | |
731 | |
732 typedef struct ViewCachedString { | |
733 struct ViewCachedString *next, *prev; | |
734 float vec[3]; | |
735 union { | |
736 unsigned char ub[4]; | |
737 int pack; | |
738 } col; | |
739 short sco[2]; | |
740 short xoffs; | |
741 short flag; | |
742 int str_len, pad; | |
743 /* str is allocated past the end */ | |
744 } ViewCachedString; | |
745 | |
746 void view3d_cached_text_draw_begin(void) | |
747 { | |
748 ListBase *strings = &CachedText[CachedTextLevel]; | |
749 strings->first = strings->last = NULL; | |
750 CachedTextLevel++; | |
751 } | |
752 | |
753 void view3d_cached_text_draw_add(const float co[3], | |
754 const char *str, | |
755 short xoffs, short flag, | |
756 const unsigned char col[4]) | |
757 { | |
758 int alloc_len = strlen(str) + 1; | |
759 ListBase *strings = &CachedText[CachedTextLevel - 1]; | |
760 /* TODO, replace with more efficient malloc, perhaps memarena per draw?
*/ | |
761 ViewCachedString *vos = MEM_callocN(sizeof(ViewCachedString) + alloc_len
, "ViewCachedString"); | |
762 | |
763 BLI_addtail(strings, vos); | |
764 copy_v3_v3(vos->vec, co); | |
765 copy_v4_v4_char((char *)vos->col.ub, (const char *)col); | |
766 vos->xoffs = xoffs; | |
767 vos->flag = flag; | |
768 vos->str_len = alloc_len - 1; | |
769 | |
770 /* allocate past the end */ | |
771 memcpy(++vos, str, alloc_len); | |
772 } | |
773 | |
774 void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
at mat[4][4]) | |
775 { | |
776 RegionView3D *rv3d = ar->regiondata; | |
777 ListBase *strings = &CachedText[CachedTextLevel - 1]; | |
778 ViewCachedString *vos; | |
779 int tot = 0; | |
780 ········ | |
781 /* project first and test */ | |
782 for (vos = strings->first; vos; vos = vos->next) { | |
783 if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE)) | |
784 mul_m4_v3(mat, vos->vec); | |
785 | |
786 if (ED_view3d_project_short_ex(ar, | |
787 (vos->flag & V3D_CACHE_TEXT_GLOBA
LSPACE) ? rv3d->persmat : rv3d->persmatob, | |
788 (vos->flag & V3D_CACHE_TEXT_LOCAL
CLIP) != 0, | |
789 vos->vec, vos->sco, | |
790 V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_
TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) | |
791 { | |
792 tot++; | |
793 } | |
794 else { | |
795 vos->sco[0] = IS_CLIPPED; | |
796 } | |
797 } | |
798 | |
799 if (tot) { | |
800 int col_pack_prev = 0; | |
801 | |
802 #if 0 | |
803 bglMats mats; /* ZBuffer depth vars */ | |
804 double ux, uy, uz; | |
805 float depth; | |
806 | |
807 if (v3d->zbuf) | |
808 bgl_get_mats(&mats); | |
809 #endif | |
810 if (rv3d->rflag & RV3D_CLIPPING) { | |
811 ED_view3d_clipping_disable(); | |
812 } | |
813 | |
814 glMatrixMode(GL_PROJECTION); | |
815 glPushMatrix(); | |
816 glMatrixMode(GL_MODELVIEW); | |
817 glPushMatrix(); | |
818 ED_region_pixelspace(ar); | |
819 ················ | |
820 if (depth_write) { | |
821 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); | |
822 } | |
823 else { | |
824 glDepthMask(0); | |
825 } | |
826 ················ | |
827 for (vos = strings->first; vos; vos = vos->next) { | |
828 if (vos->sco[0] != IS_CLIPPED) { | |
829 const char *str = (char *)(vos + 1); | |
830 | |
831 if (col_pack_prev != vos->col.pack) { | |
832 glColor3ubv(vos->col.ub); | |
833 col_pack_prev = vos->col.pack; | |
834 } | |
835 | |
836 ((vos->flag & V3D_CACHE_TEXT_ASCII) ? | |
837 BLF_draw_default_ascii : | |
838 BLF_draw_default | |
839 )( (float)vos->sco[0] + vos->xoffs, | |
840 (float)vos->sco[1], | |
841 (depth_write) ? 0.0f : 2.0f, | |
842 str, | |
843 vos->str_len); | |
844 } | |
845 } | |
846 ················ | |
847 if (depth_write) { | |
848 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); | |
849 } | |
850 else { | |
851 glDepthMask(1); | |
852 } | |
853 ················ | |
854 glMatrixMode(GL_PROJECTION); | |
855 glPopMatrix(); | |
856 glMatrixMode(GL_MODELVIEW); | |
857 glPopMatrix(); | |
858 | |
859 if (rv3d->rflag & RV3D_CLIPPING) { | |
860 ED_view3d_clipping_enable(); | |
861 } | |
862 } | |
863 ········ | |
864 if (strings->first) | |
865 BLI_freelistN(strings); | |
866 ········ | |
867 CachedTextLevel--; | |
868 } | |
869 | |
870 /* ******************** primitive drawing ******************* */ | |
871 | |
872 /* draws a cube on given the scaling of the cube, assuming that | |
873 * all required matrices have been set (used for drawing empties) | |
874 */ | |
875 static void drawcube_size(float size) | |
876 { | |
877 glBegin(GL_LINE_STRIP); | |
878 glVertex3f(-size, -size, -size); glVertex3f(-size, -size, size); | |
879 glVertex3f(-size, size, size); glVertex3f(-size, size, -size); | |
880 | |
881 glVertex3f(-size, -size, -size); glVertex3f(size, -size, -size); | |
882 glVertex3f(size, -size, size); glVertex3f(size, size, size); | |
883 | |
884 glVertex3f(size, size, -size); glVertex3f(size, -size, -size); | |
885 glEnd(); | |
886 | |
887 glBegin(GL_LINE_STRIP); | |
888 glVertex3f(-size, -size, size); glVertex3f(size, -size, size); | |
889 glEnd(); | |
890 | |
891 glBegin(GL_LINE_STRIP); | |
892 glVertex3f(-size, size, size); glVertex3f(size, size, size); | |
893 glEnd(); | |
894 | |
895 glBegin(GL_LINE_STRIP); | |
896 glVertex3f(-size, size, -size); glVertex3f(size, size, -size); | |
897 glEnd(); | |
898 } | |
899 | |
900 /* this is an unused (old) cube-drawing function based on a given size */ | |
901 #if 0 | |
902 static void drawcube_size(const float size[3]) | |
903 { | |
904 | |
905 glPushMatrix(); | |
906 glScalef(size[0], size[1], size[2]); | |
907 ········ | |
908 | |
909 glBegin(GL_LINE_STRIP); | |
910 glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVert
ex3fv(cube[3]); | |
911 glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVert
ex3fv(cube[6]); | |
912 glVertex3fv(cube[7]); glVertex3fv(cube[4]); | |
913 glEnd(); | |
914 | |
915 glBegin(GL_LINE_STRIP); | |
916 glVertex3fv(cube[1]); glVertex3fv(cube[5]); | |
917 glEnd(); | |
918 | |
919 glBegin(GL_LINE_STRIP); | |
920 glVertex3fv(cube[2]); glVertex3fv(cube[6]); | |
921 glEnd(); | |
922 | |
923 glBegin(GL_LINE_STRIP); | |
924 glVertex3fv(cube[3]); glVertex3fv(cube[7]); | |
925 glEnd(); | |
926 ········ | |
927 glPopMatrix(); | |
928 } | |
929 #endif | |
930 | |
931 static void drawshadbuflimits(Lamp *la, float mat[4][4]) | |
932 { | |
933 float sta[3], end[3], lavec[3]; | |
934 | |
935 negate_v3_v3(lavec, mat[2]); | |
936 normalize_v3(lavec); | |
937 | |
938 madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta); | |
939 madd_v3_v3v3fl(end, mat[3], lavec, la->clipend); | |
940 | |
941 glBegin(GL_LINE_STRIP); | |
942 glVertex3fv(sta); | |
943 glVertex3fv(end); | |
944 glEnd(); | |
945 | |
946 glPointSize(3.0); | |
947 bglBegin(GL_POINTS); | |
948 bglVertex3fv(sta); | |
949 bglVertex3fv(end); | |
950 bglEnd(); | |
951 glPointSize(1.0); | |
952 } | |
953 | |
954 | |
955 | |
956 static void spotvolume(float lvec[3], float vvec[3], const float inp) | |
957 { | |
958 /* camera is at 0,0,0 */ | |
959 float temp[3], plane[3], mat1[3][3], mat2[3][3], mat3[3][3], mat4[3][3],
q[4], co, si, angle; | |
960 | |
961 normalize_v3(lvec); | |
962 normalize_v3(vvec); /* is this the correct vector ? */ | |
963 | |
964 cross_v3_v3v3(temp, vvec, lvec); /* equation for a plane through vv
ec en lvec */ | |
965 cross_v3_v3v3(plane, lvec, temp); /* a plane perpendicular to this,
parrallel with lvec */ | |
966 | |
967 /* vectors are exactly aligned, use the X axis, this is arbitrary */ | |
968 if (normalize_v3(plane) == 0.0f) | |
969 plane[1] = 1.0f; | |
970 | |
971 /* now we've got two equations: one of a cone and one of a plane, but we
have | |
972 * three unknowns. We remove one unknown by rotating the plane to z=0 (t
he plane normal) */ | |
973 | |
974 /* rotate around cross product vector of (0,0,1) and plane normal, dot p
roduct degrees */ | |
975 /* according definition, we derive cross product is (plane[1],-plane[0],
0), en cos = plane[2]);*/ | |
976 | |
977 /* translating this comment to english didnt really help me understandin
g the math! :-) (ton) */ | |
978 ········ | |
979 q[1] = plane[1]; | |
980 q[2] = -plane[0]; | |
981 q[3] = 0; | |
982 normalize_v3(&q[1]); | |
983 | |
984 angle = saacos(plane[2]) / 2.0f; | |
985 co = cosf(angle); | |
986 si = sqrtf(1 - co * co); | |
987 | |
988 q[0] = co; | |
989 q[1] *= si; | |
990 q[2] *= si; | |
991 q[3] = 0; | |
992 | |
993 quat_to_mat3(mat1, q); | |
994 | |
995 /* rotate lamp vector now over acos(inp) degrees */ | |
996 copy_v3_v3(vvec, lvec); | |
997 | |
998 unit_m3(mat2); | |
999 co = inp; | |
1000 si = sqrtf(1.0f - inp * inp); | |
1001 | |
1002 mat2[0][0] = co; | |
1003 mat2[1][0] = -si; | |
1004 mat2[0][1] = si; | |
1005 mat2[1][1] = co; | |
1006 mul_m3_m3m3(mat3, mat2, mat1); | |
1007 | |
1008 mat2[1][0] = si; | |
1009 mat2[0][1] = -si; | |
1010 mul_m3_m3m3(mat4, mat2, mat1); | |
1011 transpose_m3(mat1); | |
1012 | |
1013 mul_m3_m3m3(mat2, mat1, mat3); | |
1014 mul_m3_v3(mat2, lvec); | |
1015 mul_m3_m3m3(mat2, mat1, mat4); | |
1016 mul_m3_v3(mat2, vvec); | |
1017 | |
1018 return; | |
1019 } | |
1020 | |
1021 static void draw_spot_cone(Lamp *la, float x, float z) | |
1022 { | |
1023 z = fabs(z); | |
1024 | |
1025 glBegin(GL_TRIANGLE_FAN); | |
1026 glVertex3f(0.0f, 0.0f, -x); | |
1027 | |
1028 if (la->mode & LA_SQUARE) { | |
1029 glVertex3f(z, z, 0); | |
1030 glVertex3f(-z, z, 0); | |
1031 glVertex3f(-z, -z, 0); | |
1032 glVertex3f(z, -z, 0); | |
1033 glVertex3f(z, z, 0); | |
1034 } | |
1035 else { | |
1036 float angle; | |
1037 int a; | |
1038 | |
1039 for (a = 0; a < 33; a++) { | |
1040 angle = a * M_PI * 2 / (33 - 1); | |
1041 glVertex3f(z * cosf(angle), z * sinf(angle), 0); | |
1042 } | |
1043 } | |
1044 | |
1045 glEnd(); | |
1046 } | |
1047 | |
1048 static void draw_transp_spot_volume(Lamp *la, float x, float z) | |
1049 { | |
1050 glEnable(GL_CULL_FACE); | |
1051 glEnable(GL_BLEND); | |
1052 glDepthMask(0); | |
1053 | |
1054 /* draw backside darkening */ | |
1055 glCullFace(GL_FRONT); | |
1056 | |
1057 glBlendFunc(GL_ZERO, GL_SRC_ALPHA); | |
1058 glColor4f(0.0f, 0.0f, 0.0f, 0.4f); | |
1059 | |
1060 draw_spot_cone(la, x, z); | |
1061 | |
1062 /* draw front side lighting */ | |
1063 glCullFace(GL_BACK); | |
1064 | |
1065 glBlendFunc(GL_ONE, GL_ONE); | |
1066 glColor4f(0.2f, 0.2f, 0.2f, 1.0f); | |
1067 | |
1068 draw_spot_cone(la, x, z); | |
1069 | |
1070 /* restore state */ | |
1071 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
1072 glDisable(GL_BLEND); | |
1073 glDepthMask(1); | |
1074 glDisable(GL_CULL_FACE); | |
1075 glCullFace(GL_BACK); | |
1076 } | |
1077 | |
1078 static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, | |
1079 const char dt, const short dflag, const unsigned char ob_wi
re_col[4]) | |
1080 { | |
1081 Object *ob = base->object; | |
1082 const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]); | |
1083 Lamp *la = ob->data; | |
1084 float vec[3], lvec[3], vvec[3], circrad, x, y, z; | |
1085 float lampsize; | |
1086 float imat[4][4]; | |
1087 | |
1088 unsigned char curcol[4]; | |
1089 unsigned char col[4]; | |
1090 /* cone can't be drawn for duplicated lamps, because duplilist would be
freed to */ | |
1091 /* the moment of view3d_draw_transp() call */ | |
1092 const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->
object); | |
1093 const bool drawcone = ((dt > OB_WIRE) && | |
1094 !(G.f & G_PICKSEL) && | |
1095 (la->type == LA_SPOT) && | |
1096 (la->mode & LA_SHOW_CONE) && | |
1097 !(base->flag & OB_FROMDUPLI) && | |
1098 !is_view); | |
1099 | |
1100 if (drawcone && !v3d->transp) { | |
1101 /* in this case we need to draw delayed */ | |
1102 ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); | |
1103 return; | |
1104 } | |
1105 ········ | |
1106 /* we first draw only the screen aligned & fixed scale stuff */ | |
1107 glPushMatrix(); | |
1108 glLoadMatrixf(rv3d->viewmat); | |
1109 | |
1110 /* lets calculate the scale: */ | |
1111 lampsize = pixsize * ((float)U.obcenter_dia * 0.5f); | |
1112 | |
1113 /* and view aligned matrix: */ | |
1114 copy_m4_m4(imat, rv3d->viewinv); | |
1115 normalize_v3(imat[0]); | |
1116 normalize_v3(imat[1]); | |
1117 | |
1118 /* lamp center */ | |
1119 copy_v3_v3(vec, ob->obmat[3]); | |
1120 | |
1121 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1122 /* for AA effects */ | |
1123 curcol[0] = ob_wire_col[0]; | |
1124 curcol[1] = ob_wire_col[1]; | |
1125 curcol[2] = ob_wire_col[2]; | |
1126 curcol[3] = 154; | |
1127 glColor4ubv(curcol); | |
1128 } | |
1129 | |
1130 if (lampsize > 0.0f) { | |
1131 | |
1132 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1133 if (ob->id.us > 1) { | |
1134 if (ob == OBACT || (ob->flag & SELECT)) glColor4
ub(0x88, 0xFF, 0xFF, 155); | |
1135 else glColor4ub(0x77, 0xCC, 0xCC, 155); | |
1136 } | |
1137 } | |
1138 ················ | |
1139 /* Inner Circle */ | |
1140 glEnable(GL_BLEND); | |
1141 drawcircball(GL_LINE_LOOP, vec, lampsize, imat); | |
1142 glDisable(GL_BLEND); | |
1143 drawcircball(GL_POLYGON, vec, lampsize, imat); | |
1144 ················ | |
1145 /* restore */ | |
1146 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1147 if (ob->id.us > 1) | |
1148 glColor4ubv(curcol); | |
1149 } | |
1150 | |
1151 /* Outer circle */ | |
1152 circrad = 3.0f * lampsize; | |
1153 setlinestyle(3); | |
1154 | |
1155 drawcircball(GL_LINE_LOOP, vec, circrad, imat); | |
1156 | |
1157 /* draw dashed outer circle if shadow is on. remember some lamps
can't have certain shadows! */ | |
1158 if (la->type != LA_HEMI) { | |
1159 if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF
) && (la->type == LA_SPOT))) { | |
1160 drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f *
pixsize, imat); | |
1161 } | |
1162 } | |
1163 } | |
1164 else { | |
1165 setlinestyle(3); | |
1166 circrad = 0.0f; | |
1167 } | |
1168 ········ | |
1169 /* draw the pretty sun rays */ | |
1170 if (la->type == LA_SUN) { | |
1171 float v1[3], v2[3], mat[3][3]; | |
1172 short axis; | |
1173 ················ | |
1174 /* setup a 45 degree rotation matrix */ | |
1175 axis_angle_normalized_to_mat3(mat, imat[2], (float)M_PI / 4.0f); | |
1176 | |
1177 /* vectors */ | |
1178 mul_v3_v3fl(v1, imat[0], circrad * 1.2f); | |
1179 mul_v3_v3fl(v2, imat[0], circrad * 2.5f); | |
1180 ················ | |
1181 /* center */ | |
1182 glTranslatef(vec[0], vec[1], vec[2]); | |
1183 ················ | |
1184 setlinestyle(3); | |
1185 ················ | |
1186 glBegin(GL_LINES); | |
1187 for (axis = 0; axis < 8; axis++) { | |
1188 glVertex3fv(v1); | |
1189 glVertex3fv(v2); | |
1190 mul_m3_v3(mat, v1); | |
1191 mul_m3_v3(mat, v2); | |
1192 } | |
1193 glEnd(); | |
1194 ················ | |
1195 glTranslatef(-vec[0], -vec[1], -vec[2]); | |
1196 | |
1197 } | |
1198 ········ | |
1199 if (la->type == LA_LOCAL) { | |
1200 if (la->mode & LA_SPHERE) { | |
1201 drawcircball(GL_LINE_LOOP, vec, la->dist, imat); | |
1202 } | |
1203 } | |
1204 ········ | |
1205 glPopMatrix(); /* back in object space */ | |
1206 zero_v3(vec); | |
1207 ········ | |
1208 if (is_view) { | |
1209 /* skip drawing extra info */ | |
1210 } | |
1211 else if ((la->type == LA_SPOT) || (la->type == LA_YF_PHOTON)) { | |
1212 lvec[0] = lvec[1] = 0.0; | |
1213 lvec[2] = 1.0; | |
1214 x = rv3d->persmat[0][2]; | |
1215 y = rv3d->persmat[1][2]; | |
1216 z = rv3d->persmat[2][2]; | |
1217 vvec[0] = x * ob->obmat[0][0] + y * ob->obmat[0][1] + z * ob->ob
mat[0][2]; | |
1218 vvec[1] = x * ob->obmat[1][0] + y * ob->obmat[1][1] + z * ob->ob
mat[1][2]; | |
1219 vvec[2] = x * ob->obmat[2][0] + y * ob->obmat[2][1] + z * ob->ob
mat[2][2]; | |
1220 | |
1221 y = cosf(la->spotsize * (float)(M_PI / 360.0)); | |
1222 spotvolume(lvec, vvec, y); | |
1223 x = -la->dist; | |
1224 mul_v3_fl(lvec, x); | |
1225 mul_v3_fl(vvec, x); | |
1226 | |
1227 /* draw the angled sides of the cone */ | |
1228 glBegin(GL_LINE_STRIP); | |
1229 glVertex3fv(vvec); | |
1230 glVertex3fv(vec); | |
1231 glVertex3fv(lvec); | |
1232 glEnd(); | |
1233 ················ | |
1234 z = x * sqrtf(1.0f - y * y); | |
1235 x *= y; | |
1236 | |
1237 /* draw the circle/square at the end of the cone */ | |
1238 glTranslatef(0.0, 0.0, x); | |
1239 if (la->mode & LA_SQUARE) { | |
1240 float tvec[3]; | |
1241 float z_abs = fabs(z); | |
1242 | |
1243 tvec[0] = tvec[1] = z_abs; | |
1244 tvec[2] = 0.0; | |
1245 | |
1246 glBegin(GL_LINE_LOOP); | |
1247 glVertex3fv(tvec); | |
1248 tvec[1] = -z_abs; /* neg */ | |
1249 glVertex3fv(tvec); | |
1250 tvec[0] = -z_abs; /* neg */ | |
1251 glVertex3fv(tvec); | |
1252 tvec[1] = z_abs; /* pos */ | |
1253 glVertex3fv(tvec); | |
1254 glEnd(); | |
1255 } | |
1256 else { | |
1257 circ(0.0, 0.0, fabsf(z)); | |
1258 } | |
1259 | |
1260 /* draw the circle/square representing spotbl */ | |
1261 if (la->type == LA_SPOT) { | |
1262 float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2))
; | |
1263 /* hide line if it is zero size or overlaps with outer b
order, | |
1264 * previously it adjusted to always to show it but that
seems | |
1265 * confusing because it doesn't show the actual blend si
ze */ | |
1266 if (spotblcirc != 0 && spotblcirc != fabsf(z)) | |
1267 circ(0.0, 0.0, spotblcirc); | |
1268 } | |
1269 | |
1270 if (drawcone) | |
1271 draw_transp_spot_volume(la, x, z); | |
1272 | |
1273 /* draw clip start, useful for wide cones where its not obvious
where the start is */ | |
1274 glTranslatef(0.0, 0.0, -x); /* reverse translation above */ | |
1275 if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF) ) { | |
1276 float lvec_clip[3]; | |
1277 float vvec_clip[3]; | |
1278 float clipsta_fac = la->clipsta / -x; | |
1279 | |
1280 interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac); | |
1281 interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac); | |
1282 | |
1283 glBegin(GL_LINE_STRIP); | |
1284 glVertex3fv(lvec_clip); | |
1285 glVertex3fv(vvec_clip); | |
1286 glEnd(); | |
1287 } | |
1288 /* Else, draw spot direction (using distance as end limit, same
as for Area lamp). */ | |
1289 else { | |
1290 glBegin(GL_LINE_STRIP); | |
1291 glVertex3f(0.0, 0.0, -circrad); | |
1292 glVertex3f(0.0, 0.0, -la->dist); | |
1293 glEnd(); | |
1294 } | |
1295 } | |
1296 else if (ELEM(la->type, LA_HEMI, LA_SUN)) { | |
1297 ················ | |
1298 /* draw the line from the circle along the dist */ | |
1299 glBegin(GL_LINE_STRIP); | |
1300 vec[2] = -circrad; | |
1301 glVertex3fv(vec); | |
1302 vec[2] = -la->dist; | |
1303 glVertex3fv(vec); | |
1304 glEnd(); | |
1305 ················ | |
1306 if (la->type == LA_HEMI) { | |
1307 /* draw the hemisphere curves */ | |
1308 short axis, steps, dir; | |
1309 float outdist, zdist, mul; | |
1310 zero_v3(vec); | |
1311 outdist = 0.14; mul = 1.4; dir = 1; | |
1312 ························ | |
1313 setlinestyle(4); | |
1314 /* loop over the 4 compass points, and draw each arc as
a LINE_STRIP */ | |
1315 for (axis = 0; axis < 4; axis++) { | |
1316 float v[3] = {0.0, 0.0, 0.0}; | |
1317 zdist = 0.02; | |
1318 ································ | |
1319 glBegin(GL_LINE_STRIP); | |
1320 ································ | |
1321 for (steps = 0; steps < 6; steps++) { | |
1322 if (axis == 0 || axis == 1) { /* x
axis up, x axis down */ | |
1323 /* make the arcs start at the ed
ge of the energy circle */ | |
1324 if (steps == 0) v[0] = dir * cir
crad; | |
1325 else v[0] = v[0] + dir * (steps
* outdist); | |
1326 } | |
1327 else if (axis == 2 || axis == 3) {
/* y axis up, y axis down */ | |
1328 /* make the arcs start at the ed
ge of the energy circle */ | |
1329 v[1] = (steps == 0) ? (dir * cir
crad) : (v[1] + dir * (steps * outdist)); | |
1330 } | |
1331 | |
1332 v[2] = v[2] - steps * zdist; | |
1333 ········································ | |
1334 glVertex3fv(v); | |
1335 ········································ | |
1336 zdist = zdist * mul; | |
1337 } | |
1338 ································ | |
1339 glEnd(); | |
1340 /* flip the direction */ | |
1341 dir = -dir; | |
1342 } | |
1343 } | |
1344 } | |
1345 else if (la->type == LA_AREA) { | |
1346 setlinestyle(3); | |
1347 if (la->area_shape == LA_AREA_SQUARE) | |
1348 fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, l
a->area_size * 0.5f, la->area_size * 0.5f); | |
1349 else if (la->area_shape == LA_AREA_RECT) | |
1350 fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f,
la->area_size * 0.5f, la->area_sizey * 0.5f); | |
1351 | |
1352 glBegin(GL_LINE_STRIP); | |
1353 glVertex3f(0.0, 0.0, -circrad); | |
1354 glVertex3f(0.0, 0.0, -la->dist); | |
1355 glEnd(); | |
1356 } | |
1357 ········ | |
1358 /* and back to viewspace */ | |
1359 glPushMatrix(); | |
1360 glLoadMatrixf(rv3d->viewmat); | |
1361 copy_v3_v3(vec, ob->obmat[3]); | |
1362 | |
1363 setlinestyle(0); | |
1364 ········ | |
1365 if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == fal
se)) { | |
1366 drawshadbuflimits(la, ob->obmat); | |
1367 } | |
1368 ········ | |
1369 UI_GetThemeColor4ubv(TH_LAMP, col); | |
1370 glColor4ubv(col); | |
1371 | |
1372 glEnable(GL_BLEND); | |
1373 ········ | |
1374 if (vec[2] > 0) vec[2] -= circrad; | |
1375 else vec[2] += circrad; | |
1376 ········ | |
1377 glBegin(GL_LINE_STRIP); | |
1378 glVertex3fv(vec); | |
1379 vec[2] = 0; | |
1380 glVertex3fv(vec); | |
1381 glEnd(); | |
1382 ········ | |
1383 glPointSize(2.0); | |
1384 glBegin(GL_POINTS); | |
1385 glVertex3fv(vec); | |
1386 glEnd(); | |
1387 glPointSize(1.0); | |
1388 ········ | |
1389 glDisable(GL_BLEND); | |
1390 ········ | |
1391 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1392 /* restore for drawing extra stuff */ | |
1393 glColor3ubv(ob_wire_col); | |
1394 } | |
1395 /* and finally back to org object space! */ | |
1396 glPopMatrix(); | |
1397 } | |
1398 | |
1399 static void draw_limit_line(float sta, float end, const short dflag, unsigned in
t col) | |
1400 { | |
1401 glBegin(GL_LINES); | |
1402 glVertex3f(0.0, 0.0, -sta); | |
1403 glVertex3f(0.0, 0.0, -end); | |
1404 glEnd(); | |
1405 | |
1406 if (!(dflag & DRAW_PICKING)) { | |
1407 glPointSize(3.0); | |
1408 glBegin(GL_POINTS); | |
1409 cpack(col); | |
1410 glVertex3f(0.0, 0.0, -sta); | |
1411 glVertex3f(0.0, 0.0, -end); | |
1412 glEnd(); | |
1413 glPointSize(1.0); | |
1414 } | |
1415 } | |
1416 | |
1417 | |
1418 /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ | |
1419 /* qdn: now also enabled for Blender to set focus point for defocus composite no
de */ | |
1420 static void draw_focus_cross(float dist, float size) | |
1421 { | |
1422 glBegin(GL_LINES); | |
1423 glVertex3f(-size, 0.f, -dist); | |
1424 glVertex3f(size, 0.f, -dist); | |
1425 glVertex3f(0.f, -size, -dist); | |
1426 glVertex3f(0.f, size, -dist); | |
1427 glEnd(); | |
1428 } | |
1429 | |
1430 #ifdef VIEW3D_CAMERA_BORDER_HACK | |
1431 unsigned char view3d_camera_border_hack_col[3]; | |
1432 bool view3d_camera_border_hack_test = false; | |
1433 #endif | |
1434 | |
1435 /* ****************** draw clip data *************** */ | |
1436 | |
1437 static void draw_bundle_sphere(void) | |
1438 { | |
1439 static GLuint displist = 0; | |
1440 | |
1441 if (displist == 0) { | |
1442 GLUquadricObj *qobj; | |
1443 | |
1444 displist = glGenLists(1); | |
1445 glNewList(displist, GL_COMPILE); | |
1446 | |
1447 qobj = gluNewQuadric(); | |
1448 gluQuadricDrawStyle(qobj, GLU_FILL); | |
1449 glShadeModel(GL_SMOOTH); | |
1450 gluSphere(qobj, 0.05, 8, 8); | |
1451 glShadeModel(GL_FLAT); | |
1452 gluDeleteQuadric(qobj); | |
1453 | |
1454 glEndList(); | |
1455 } | |
1456 | |
1457 glCallList(displist); | |
1458 } | |
1459 | |
1460 static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
*v3d, | |
1461 MovieClip *clip, MovieTrackingOb
ject *tracking_object, | |
1462 const short dflag, const unsigne
d char ob_wire_col[4], | |
1463 int *global_track_index, bool dr
aw_selected) | |
1464 { | |
1465 MovieTracking *tracking = &clip->tracking; | |
1466 MovieTrackingTrack *track; | |
1467 float mat[4][4], imat[4][4]; | |
1468 unsigned char col_unsel[4], col_sel[4]; | |
1469 int tracknr = *global_track_index; | |
1470 ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking
_object); | |
1471 float camera_size[3]; | |
1472 | |
1473 UI_GetThemeColor4ubv(TH_TEXT, col_unsel); | |
1474 UI_GetThemeColor4ubv(TH_SELECT, col_sel); | |
1475 | |
1476 BKE_tracking_get_camera_object_matrix(scene, base->object, mat); | |
1477 | |
1478 /* we're compensating camera size for bundles size, | |
1479 * to make it so bundles are always displayed with the same size | |
1480 */ | |
1481 copy_v3_v3(camera_size, base->object->size); | |
1482 if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) | |
1483 mul_v3_fl(camera_size, tracking_object->scale); | |
1484 | |
1485 glPushMatrix(); | |
1486 | |
1487 if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { | |
1488 /* current ogl matrix is translated in camera space, bundles sho
uld | |
1489 * be rendered in world space, so camera matrix should be "remov
ed" | |
1490 * from current ogl matrix */ | |
1491 invert_m4_m4(imat, base->object->obmat); | |
1492 | |
1493 glMultMatrixf(imat); | |
1494 glMultMatrixf(mat); | |
1495 } | |
1496 else { | |
1497 float obmat[4][4]; | |
1498 | |
1499 BKE_tracking_camera_get_reconstructed_interpolate(tracking, trac
king_object, scene->r.cfra, obmat); | |
1500 | |
1501 invert_m4_m4(imat, obmat); | |
1502 glMultMatrixf(imat); | |
1503 } | |
1504 | |
1505 for (track = tracksbase->first; track; track = track->next) { | |
1506 int selected = TRACK_SELECTED(track); | |
1507 | |
1508 if (draw_selected && !selected) | |
1509 continue; | |
1510 | |
1511 if ((track->flag & TRACK_HAS_BUNDLE) == 0) | |
1512 continue; | |
1513 | |
1514 if (dflag & DRAW_PICKING) | |
1515 glLoadName(base->selcol + (tracknr << 16)); | |
1516 | |
1517 glPushMatrix(); | |
1518 glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->
bundle_pos[2]); | |
1519 glScalef(v3d->bundle_size / 0.05f / camera_size[0], | |
1520 v3d->bundle_size / 0.05f / camera_size[1], | |
1521 v3d->bundle_size / 0.05f / camera_size[2]); | |
1522 | |
1523 if (v3d->drawtype == OB_WIRE) { | |
1524 glDisable(GL_LIGHTING); | |
1525 | |
1526 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1527 if (selected && (track->flag & TRACK_CUSTOMCOLOR
) == 0) { | |
1528 glColor3ubv(ob_wire_col); | |
1529 } | |
1530 else { | |
1531 glColor3fv(track->color); | |
1532 } | |
1533 } | |
1534 | |
1535 drawaxes(0.05f, v3d->bundle_drawtype); | |
1536 | |
1537 glEnable(GL_LIGHTING); | |
1538 } | |
1539 else if (v3d->drawtype > OB_WIRE) { | |
1540 if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) { | |
1541 /* selection outline */ | |
1542 if (selected) { | |
1543 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1544 glColor3ubv(ob_wire_col); | |
1545 } | |
1546 | |
1547 glLineWidth(2.f); | |
1548 glDisable(GL_LIGHTING); | |
1549 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE
); | |
1550 | |
1551 draw_bundle_sphere(); | |
1552 | |
1553 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL
); | |
1554 glEnable(GL_LIGHTING); | |
1555 glLineWidth(1.f); | |
1556 } | |
1557 | |
1558 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1559 if (track->flag & TRACK_CUSTOMCOLOR) glC
olor3fv(track->color); | |
1560 else UI_ThemeColor(TH_BUNDLE_SOLID); | |
1561 } | |
1562 | |
1563 draw_bundle_sphere(); | |
1564 } | |
1565 else { | |
1566 glDisable(GL_LIGHTING); | |
1567 | |
1568 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1569 if (selected) { | |
1570 glColor3ubv(ob_wire_col); | |
1571 } | |
1572 else { | |
1573 if (track->flag & TRACK_CUSTOMCO
LOR) glColor3fv(track->color); | |
1574 else UI_ThemeColor(TH_WIRE); | |
1575 } | |
1576 } | |
1577 | |
1578 drawaxes(0.05f, v3d->bundle_drawtype); | |
1579 | |
1580 glEnable(GL_LIGHTING); | |
1581 } | |
1582 } | |
1583 | |
1584 glPopMatrix(); | |
1585 | |
1586 if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLE
NAME)) { | |
1587 float pos[3]; | |
1588 | |
1589 mul_v3_m4v3(pos, mat, track->bundle_pos); | |
1590 view3d_cached_text_draw_add(pos, track->name, 10, V3D_CA
CHE_TEXT_GLOBALSPACE, selected ? col_sel : col_unsel); | |
1591 } | |
1592 | |
1593 tracknr++; | |
1594 } | |
1595 | |
1596 if ((dflag & DRAW_PICKING) == 0) { | |
1597 if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag
& TRACKING_OBJECT_CAMERA)) { | |
1598 MovieTrackingReconstruction *reconstruction; | |
1599 reconstruction = BKE_tracking_object_get_reconstruction(
tracking, tracking_object); | |
1600 | |
1601 if (reconstruction->camnr) { | |
1602 MovieReconstructedCamera *camera = reconstructio
n->cameras; | |
1603 int a = 0; | |
1604 | |
1605 glDisable(GL_LIGHTING); | |
1606 UI_ThemeColor(TH_CAMERA_PATH); | |
1607 glLineWidth(2.0f); | |
1608 | |
1609 glBegin(GL_LINE_STRIP); | |
1610 for (a = 0; a < reconstruction->camnr; a++, came
ra++) { | |
1611 glVertex3fv(camera->mat[3]); | |
1612 } | |
1613 glEnd(); | |
1614 | |
1615 glLineWidth(1.0f); | |
1616 glEnable(GL_LIGHTING); | |
1617 } | |
1618 } | |
1619 } | |
1620 | |
1621 glPopMatrix(); | |
1622 | |
1623 *global_track_index = tracknr; | |
1624 } | |
1625 | |
1626 static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
MovieClip *clip, | |
1627 const short dflag, const unsigned char
ob_wire_col[4], | |
1628 const bool draw_selected) | |
1629 { | |
1630 MovieTracking *tracking = &clip->tracking; | |
1631 MovieTrackingObject *tracking_object; | |
1632 int global_track_index = 1; | |
1633 | |
1634 if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) | |
1635 return; | |
1636 | |
1637 if (v3d->flag2 & V3D_RENDER_OVERRIDE) | |
1638 return; | |
1639 | |
1640 glEnable(GL_LIGHTING); | |
1641 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
1642 glEnable(GL_COLOR_MATERIAL); | |
1643 glShadeModel(GL_SMOOTH); | |
1644 | |
1645 tracking_object = tracking->objects.first; | |
1646 while (tracking_object) { | |
1647 draw_viewport_object_reconstruction(scene, base, v3d, clip, trac
king_object, | |
1648 dflag, ob_wire_col, &global_
track_index, draw_selected); | |
1649 | |
1650 tracking_object = tracking_object->next; | |
1651 } | |
1652 | |
1653 /* restore */ | |
1654 glShadeModel(GL_FLAT); | |
1655 glDisable(GL_COLOR_MATERIAL); | |
1656 glDisable(GL_LIGHTING); | |
1657 | |
1658 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1659 glColor3ubv(ob_wire_col); | |
1660 } | |
1661 | |
1662 if (dflag & DRAW_PICKING) | |
1663 glLoadName(base->selcol); | |
1664 } | |
1665 | |
1666 /* flag similar to draw_object() */ | |
1667 static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
, | |
1668 const short dflag, const unsigned char ob_wire_col[4]) | |
1669 { | |
1670 /* a standing up pyramid with (0,0,0) as top */ | |
1671 Camera *cam; | |
1672 Object *ob = base->object; | |
1673 float tvec[3]; | |
1674 float vec[4][3], asp[2], shift[2], scale[3]; | |
1675 int i; | |
1676 float drawsize; | |
1677 const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera); | |
1678 MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false); | |
1679 | |
1680 /* draw data for movie clip set as active for scene */ | |
1681 if (clip) { | |
1682 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_w
ire_col, false); | |
1683 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_w
ire_col, true); | |
1684 } | |
1685 | |
1686 #ifdef VIEW3D_CAMERA_BORDER_HACK | |
1687 if (is_view && !(G.f & G_PICKSEL)) { | |
1688 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
1689 view3d_camera_border_hack_col[0] = ob_wire_col[0]; | |
1690 view3d_camera_border_hack_col[1] = ob_wire_col[1]; | |
1691 view3d_camera_border_hack_col[2] = ob_wire_col[2]; | |
1692 } | |
1693 else { | |
1694 float col[4]; | |
1695 glGetFloatv(GL_CURRENT_COLOR, col); | |
1696 rgb_float_to_uchar(view3d_camera_border_hack_col, col); | |
1697 } | |
1698 view3d_camera_border_hack_test = true; | |
1699 return; | |
1700 } | |
1701 #endif | |
1702 | |
1703 cam = ob->data; | |
1704 | |
1705 scale[0] = 1.0f / len_v3(ob->obmat[0]); | |
1706 scale[1] = 1.0f / len_v3(ob->obmat[1]); | |
1707 scale[2] = 1.0f / len_v3(ob->obmat[2]); | |
1708 | |
1709 BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale, | |
1710 asp, shift, &drawsize, vec); | |
1711 | |
1712 glDisable(GL_LIGHTING); | |
1713 glDisable(GL_CULL_FACE); | |
1714 | |
1715 /* camera frame */ | |
1716 glBegin(GL_LINE_LOOP); | |
1717 glVertex3fv(vec[0]); | |
1718 glVertex3fv(vec[1]); | |
1719 glVertex3fv(vec[2]); | |
1720 glVertex3fv(vec[3]); | |
1721 glEnd(); | |
1722 | |
1723 if (is_view) | |
1724 return; | |
1725 | |
1726 zero_v3(tvec); | |
1727 | |
1728 /* center point to camera frame */ | |
1729 glBegin(GL_LINE_STRIP); | |
1730 glVertex3fv(vec[1]); | |
1731 glVertex3fv(tvec); | |
1732 glVertex3fv(vec[0]); | |
1733 glVertex3fv(vec[3]); | |
1734 glVertex3fv(tvec); | |
1735 glVertex3fv(vec[2]); | |
1736 glEnd(); | |
1737 | |
1738 | |
1739 /* arrow on top */ | |
1740 tvec[2] = vec[1][2]; /* copy the depth */ | |
1741 | |
1742 | |
1743 /* draw an outline arrow for inactive cameras and filled | |
1744 * for active cameras. We actually draw both outline+filled | |
1745 * for active cameras so the wire can be seen side-on */ | |
1746 for (i = 0; i < 2; i++) { | |
1747 if (i == 0) glBegin(GL_LINE_LOOP); | |
1748 else if (i == 1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES); | |
1749 else break; | |
1750 | |
1751 tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]); | |
1752 tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]); | |
1753 glVertex3fv(tvec); /* left */ | |
1754 ················ | |
1755 tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]); | |
1756 glVertex3fv(tvec); /* right */ | |
1757 ················ | |
1758 tvec[0] = shift[0]; | |
1759 tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scal
e[1]); | |
1760 glVertex3fv(tvec); /* top */ | |
1761 | |
1762 glEnd(); | |
1763 } | |
1764 | |
1765 if ((dflag & DRAW_SCENESET) == 0) { | |
1766 if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) { | |
1767 float nobmat[4][4]; | |
1768 | |
1769 /* draw in normalized object matrix space */ | |
1770 copy_m4_m4(nobmat, ob->obmat); | |
1771 normalize_m4(nobmat); | |
1772 | |
1773 glPushMatrix(); | |
1774 glLoadMatrixf(rv3d->viewmat); | |
1775 glMultMatrixf(nobmat); | |
1776 | |
1777 if (cam->flag & CAM_SHOWLIMITS) { | |
1778 draw_limit_line(cam->clipsta, cam->clipend, dfla
g, 0x77FFFF); | |
1779 /* qdn: was yafray only, now also enabled for Bl
ender to be used with defocus composite node */ | |
1780 draw_focus_cross(BKE_camera_object_dof_distance(
ob), cam->drawsize); | |
1781 } | |
1782 | |
1783 if (cam->flag & CAM_SHOWMIST) { | |
1784 World *world = scene->world; | |
1785 if (world) { | |
1786 draw_limit_line(world->miststa, world->m
iststa + world->mistdist, dflag, 0xFFFFFF); | |
1787 } | |
1788 } | |
1789 glPopMatrix(); | |
1790 } | |
1791 } | |
1792 } | |
1793 | |
1794 /* flag similar to draw_object() */ | |
1795 static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D
*UNUSED(rv3d), | |
1796 Object *UNUSED(ob), int UNUSED(flag)) | |
1797 { | |
1798 //Speaker *spk = ob->data; | |
1799 | |
1800 float vec[3]; | |
1801 int i, j; | |
1802 | |
1803 glEnable(GL_BLEND); | |
1804 | |
1805 for (j = 0; j < 3; j++) { | |
1806 vec[2] = 0.25f * j - 0.125f; | |
1807 | |
1808 glBegin(GL_LINE_LOOP); | |
1809 for (i = 0; i < 16; i++) { | |
1810 vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f :
0.25f); | |
1811 vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f :
0.25f); | |
1812 glVertex3fv(vec); | |
1813 } | |
1814 glEnd(); | |
1815 } | |
1816 | |
1817 for (j = 0; j < 4; j++) { | |
1818 vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f; | |
1819 vec[1] = ((j % 2) * (j - 2)) * 0.5f; | |
1820 glBegin(GL_LINE_STRIP); | |
1821 for (i = 0; i < 3; i++) { | |
1822 if (i == 1) { | |
1823 vec[0] *= 0.5f; | |
1824 vec[1] *= 0.5f; | |
1825 } | |
1826 | |
1827 vec[2] = 0.25f * i - 0.125f; | |
1828 glVertex3fv(vec); | |
1829 } | |
1830 glEnd(); | |
1831 } | |
1832 | |
1833 glDisable(GL_BLEND); | |
1834 } | |
1835 | |
1836 static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
el) | |
1837 { | |
1838 BPoint *bp = lt->def; | |
1839 float *co = dl ? dl->verts : NULL; | |
1840 int u, v, w; | |
1841 | |
1842 const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX; | |
1843 UI_ThemeColor(color); | |
1844 | |
1845 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); | |
1846 bglBegin(GL_POINTS); | |
1847 | |
1848 for (w = 0; w < lt->pntsw; w++) { | |
1849 int wxt = (w == 0 || w == lt->pntsw - 1); | |
1850 for (v = 0; v < lt->pntsv; v++) { | |
1851 int vxt = (v == 0 || v == lt->pntsv - 1); | |
1852 for (u = 0; u < lt->pntsu; u++, bp++, co += 3) { | |
1853 int uxt = (u == 0 || u == lt->pntsu - 1); | |
1854 if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wx
t) { | |
1855 if (bp->hide == 0) { | |
1856 /* check for active BPoint and e
nsure selected */ | |
1857 if ((bp == actbp) && (bp->f1 & S
ELECT)) { | |
1858 UI_ThemeColor(TH_LASTSEL
_POINT); | |
1859 bglVertex3fv(dl ? co : b
p->vec); | |
1860 UI_ThemeColor(color); | |
1861 } | |
1862 else if ((bp->f1 & SELECT) == se
l) { | |
1863 bglVertex3fv(dl ? co : b
p->vec); | |
1864 } | |
1865 } | |
1866 } | |
1867 } | |
1868 } | |
1869 } | |
1870 ········ | |
1871 glPointSize(1.0); | |
1872 bglEnd(); | |
1873 } | |
1874 | |
1875 static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i
nt actdef_wcol) | |
1876 { | |
1877 int index = ((w * lt->pntsv + v) * lt->pntsu) + u; | |
1878 | |
1879 if (actdef_wcol) { | |
1880 float col[3]; | |
1881 MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actde
f_wcol - 1); | |
1882 ················ | |
1883 weight_to_rgb(col, mdw ? mdw->weight : 0.0f); | |
1884 glColor3fv(col); | |
1885 | |
1886 } | |
1887 ········ | |
1888 if (dl) { | |
1889 glVertex3fv(&dl->verts[index * 3]); | |
1890 } | |
1891 else { | |
1892 glVertex3fv(lt->def[index].vec); | |
1893 } | |
1894 } | |
1895 | |
1896 /* lattice color is hardcoded, now also shows weightgroup values in edit mode */ | |
1897 static void drawlattice(Scene *scene, View3D *v3d, Object *ob) | |
1898 { | |
1899 Lattice *lt = ob->data; | |
1900 DispList *dl; | |
1901 int u, v, w; | |
1902 int actdef_wcol = 0; | |
1903 const bool is_edit = (lt->editlatt != NULL); | |
1904 | |
1905 /* now we default make displist, this will modifiers work for non animat
ed case */ | |
1906 if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) | |
1907 BKE_lattice_modifiers_calc(scene, ob); | |
1908 dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS); | |
1909 ········ | |
1910 if (is_edit) { | |
1911 lt = lt->editlatt->latt; | |
1912 | |
1913 UI_ThemeColor(TH_WIRE_EDIT); | |
1914 ················ | |
1915 if (ob->defbase.first && lt->dvert) { | |
1916 actdef_wcol = ob->actdef; | |
1917 glShadeModel(GL_SMOOTH); | |
1918 } | |
1919 } | |
1920 ········ | |
1921 glBegin(GL_LINES); | |
1922 for (w = 0; w < lt->pntsw; w++) { | |
1923 int wxt = (w == 0 || w == lt->pntsw - 1); | |
1924 for (v = 0; v < lt->pntsv; v++) { | |
1925 int vxt = (v == 0 || v == lt->pntsv - 1); | |
1926 for (u = 0; u < lt->pntsu; u++) { | |
1927 int uxt = (u == 0 || u == lt->pntsu - 1); | |
1928 | |
1929 if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSID
E))) { | |
1930 drawlattice__point(lt, dl, u, v, w - 1,
actdef_wcol); | |
1931 drawlattice__point(lt, dl, u, v, w, actd
ef_wcol); | |
1932 } | |
1933 if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSID
E))) { | |
1934 drawlattice__point(lt, dl, u, v - 1, w,
actdef_wcol); | |
1935 drawlattice__point(lt, dl, u, v, w, actd
ef_wcol); | |
1936 } | |
1937 if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSID
E))) { | |
1938 drawlattice__point(lt, dl, u - 1, v, w,
actdef_wcol); | |
1939 drawlattice__point(lt, dl, u, v, w, actd
ef_wcol); | |
1940 } | |
1941 } | |
1942 } | |
1943 } | |
1944 glEnd(); | |
1945 ········ | |
1946 /* restoration for weight colors */ | |
1947 if (actdef_wcol) | |
1948 glShadeModel(GL_FLAT); | |
1949 | |
1950 if (is_edit) { | |
1951 BPoint *actbp = BKE_lattice_active_point_get(lt); | |
1952 | |
1953 if (v3d->zbuf) glDisable(GL_DEPTH_TEST); | |
1954 ················ | |
1955 lattice_draw_verts(lt, dl, actbp, 0); | |
1956 lattice_draw_verts(lt, dl, actbp, 1); | |
1957 ················ | |
1958 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); | |
1959 } | |
1960 } | |
1961 | |
1962 /* ***************** ******************** */ | |
1963 | |
1964 /* draw callback */ | |
1965 | |
1966 typedef struct drawDMVertSel_userData { | |
1967 MVert *mvert; | |
1968 int active; | |
1969 unsigned char *col[3]; /* (base, sel, act) */ | |
1970 char sel_prev; | |
1971 } drawDMVertSel_userData; | |
1972 | |
1973 static void drawSelectedVertices__mapFunc(void *userData, int index, const float
co[3], | |
1974 const float UNUSED(no_f[3]), const sho
rt UNUSED(no_s[3])) | |
1975 { | |
1976 drawDMVertSel_userData *data = userData; | |
1977 MVert *mv = &data->mvert[index]; | |
1978 | |
1979 if (!(mv->flag & ME_HIDE)) { | |
1980 const char sel = (index == data->active) ? 2 : (mv->flag & SELEC
T); | |
1981 if (sel != data->sel_prev) { | |
1982 glColor3ubv(data->col[sel]); | |
1983 data->sel_prev = sel; | |
1984 } | |
1985 | |
1986 glVertex3fv(co); | |
1987 } | |
1988 } | |
1989 | |
1990 static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) | |
1991 { | |
1992 drawDMVertSel_userData data; | |
1993 | |
1994 /* TODO define selected color */ | |
1995 unsigned char base_col[3] = {0x0, 0x0, 0x0}; | |
1996 unsigned char sel_col[3] = {0xd8, 0xb8, 0x0}; | |
1997 unsigned char act_col[3] = {0xff, 0xff, 0xff}; | |
1998 | |
1999 data.mvert = me->mvert; | |
2000 data.active = BKE_mesh_mselect_active_get(me, ME_VSEL); | |
2001 data.sel_prev = 0xff; | |
2002 | |
2003 data.col[0] = base_col; | |
2004 data.col[1] = sel_col; | |
2005 data.col[2] = act_col; | |
2006 | |
2007 glBegin(GL_POINTS); | |
2008 dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREA
CH_NOP); | |
2009 glEnd(); | |
2010 } | |
2011 | |
2012 /* ************** DRAW MESH ****************** */ | |
2013 | |
2014 /* First section is all the "simple" draw routines, | |
2015 * ones that just pass some sort of primitive to GL, | |
2016 * with perhaps various options to control lighting, | |
2017 * color, etc. | |
2018 * | |
2019 * These routines should not have user interface related | |
2020 * logic!!! | |
2021 */ | |
2022 | |
2023 static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data) | |
2024 { | |
2025 float obmat[3][3]; | |
2026 | |
2027 copy_m3_m4(obmat, ob->obmat); | |
2028 | |
2029 data->uniform_scale = is_uniform_scaled_m3(obmat); | |
2030 | |
2031 if (!data->uniform_scale) { | |
2032 /* inverted matrix */ | |
2033 invert_m3_m3(data->imat, obmat); | |
2034 | |
2035 /* transposed inverted matrix */ | |
2036 copy_m3_m3(data->tmat, data->imat); | |
2037 transpose_m3(data->tmat); | |
2038 } | |
2039 } | |
2040 | |
2041 static void draw_dm_face_normals__mapFunc(void *userData, int index, const float
cent[3], const float no[3]) | |
2042 { | |
2043 drawDMNormal_userData *data = userData; | |
2044 BMFace *efa = BM_face_at_index(data->bm, index); | |
2045 float n[3]; | |
2046 | |
2047 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
2048 if (!data->uniform_scale) { | |
2049 mul_v3_m3v3(n, data->tmat, no); | |
2050 normalize_v3(n); | |
2051 mul_m3_v3(data->imat, n); | |
2052 } | |
2053 else { | |
2054 copy_v3_v3(n, no); | |
2055 } | |
2056 | |
2057 glVertex3fv(cent); | |
2058 glVertex3f(cent[0] + n[0] * data->normalsize, | |
2059 cent[1] + n[1] * data->normalsize, | |
2060 cent[2] + n[2] * data->normalsize); | |
2061 } | |
2062 } | |
2063 | |
2064 static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv
edMesh *dm) | |
2065 { | |
2066 drawDMNormal_userData data; | |
2067 | |
2068 data.bm = em->bm; | |
2069 data.normalsize = scene->toolsettings->normalsize; | |
2070 | |
2071 calcDrawDMNormalScale(ob, &data); | |
2072 | |
2073 glBegin(GL_LINES); | |
2074 dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM
_FOREACH_USE_NORMAL); | |
2075 glEnd(); | |
2076 } | |
2077 | |
2078 static void draw_dm_face_centers__mapFunc(void *userData, int index, const float
cent[3], const float UNUSED(no[3])) | |
2079 { | |
2080 BMFace *efa = BM_face_at_index(((void **)userData)[0], index); | |
2081 const char sel = *(((char **)userData)[1]); | |
2082 ········ | |
2083 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && | |
2084 (BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel)) | |
2085 { | |
2086 bglVertex3fv(cent); | |
2087 } | |
2088 } | |
2089 static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) | |
2090 { | |
2091 void *ptrs[2] = {em->bm, &sel}; | |
2092 | |
2093 bglBegin(GL_POINTS); | |
2094 dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs, DM_
FOREACH_NOP); | |
2095 bglEnd(); | |
2096 } | |
2097 | |
2098 static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float
co[3], const float no_f[3], const short no_s[3]) | |
2099 { | |
2100 drawDMNormal_userData *data = userData; | |
2101 BMVert *eve = BM_vert_at_index(data->bm, index); | |
2102 | |
2103 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { | |
2104 float no[3], n[3]; | |
2105 | |
2106 if (no_f) { | |
2107 copy_v3_v3(no, no_f); | |
2108 } | |
2109 else { | |
2110 normal_short_to_float_v3(no, no_s); | |
2111 } | |
2112 | |
2113 if (!data->uniform_scale) { | |
2114 mul_v3_m3v3(n, data->tmat, no); | |
2115 normalize_v3(n); | |
2116 mul_m3_v3(data->imat, n); | |
2117 } | |
2118 else { | |
2119 copy_v3_v3(n, no); | |
2120 } | |
2121 | |
2122 glVertex3fv(co); | |
2123 glVertex3f(co[0] + n[0] * data->normalsize, | |
2124 co[1] + n[1] * data->normalsize, | |
2125 co[2] + n[2] * data->normalsize); | |
2126 } | |
2127 } | |
2128 | |
2129 static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv
edMesh *dm) | |
2130 { | |
2131 drawDMNormal_userData data; | |
2132 | |
2133 data.bm = em->bm; | |
2134 data.normalsize = scene->toolsettings->normalsize; | |
2135 | |
2136 calcDrawDMNormalScale(ob, &data); | |
2137 | |
2138 glBegin(GL_LINES); | |
2139 dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREA
CH_USE_NORMAL); | |
2140 glEnd(); | |
2141 } | |
2142 | |
2143 /* Draw verts with color set based on selection */ | |
2144 static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], | |
2145 const float UNUSED(no_f[3]), const short UNUS
ED(no_s[3])) | |
2146 { | |
2147 drawDMVerts_userData *data = userData; | |
2148 BMVert *eve = BM_vert_at_index(data->bm, index); | |
2149 | |
2150 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM
_ELEM_SELECT) == data->sel) { | |
2151 /* skin nodes: draw a red circle around the root | |
2152 * node(s) */ | |
2153 if (data->cd_vskin_offset != -1) { | |
2154 const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->c
d_vskin_offset); | |
2155 if (vs->flag & MVERT_SKIN_ROOT) { | |
2156 float radius = (vs->radius[0] + vs->radius[1]) *
0.5f; | |
2157 bglEnd(); | |
2158 ························ | |
2159 glColor4ubv(data->th_skin_root); | |
2160 drawcircball(GL_LINES, co, radius, data->imat); | |
2161 | |
2162 glColor4ubv(data->sel ? data->th_vertex_select :
data->th_vertex); | |
2163 bglBegin(GL_POINTS); | |
2164 } | |
2165 } | |
2166 | |
2167 /* draw active larger - need to stop/start point drawing for thi
s :/ */ | |
2168 if (eve == data->eve_act) { | |
2169 glColor4ubv(data->th_editmesh_active); | |
2170 ························ | |
2171 bglEnd(); | |
2172 ························ | |
2173 glPointSize(data->th_vertex_size); | |
2174 bglBegin(GL_POINTS); | |
2175 bglVertex3fv(co); | |
2176 bglEnd(); | |
2177 | |
2178 glColor4ubv(data->sel ? data->th_vertex_select : data->t
h_vertex); | |
2179 glPointSize(data->th_vertex_size); | |
2180 bglBegin(GL_POINTS); | |
2181 } | |
2182 else { | |
2183 bglVertex3fv(co); | |
2184 } | |
2185 } | |
2186 } | |
2187 | |
2188 static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
t *eve_act, | |
2189 RegionView3D *rv3d) | |
2190 { | |
2191 drawDMVerts_userData data; | |
2192 data.sel = sel; | |
2193 data.eve_act = eve_act; | |
2194 data.bm = em->bm; | |
2195 | |
2196 /* Cache theme values */ | |
2197 UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active); | |
2198 UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select); | |
2199 UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex); | |
2200 UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root); | |
2201 data.th_vertex_size = UI_GetThemeValuef(TH_VERTEX_SIZE); | |
2202 | |
2203 /* For skin root drawing */ | |
2204 data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SK
IN); | |
2205 /* view-aligned matrix */ | |
2206 mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat); | |
2207 invert_m4(data.imat); | |
2208 | |
2209 bglBegin(GL_POINTS); | |
2210 dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP)
; | |
2211 bglEnd(); | |
2212 } | |
2213 | |
2214 /* Draw edges with color set based on selection */ | |
2215 static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) | |
2216 { | |
2217 BMEdge *eed; | |
2218 //unsigned char **cols = userData, *col; | |
2219 drawDMEdgesSel_userData *data = userData; | |
2220 unsigned char *col; | |
2221 | |
2222 eed = BM_edge_at_index(data->bm, index); | |
2223 | |
2224 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | |
2225 if (eed == data->eed_act) { | |
2226 glColor4ubv(data->actCol); | |
2227 } | |
2228 else { | |
2229 if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { | |
2230 col = data->selCol; | |
2231 } | |
2232 else { | |
2233 col = data->baseCol; | |
2234 } | |
2235 /* no alpha, this is used so a transparent color can dis
able drawing unselected edges in editmode */ | |
2236 if (col[3] == 0) | |
2237 return DM_DRAW_OPTION_SKIP; | |
2238 ························ | |
2239 glColor4ubv(col); | |
2240 } | |
2241 return DM_DRAW_OPTION_NORMAL; | |
2242 } | |
2243 else { | |
2244 return DM_DRAW_OPTION_SKIP; | |
2245 } | |
2246 } | |
2247 static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
seCol, | |
2248 unsigned char *selCol, unsigned char *actCol, BMEd
ge *eed_act) | |
2249 { | |
2250 drawDMEdgesSel_userData data; | |
2251 ········ | |
2252 data.baseCol = baseCol; | |
2253 data.selCol = selCol; | |
2254 data.actCol = actCol; | |
2255 data.bm = em->bm; | |
2256 data.eed_act = eed_act; | |
2257 dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data); | |
2258 } | |
2259 | |
2260 /* Draw edges */ | |
2261 static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) | |
2262 { | |
2263 if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN)
) | |
2264 return DM_DRAW_OPTION_SKIP; | |
2265 else | |
2266 return DM_DRAW_OPTION_NORMAL; | |
2267 } | |
2268 | |
2269 static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) | |
2270 { | |
2271 dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm); | |
2272 } | |
2273 | |
2274 /* Draw edges with color interpolated based on selection */ | |
2275 static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int
index) | |
2276 { | |
2277 if (BM_elem_flag_test(BM_edge_at_index(((void **)userData)[0], index), B
M_ELEM_HIDDEN)) | |
2278 return DM_DRAW_OPTION_SKIP; | |
2279 else | |
2280 return DM_DRAW_OPTION_NORMAL; | |
2281 } | |
2282 static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i
ndex, float t) | |
2283 { | |
2284 BMEdge *eed = BM_edge_at_index(((void **)userData)[0], index); | |
2285 unsigned char **cols = userData; | |
2286 unsigned char *col0 = cols[(BM_elem_flag_test(eed->v1, BM_ELEM_SELECT))
? 2 : 1]; | |
2287 unsigned char *col1 = cols[(BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))
? 2 : 1]; | |
2288 | |
2289 glColor4ub(col0[0] + (col1[0] - col0[0]) * t, | |
2290 col0[1] + (col1[1] - col0[1]) * t, | |
2291 col0[2] + (col1[2] - col0[2]) * t, | |
2292 col0[3] + (col1[3] - col0[3]) * t); | |
2293 } | |
2294 | |
2295 static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned c
har *baseCol, unsigned char *selCol) | |
2296 { | |
2297 void *cols[3] = {em->bm, baseCol, selCol}; | |
2298 | |
2299 dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions,
draw_dm_edges_sel_interp__setDrawInterpOptions, cols); | |
2300 } | |
2301 | |
2302 /* Draw only seam edges */ | |
2303 static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int inde
x) | |
2304 { | |
2305 BMEdge *eed = BM_edge_at_index(userData, index); | |
2306 | |
2307 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM
_ELEM_SEAM)) | |
2308 return DM_DRAW_OPTION_NORMAL; | |
2309 else | |
2310 return DM_DRAW_OPTION_SKIP; | |
2311 } | |
2312 | |
2313 static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm) | |
2314 { | |
2315 dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm); | |
2316 } | |
2317 | |
2318 /* Draw only sharp edges */ | |
2319 static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int inde
x) | |
2320 { | |
2321 BMEdge *eed = BM_edge_at_index(userData, index); | |
2322 | |
2323 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, B
M_ELEM_SMOOTH)) | |
2324 return DM_DRAW_OPTION_NORMAL; | |
2325 else | |
2326 return DM_DRAW_OPTION_SKIP; | |
2327 } | |
2328 | |
2329 static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) | |
2330 { | |
2331 dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm); | |
2332 } | |
2333 | |
2334 #ifdef WITH_FREESTYLE | |
2335 | |
2336 static int draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed) | |
2337 { | |
2338 FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD
_FREESTYLE_EDGE); | |
2339 if (!fed) | |
2340 return 0; | |
2341 return (fed->flag & FREESTYLE_EDGE_MARK) != 0; | |
2342 } | |
2343 | |
2344 /* Draw only Freestyle feature edges */ | |
2345 static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int
index) | |
2346 { | |
2347 BMEdge *eed = BM_edge_at_index(userData, index); | |
2348 | |
2349 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_ed
ge_mark(userData, eed)) | |
2350 return DM_DRAW_OPTION_NORMAL; | |
2351 else | |
2352 return DM_DRAW_OPTION_SKIP; | |
2353 } | |
2354 | |
2355 static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) | |
2356 { | |
2357 dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm)
; | |
2358 } | |
2359 | |
2360 static int draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa) | |
2361 { | |
2362 FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD
_FREESTYLE_FACE); | |
2363 if (!ffa) | |
2364 return 0; | |
2365 return (ffa->flag & FREESTYLE_FACE_MARK) != 0; | |
2366 } | |
2367 | |
2368 #endif | |
2369 | |
2370 /* Draw faces with color set based on selection | |
2371 * return 2 for the active face so it renders with stipple enabled */ | |
2372 static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) | |
2373 { | |
2374 drawDMFacesSel_userData *data = userData; | |
2375 BMFace *efa = BM_face_at_index(data->bm, index); | |
2376 unsigned char *col; | |
2377 ········ | |
2378 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
2379 if (efa == data->efa_act) { | |
2380 glColor4ubv(data->cols[2]); | |
2381 return DM_DRAW_OPTION_STIPPLE; | |
2382 } | |
2383 else { | |
2384 #ifdef WITH_FREESTYLE | |
2385 col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT)
? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; | |
2386 #else | |
2387 col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT)
? 1 : 0]; | |
2388 #endif | |
2389 if (col[3] == 0) | |
2390 return DM_DRAW_OPTION_SKIP; | |
2391 glColor4ubv(col); | |
2392 return DM_DRAW_OPTION_NORMAL; | |
2393 } | |
2394 } | |
2395 return DM_DRAW_OPTION_SKIP; | |
2396 } | |
2397 | |
2398 static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
next_index) | |
2399 { | |
2400 | |
2401 drawDMFacesSel_userData *data = userData; | |
2402 int i; | |
2403 BMFace *efa; | |
2404 BMFace *next_efa; | |
2405 | |
2406 unsigned char *col, *next_col; | |
2407 | |
2408 if (!data->orig_index_mf_to_mpoly) | |
2409 return 0; | |
2410 | |
2411 i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_in
dex_mp_to_orig, index); | |
2412 efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; | |
2413 i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_in
dex_mp_to_orig, next_index); | |
2414 next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; | |
2415 | |
2416 if (ELEM(NULL, efa, next_efa)) | |
2417 return 0; | |
2418 | |
2419 if (efa == next_efa) | |
2420 return 1; | |
2421 | |
2422 if (efa == data->efa_act || next_efa == data->efa_act) | |
2423 return 0; | |
2424 | |
2425 #ifdef WITH_FREESTYLE | |
2426 col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_te
st_freestyle_face_mark(data->bm, efa) ? 3 : 0]; | |
2427 next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 :
draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; | |
2428 #else | |
2429 col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; | |
2430 next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 :
0]; | |
2431 #endif | |
2432 | |
2433 if (col[3] == 0 || next_col[3] == 0) | |
2434 return 0; | |
2435 | |
2436 return col == next_col; | |
2437 } | |
2438 | |
2439 /* also draws the active face */ | |
2440 #ifdef WITH_FREESTYLE | |
2441 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
seCol, | |
2442 unsigned char *selCol, unsigned char *actCol, unsi
gned char *markCol, BMFace *efa_act) | |
2443 #else | |
2444 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
seCol, | |
2445 unsigned char *selCol, unsigned char *actCol, BMFa
ce *efa_act) | |
2446 #endif | |
2447 { | |
2448 drawDMFacesSel_userData data; | |
2449 data.dm = dm; | |
2450 data.cols[0] = baseCol; | |
2451 data.bm = em->bm; | |
2452 data.cols[1] = selCol; | |
2453 data.cols[2] = actCol; | |
2454 #ifdef WITH_FREESTYLE | |
2455 data.cols[3] = markCol; | |
2456 #endif | |
2457 data.efa_act = efa_act; | |
2458 /* double lookup */ | |
2459 data.orig_index_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDE
X); | |
2460 data.orig_index_mp_to_orig = DM_get_poly_data_layer(dm, CD_ORIGINDEX); | |
2461 if ((data.orig_index_mf_to_mpoly && data.orig_index_mp_to_orig) == false
) { | |
2462 data.orig_index_mf_to_mpoly = data.orig_index_mp_to_orig = NULL; | |
2463 } | |
2464 | |
2465 dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_ma
terial, draw_dm_faces_sel__compareDrawOptions, &data, 0); | |
2466 } | |
2467 | |
2468 static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index) | |
2469 { | |
2470 drawDMLayer_userData *data = userData; | |
2471 BMesh *bm = data->bm; | |
2472 BMEdge *eed = BM_edge_at_index(bm, index); | |
2473 ········ | |
2474 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | |
2475 const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_of
fset); | |
2476 if (crease != 0.0f) { | |
2477 UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease)
; | |
2478 return DM_DRAW_OPTION_NORMAL; | |
2479 } | |
2480 } | |
2481 return DM_DRAW_OPTION_SKIP; | |
2482 } | |
2483 static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm) | |
2484 { | |
2485 drawDMLayer_userData data; | |
2486 | |
2487 data.bm = em->bm; | |
2488 data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); | |
2489 | |
2490 if (data.cd_layer_offset != -1) { | |
2491 glLineWidth(3.0); | |
2492 dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data); | |
2493 glLineWidth(1.0); | |
2494 } | |
2495 } | |
2496 | |
2497 static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) | |
2498 { | |
2499 drawDMLayer_userData *data = userData; | |
2500 BMesh *bm = data->bm; | |
2501 BMEdge *eed = BM_edge_at_index(bm, index); | |
2502 | |
2503 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | |
2504 const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_o
ffset); | |
2505 if (bweight != 0.0f) { | |
2506 UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, bweight
); | |
2507 return DM_DRAW_OPTION_NORMAL; | |
2508 } | |
2509 } | |
2510 return DM_DRAW_OPTION_SKIP; | |
2511 } | |
2512 static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[
3], | |
2513 const float UNUSED(no_f[3]), const short U
NUSED(no_s[3])) | |
2514 { | |
2515 drawDMLayer_userData *data = userData; | |
2516 BMesh *bm = data->bm; | |
2517 BMVert *eve = BM_vert_at_index(bm, index); | |
2518 | |
2519 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { | |
2520 const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_o
ffset); | |
2521 if (bweight != 0.0f) { | |
2522 UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, bweight)
; | |
2523 bglVertex3fv(co); | |
2524 } | |
2525 } | |
2526 } | |
2527 static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) | |
2528 { | |
2529 ToolSettings *ts = scene->toolsettings; | |
2530 | |
2531 if (ts->selectmode & SCE_SELECT_VERTEX) { | |
2532 drawDMLayer_userData data; | |
2533 | |
2534 data.bm = em->bm; | |
2535 data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_
BWEIGHT); | |
2536 | |
2537 if (data.cd_layer_offset != -1) { | |
2538 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); | |
2539 bglBegin(GL_POINTS); | |
2540 dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &da
ta, DM_FOREACH_NOP); | |
2541 bglEnd(); | |
2542 } | |
2543 } | |
2544 else { | |
2545 drawDMLayer_userData data; | |
2546 | |
2547 data.bm = em->bm; | |
2548 data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_
BWEIGHT); | |
2549 | |
2550 if (data.cd_layer_offset != -1) { | |
2551 glLineWidth(3.0); | |
2552 dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions
, &data); | |
2553 glLineWidth(1.0); | |
2554 } | |
2555 } | |
2556 } | |
2557 | |
2558 static int draw_dm_override_material_color(int UNUSED(nr), void *UNUSED(attribs)
) | |
2559 { | |
2560 return 1; | |
2561 } | |
2562 | |
2563 /* Second section of routines: Combine first sets to form fancy | |
2564 * drawing routines (for example rendering twice to get overlays). | |
2565 * | |
2566 * Also includes routines that are basic drawing but are too | |
2567 * specialized to be split out (like drawing creases or measurements). | |
2568 */ | |
2569 | |
2570 /* EditMesh drawing routines*/ | |
2571 | |
2572 static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, | |
2573 BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve
_act, | |
2574 RegionView3D *rv3d) | |
2575 { | |
2576 ToolSettings *ts = scene->toolsettings; | |
2577 int sel; | |
2578 | |
2579 if (v3d->zbuf) glDepthMask(0); /* disable write in zbuffer, zbuf select
*/ | |
2580 | |
2581 for (sel = 0; sel < 2; sel++) { | |
2582 unsigned char col[4], fcol[4]; | |
2583 int pass; | |
2584 | |
2585 UI_GetThemeColor3ubv(sel ? TH_VERTEX_SELECT : TH_VERTEX, col); | |
2586 UI_GetThemeColor3ubv(sel ? TH_FACE_DOT : TH_WIRE_EDIT, fcol); | |
2587 | |
2588 for (pass = 0; pass < 2; pass++) { | |
2589 float size = UI_GetThemeValuef(TH_VERTEX_SIZE); | |
2590 float fsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); | |
2591 | |
2592 if (pass == 0) { | |
2593 if (v3d->zbuf && !(v3d->flag & V3D_ZBUF_SELECT))
{ | |
2594 glDisable(GL_DEPTH_TEST); | |
2595 | |
2596 glEnable(GL_BLEND); | |
2597 } | |
2598 else { | |
2599 continue; | |
2600 } | |
2601 | |
2602 size = (size > 2.1f ? size / 2.0f : size); | |
2603 fsize = (fsize > 2.1f ? fsize / 2.0f : fsize); | |
2604 col[3] = fcol[3] = 100; | |
2605 } | |
2606 else { | |
2607 col[3] = fcol[3] = 255; | |
2608 } | |
2609 | |
2610 if (ts->selectmode & SCE_SELECT_VERTEX) { | |
2611 glPointSize(size); | |
2612 glColor4ubv(col); | |
2613 draw_dm_verts(em, cageDM, sel, eve_act, rv3d); | |
2614 } | |
2615 ························ | |
2616 if (check_ob_drawface_dot(scene, v3d, obedit->dt)) { | |
2617 glPointSize(fsize); | |
2618 glColor4ubv(fcol); | |
2619 draw_dm_face_centers(em, cageDM, sel); | |
2620 } | |
2621 ························ | |
2622 if (pass == 0) { | |
2623 glDisable(GL_BLEND); | |
2624 glEnable(GL_DEPTH_TEST); | |
2625 } | |
2626 } | |
2627 } | |
2628 | |
2629 if (v3d->zbuf) glDepthMask(1); | |
2630 glPointSize(1.0); | |
2631 } | |
2632 | |
2633 static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, | |
2634 Mesh *me, DerivedMesh *cageDM, short sel_only, | |
2635 BMEdge *eed_act) | |
2636 { | |
2637 ToolSettings *ts = scene->toolsettings; | |
2638 int pass; | |
2639 unsigned char wireCol[4], selCol[4], actCol[4]; | |
2640 | |
2641 /* since this function does transparent... */ | |
2642 UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol); | |
2643 UI_GetThemeColor4ubv(TH_WIRE_EDIT, wireCol); | |
2644 UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol); | |
2645 ········ | |
2646 /* when sel only is used, don't render wire, only selected, this is used
for | |
2647 * textured draw mode when the 'edges' option is disabled */ | |
2648 if (sel_only) | |
2649 wireCol[3] = 0; | |
2650 | |
2651 for (pass = 0; pass < 2; pass++) { | |
2652 /* show wires in transparent when no zbuf clipping for select */ | |
2653 if (pass == 0) { | |
2654 if (v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT) == 0) { | |
2655 glEnable(GL_BLEND); | |
2656 glDisable(GL_DEPTH_TEST); | |
2657 selCol[3] = 85; | |
2658 if (!sel_only) wireCol[3] = 85; | |
2659 } | |
2660 else { | |
2661 continue; | |
2662 } | |
2663 } | |
2664 else { | |
2665 selCol[3] = 255; | |
2666 if (!sel_only) wireCol[3] = 255; | |
2667 } | |
2668 | |
2669 if (ts->selectmode == SCE_SELECT_FACE) { | |
2670 draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, e
ed_act); | |
2671 } | |
2672 else if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_
SELECT_EDGE)) { | |
2673 if (cageDM->drawMappedEdgesInterp && (ts->selectmode & S
CE_SELECT_VERTEX)) { | |
2674 glShadeModel(GL_SMOOTH); | |
2675 draw_dm_edges_sel_interp(em, cageDM, wireCol, se
lCol); | |
2676 glShadeModel(GL_FLAT); | |
2677 } | |
2678 else { | |
2679 draw_dm_edges_sel(em, cageDM, wireCol, selCol, a
ctCol, eed_act); | |
2680 } | |
2681 } | |
2682 else { | |
2683 if (!sel_only) { | |
2684 glColor4ubv(wireCol); | |
2685 draw_dm_edges(em, cageDM); | |
2686 } | |
2687 } | |
2688 | |
2689 if (pass == 0) { | |
2690 glDisable(GL_BLEND); | |
2691 glEnable(GL_DEPTH_TEST); | |
2692 } | |
2693 } | |
2694 } | |
2695 | |
2696 static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
sh *em, UnitSettings *unit) | |
2697 { | |
2698 /* Do not use ascii when using non-default unit system, some unit chars
are utf8 (micro, square, etc.). | |
2699 * See bug #36090. | |
2700 */ | |
2701 const short txt_flag = V3D_CACHE_TEXT_LOCALCLIP | (unit->system ? 0 : V3
D_CACHE_TEXT_ASCII); | |
2702 Mesh *me = ob->data; | |
2703 float v1[3], v2[3], v3[3], vmid[3], fvec[3]; | |
2704 char numstr[32]; /* Stores the measurement display text here */ | |
2705 const char *conv_float; /* Use a float conversion matching the grid size
*/ | |
2706 unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */ | |
2707 float area; /* area of the face */ | |
2708 float grid = unit->system ? unit->scale_length : v3d->grid; | |
2709 const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; | |
2710 const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; | |
2711 const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0; | |
2712 float clip_planes[4][4]; | |
2713 /* allow for displaying shape keys and deform mods */ | |
2714 DerivedMesh *dm = EDBM_mesh_deform_dm_get(em); | |
2715 BMIter iter; | |
2716 int i; | |
2717 | |
2718 /* make the precision of the display value proportionate to the gridsize
*/ | |
2719 | |
2720 if (grid <= 0.01f) conv_float = "%.6g"; | |
2721 else if (grid <= 0.1f) conv_float = "%.5g"; | |
2722 else if (grid <= 1.0f) conv_float = "%.4g"; | |
2723 else if (grid <= 10.0f) conv_float = "%.3g"; | |
2724 else conv_float = "%.2g"; | |
2725 | |
2726 if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) { | |
2727 BoundBox bb; | |
2728 bglMats mats = {{0}}; | |
2729 const rcti rect = {0, ar->winx, 0, ar->winy}; | |
2730 | |
2731 view3d_get_transformation(ar, ar->regiondata, em->ob, &mats); | |
2732 ED_view3d_clipping_calc(&bb, clip_planes, &mats, &rect); | |
2733 } | |
2734 | |
2735 if (me->drawflag & ME_DRAWEXTRA_EDGELEN) { | |
2736 BMEdge *eed; | |
2737 | |
2738 UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); | |
2739 | |
2740 if (dm) { | |
2741 BM_mesh_elem_index_ensure(em->bm, BM_VERT); | |
2742 } | |
2743 | |
2744 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | |
2745 /* draw selected edges, or edges next to selected verts
while draging */ | |
2746 if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || | |
2747 (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SE
LECT) || | |
2748 BM_elem_flag_test(eed->v2, BM_ELEM_SE
LECT)))) | |
2749 { | |
2750 float v1_clip[3], v2_clip[3]; | |
2751 | |
2752 if (dm) { | |
2753 dm->getVertCo(dm, BM_elem_index_get(eed-
>v1), v1); | |
2754 dm->getVertCo(dm, BM_elem_index_get(eed-
>v2), v2); | |
2755 } | |
2756 else { | |
2757 copy_v3_v3(v1, eed->v1->co); | |
2758 copy_v3_v3(v2, eed->v2->co); | |
2759 } | |
2760 | |
2761 copy_v3_v3(v1_clip, v1); | |
2762 copy_v3_v3(v2_clip, v2); | |
2763 | |
2764 if (clip_segment_v3_plane_n(v1_clip, v2_clip, cl
ip_planes, 4)) { | |
2765 | |
2766 mid_v3_v3v3(vmid, v1_clip, v2_clip); | |
2767 | |
2768 if (do_global) { | |
2769 mul_mat3_m4_v3(ob->obmat, v1); | |
2770 mul_mat3_m4_v3(ob->obmat, v2); | |
2771 } | |
2772 | |
2773 if (unit->system) { | |
2774 bUnit_AsString(numstr, sizeof(nu
mstr), len_v3v3(v1, v2) * unit->scale_length, 3, | |
2775 unit->system, B_U
NIT_LENGTH, do_split, false); | |
2776 } | |
2777 else { | |
2778 BLI_snprintf(numstr, sizeof(nums
tr), conv_float, len_v3v3(v1, v2)); | |
2779 } | |
2780 | |
2781 view3d_cached_text_draw_add(vmid, numstr
, 0, txt_flag, col); | |
2782 } | |
2783 } | |
2784 } | |
2785 } | |
2786 | |
2787 if (me->drawflag & ME_DRAWEXTRA_EDGEANG) { | |
2788 const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADI
ANS); | |
2789 BMEdge *eed; | |
2790 | |
2791 UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col); | |
2792 | |
2793 if (dm) { | |
2794 BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); | |
2795 } | |
2796 | |
2797 // invert_m4_m4(ob->imat, ob->obmat); // this is already called | |
2798 | |
2799 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | |
2800 BMLoop *l_a, *l_b; | |
2801 if (BM_edge_loop_pair(eed, &l_a, &l_b)) { | |
2802 /* draw selected edges, or edges next to selecte
d verts while draging */ | |
2803 if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || | |
2804 (do_moving && (BM_elem_flag_test(eed->v1, BM
_ELEM_SELECT) || | |
2805 BM_elem_flag_test(eed->v2, BM
_ELEM_SELECT) || | |
2806 /* special case, this is usef
ul to show when vertes connected to this edge via a | |
2807 * face are being transformed
*/ | |
2808 BM_elem_flag_test(l_a->next->
next->v, BM_ELEM_SELECT) || | |
2809 BM_elem_flag_test(l_a->prev->
v, BM_ELEM_SELECT) || | |
2810 BM_elem_flag_test(l_b->next->
next->v, BM_ELEM_SELECT) || | |
2811 BM_elem_flag_test(l_b->prev->
v, BM_ELEM_SELECT) | |
2812 ))) | |
2813 { | |
2814 float v1_clip[3], v2_clip[3]; | |
2815 | |
2816 if (dm) { | |
2817 dm->getVertCo(dm, BM_elem_index_
get(eed->v1), v1); | |
2818 dm->getVertCo(dm, BM_elem_index_
get(eed->v2), v2); | |
2819 } | |
2820 else { | |
2821 copy_v3_v3(v1, eed->v1->co); | |
2822 copy_v3_v3(v2, eed->v2->co); | |
2823 } | |
2824 | |
2825 copy_v3_v3(v1_clip, v1); | |
2826 copy_v3_v3(v2_clip, v2); | |
2827 | |
2828 if (clip_segment_v3_plane_n(v1_clip, v2_
clip, clip_planes, 4)) { | |
2829 float no_a[3], no_b[3]; | |
2830 float angle; | |
2831 | |
2832 mid_v3_v3v3(vmid, v1_clip, v2_cl
ip); | |
2833 | |
2834 if (dm) { | |
2835 dm->getPolyNo(dm, BM_ele
m_index_get(l_a->f), no_a); | |
2836 dm->getPolyNo(dm, BM_ele
m_index_get(l_b->f), no_b); | |
2837 } | |
2838 else { | |
2839 copy_v3_v3(no_a, l_a->f-
>no); | |
2840 copy_v3_v3(no_b, l_b->f-
>no); | |
2841 } | |
2842 | |
2843 if (do_global) { | |
2844 mul_mat3_m4_v3(ob->imat,
no_a); | |
2845 mul_mat3_m4_v3(ob->imat,
no_b); | |
2846 normalize_v3(no_a); | |
2847 normalize_v3(no_b); | |
2848 } | |
2849 | |
2850 angle = angle_normalized_v3v3(no
_a, no_b); | |
2851 | |
2852 BLI_snprintf(numstr, sizeof(nums
tr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); | |
2853 | |
2854 view3d_cached_text_draw_add(vmid
, numstr, 0, txt_flag, col); | |
2855 } | |
2856 } | |
2857 } | |
2858 } | |
2859 } | |
2860 | |
2861 if (me->drawflag & ME_DRAWEXTRA_FACEAREA) { | |
2862 /* would be nice to use BM_face_calc_area, but that is for 2d fa
ces | |
2863 * so instead add up tessellation triangle areas */ | |
2864 BMFace *f; | |
2865 int n; | |
2866 | |
2867 #define DRAW_EM_MEASURE_STATS_FACEAREA()
\ | |
2868 if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
\ | |
2869 mul_v3_fl(vmid, 1.0f / (float)n);
\ | |
2870 if (unit->system) {
\ | |
2871 bUnit_AsString(numstr, sizeof(numstr),
\ | |
2872 (double)(area * unit->scale_length * unit
->scale_length), \ | |
2873 3, unit->system, B_UNIT_AREA, do_split, f
alse); \ | |
2874 }
\ | |
2875 else {
\ | |
2876 BLI_snprintf(numstr, sizeof(numstr), conv_float, area);
\ | |
2877 }
\ | |
2878 view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
\ | |
2879 } (void)0 | |
2880 | |
2881 UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); | |
2882 ················ | |
2883 if (dm) { | |
2884 BM_mesh_elem_index_ensure(em->bm, BM_VERT); | |
2885 } | |
2886 | |
2887 f = NULL; | |
2888 area = 0.0; | |
2889 zero_v3(vmid); | |
2890 n = 0; | |
2891 for (i = 0; i < em->tottri; i++) { | |
2892 BMLoop **l = em->looptris[i]; | |
2893 if (f && l[0]->f != f) { | |
2894 DRAW_EM_MEASURE_STATS_FACEAREA(); | |
2895 zero_v3(vmid); | |
2896 area = 0.0; | |
2897 n = 0; | |
2898 } | |
2899 | |
2900 f = l[0]->f; | |
2901 | |
2902 if (dm) { | |
2903 dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1
); | |
2904 dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2
); | |
2905 dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3
); | |
2906 } | |
2907 else { | |
2908 copy_v3_v3(v1, l[0]->v->co); | |
2909 copy_v3_v3(v2, l[1]->v->co); | |
2910 copy_v3_v3(v3, l[2]->v->co); | |
2911 } | |
2912 | |
2913 add_v3_v3(vmid, v1); | |
2914 add_v3_v3(vmid, v2); | |
2915 add_v3_v3(vmid, v3); | |
2916 n += 3; | |
2917 if (do_global) { | |
2918 mul_mat3_m4_v3(ob->obmat, v1); | |
2919 mul_mat3_m4_v3(ob->obmat, v2); | |
2920 mul_mat3_m4_v3(ob->obmat, v3); | |
2921 } | |
2922 area += area_tri_v3(v1, v2, v3); | |
2923 } | |
2924 | |
2925 if (f) { | |
2926 DRAW_EM_MEASURE_STATS_FACEAREA(); | |
2927 } | |
2928 #undef DRAW_EM_MEASURE_STATS_FACEAREA | |
2929 } | |
2930 | |
2931 if (me->drawflag & ME_DRAWEXTRA_FACEANG) { | |
2932 BMFace *efa; | |
2933 const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADI
ANS); | |
2934 | |
2935 UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); | |
2936 | |
2937 if (dm) { | |
2938 BM_mesh_elem_index_ensure(em->bm, BM_VERT); | |
2939 } | |
2940 | |
2941 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | |
2942 const int is_face_sel = BM_elem_flag_test(efa, BM_ELEM_S
ELECT); | |
2943 | |
2944 if (is_face_sel || do_moving) { | |
2945 BMIter liter; | |
2946 BMLoop *loop; | |
2947 bool is_first = true; | |
2948 | |
2949 BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FAC
E) { | |
2950 if (is_face_sel || (do_moving && BM_elem
_flag_test(loop->v, BM_ELEM_SELECT))) { | |
2951 float angle; | |
2952 float v2_local[3]; | |
2953 | |
2954 /* lazy init center calc */ | |
2955 if (is_first) { | |
2956 if (dm) { | |
2957 BMLoop *l_iter,
*l_first; | |
2958 float tvec[3]; | |
2959 zero_v3(vmid); | |
2960 l_iter = l_first
= BM_FACE_FIRST_LOOP(efa); | |
2961 do { | |
2962 dm->getV
ertCo(dm, BM_elem_index_get(l_iter->v), tvec); | |
2963 add_v3_v
3(vmid, tvec); | |
2964 } while ((l_iter
= l_iter->next) != l_first); | |
2965 mul_v3_fl(vmid,
1.0f / (float)efa->len); | |
2966 } | |
2967 else { | |
2968 BM_face_calc_cen
ter_bounds(efa, vmid); | |
2969 } | |
2970 is_first = false; | |
2971 } | |
2972 | |
2973 if (dm) { | |
2974 dm->getVertCo(dm, BM_ele
m_index_get(loop->prev->v), v1); | |
2975 dm->getVertCo(dm, BM_ele
m_index_get(loop->v), v2); | |
2976 dm->getVertCo(dm, BM_ele
m_index_get(loop->next->v), v3); | |
2977 } | |
2978 else { | |
2979 copy_v3_v3(v1, loop->pre
v->v->co); | |
2980 copy_v3_v3(v2, loop->v->
co); | |
2981 copy_v3_v3(v3, loop->nex
t->v->co); | |
2982 } | |
2983 | |
2984 copy_v3_v3(v2_local, v2); | |
2985 | |
2986 if (do_global) { | |
2987 mul_mat3_m4_v3(ob->obmat
, v1); | |
2988 mul_mat3_m4_v3(ob->obmat
, v2); | |
2989 mul_mat3_m4_v3(ob->obmat
, v3); | |
2990 } | |
2991 | |
2992 angle = angle_v3v3v3(v1, v2, v3)
; | |
2993 | |
2994 BLI_snprintf(numstr, sizeof(nums
tr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); | |
2995 interp_v3_v3v3(fvec, vmid, v2_lo
cal, 0.8f); | |
2996 view3d_cached_text_draw_add(fvec
, numstr, 0, txt_flag, col); | |
2997 } | |
2998 } | |
2999 } | |
3000 } | |
3001 } | |
3002 } | |
3003 | |
3004 static void draw_em_indices(BMEditMesh *em) | |
3005 { | |
3006 const short txt_flag = V3D_CACHE_TEXT_ASCII | V3D_CACHE_TEXT_LOCALCLIP; | |
3007 BMEdge *e; | |
3008 BMFace *f; | |
3009 BMVert *v; | |
3010 int i; | |
3011 char numstr[32]; | |
3012 float pos[3]; | |
3013 unsigned char col[4]; | |
3014 | |
3015 BMIter iter; | |
3016 BMesh *bm = em->bm; | |
3017 | |
3018 /* For now, reuse appropriate theme colors from stats text colors */ | |
3019 i = 0; | |
3020 if (em->selectmode & SCE_SELECT_VERTEX) { | |
3021 UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); | |
3022 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | |
3023 if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { | |
3024 BLI_snprintf(numstr, sizeof(numstr), "%d", i); | |
3025 view3d_cached_text_draw_add(v->co, numstr, 0, tx
t_flag, col); | |
3026 } | |
3027 i++; | |
3028 } | |
3029 } | |
3030 | |
3031 if (em->selectmode & SCE_SELECT_EDGE) { | |
3032 i = 0; | |
3033 UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); | |
3034 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | |
3035 if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { | |
3036 BLI_snprintf(numstr, sizeof(numstr), "%d", i); | |
3037 mid_v3_v3v3(pos, e->v1->co, e->v2->co); | |
3038 view3d_cached_text_draw_add(pos, numstr, 0, txt_
flag, col); | |
3039 } | |
3040 i++; | |
3041 } | |
3042 } | |
3043 | |
3044 if (em->selectmode & SCE_SELECT_FACE) { | |
3045 i = 0; | |
3046 UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); | |
3047 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { | |
3048 if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { | |
3049 BM_face_calc_center_mean(f, pos); | |
3050 BLI_snprintf(numstr, sizeof(numstr), "%d", i); | |
3051 view3d_cached_text_draw_add(pos, numstr, 0, txt_
flag, col); | |
3052 } | |
3053 i++; | |
3054 } | |
3055 } | |
3056 } | |
3057 | |
3058 static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) | |
3059 { | |
3060 BMEditMesh *em = userData; | |
3061 BMFace *efa; | |
3062 | |
3063 if (UNLIKELY(index >= em->bm->totface)) | |
3064 return DM_DRAW_OPTION_NORMAL; | |
3065 | |
3066 efa = BM_face_at_index(em->bm, index); | |
3067 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
3068 GPU_enable_material(efa->mat_nr + 1, NULL); | |
3069 return DM_DRAW_OPTION_NORMAL; | |
3070 } | |
3071 else { | |
3072 return DM_DRAW_OPTION_SKIP; | |
3073 } | |
3074 } | |
3075 | |
3076 static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) | |
3077 { | |
3078 BMEditMesh *em = userData; | |
3079 BMFace *efa; | |
3080 | |
3081 if (UNLIKELY(index >= em->bm->totface)) | |
3082 return DM_DRAW_OPTION_NORMAL; | |
3083 | |
3084 efa = BM_face_at_index(em->bm, index); | |
3085 | |
3086 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
3087 return DM_DRAW_OPTION_NORMAL; | |
3088 } | |
3089 else { | |
3090 return DM_DRAW_OPTION_SKIP; | |
3091 } | |
3092 } | |
3093 | |
3094 static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, | |
3095 Object *ob, BMEditMesh *em, DerivedMesh *cageDM, Deriv
edMesh *finalDM, const char dt) | |
3096 | |
3097 { | |
3098 RegionView3D *rv3d = ar->regiondata; | |
3099 Mesh *me = ob->data; | |
3100 BMFace *efa_act = BM_mesh_active_face_get(em->bm, false, true); /* annoy
ing but active faces is stored differently */ | |
3101 BMEdge *eed_act = NULL; | |
3102 BMVert *eve_act = NULL; | |
3103 bool use_occlude_wire = (v3d->flag2 & V3D_OCCLUDE_WIRE) && (dt > OB_WIRE
); | |
3104 ········ | |
3105 if (em->bm->selected.last) { | |
3106 BMEditSelection *ese = em->bm->selected.last; | |
3107 /* face is handeled above */ | |
3108 #if 0 | |
3109 if (ese->type == BM_FACE) { | |
3110 efa_act = (BMFace *)ese->data; | |
3111 } | |
3112 else | |
3113 #endif | |
3114 if (ese->htype == BM_EDGE) { | |
3115 eed_act = (BMEdge *)ese->ele; | |
3116 } | |
3117 else if (ese->htype == BM_VERT) { | |
3118 eve_act = (BMVert *)ese->ele; | |
3119 } | |
3120 } | |
3121 ········ | |
3122 BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); | |
3123 | |
3124 if (check_object_draw_editweight(me, finalDM)) { | |
3125 if (dt > OB_WIRE) { | |
3126 draw_mesh_paint_weight_faces(finalDM, true, draw_em_fanc
y__setFaceOpts, me->edit_btmesh); | |
3127 | |
3128 bglPolygonOffset(rv3d->dist, 1.0); | |
3129 glDepthMask(0); | |
3130 } | |
3131 else { | |
3132 glEnable(GL_DEPTH_TEST); | |
3133 draw_mesh_paint_weight_faces(finalDM, false, draw_em_fan
cy__setFaceOpts, me->edit_btmesh); | |
3134 draw_mesh_paint_weight_edges(rv3d, finalDM, true, draw_d
m_edges__setDrawOptions, me->edit_btmesh->bm); | |
3135 glDisable(GL_DEPTH_TEST); | |
3136 } | |
3137 } | |
3138 else if (dt > OB_WIRE) { | |
3139 if (use_occlude_wire) { | |
3140 /* use the cageDM since it always overlaps the editmesh
faces */ | |
3141 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | |
3142 cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOp
ts, | |
3143 GPU_enable_material, NULL, me->e
dit_btmesh, 0); | |
3144 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
3145 } | |
3146 else if (check_object_draw_texture(scene, v3d, dt)) { | |
3147 if (draw_glsl_material(scene, ob, v3d, dt)) { | |
3148 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_
CW : GL_CCW); | |
3149 | |
3150 finalDM->drawMappedFacesGLSL(finalDM, GPU_enable
_material, | |
3151 draw_em_fancy__setG
LSLFaceOpts, em); | |
3152 GPU_disable_material(); | |
3153 | |
3154 glFrontFace(GL_CCW); | |
3155 } | |
3156 else { | |
3157 draw_mesh_textured(scene, v3d, rv3d, ob, finalDM
, 0); | |
3158 } | |
3159 } | |
3160 else { | |
3161 /* 3 floats for position, | |
3162 * 3 for normal and times two because the faces may actu
ally be quads instead of triangles */ | |
3163 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TW
OSIDED) ? GL_TRUE : GL_FALSE); | |
3164 | |
3165 glEnable(GL_LIGHTING); | |
3166 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_
CCW); | |
3167 finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFace
Opts, GPU_enable_material, NULL, me->edit_btmesh, 0); | |
3168 | |
3169 glFrontFace(GL_CCW); | |
3170 glDisable(GL_LIGHTING); | |
3171 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); | |
3172 } | |
3173 | |
3174 /* Setup for drawing wire over, disable zbuffer | |
3175 * write to show selected edge wires better */ | |
3176 UI_ThemeColor(TH_WIRE_EDIT); | |
3177 | |
3178 bglPolygonOffset(rv3d->dist, 1.0); | |
3179 glDepthMask(0); | |
3180 } | |
3181 else { | |
3182 if (cageDM != finalDM) { | |
3183 UI_ThemeColorBlend(TH_WIRE_EDIT, TH_BACK, 0.7); | |
3184 finalDM->drawEdges(finalDM, 1, 0); | |
3185 } | |
3186 } | |
3187 | |
3188 if ((me->drawflag & ME_DRAWFACES) && (use_occlude_wire == false)) { /*
transp faces */ | |
3189 unsigned char col1[4], col2[4], col3[4]; | |
3190 #ifdef WITH_FREESTYLE | |
3191 unsigned char col4[4]; | |
3192 #endif | |
3193 | |
3194 UI_GetThemeColor4ubv(TH_FACE, col1); | |
3195 UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); | |
3196 UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); | |
3197 #ifdef WITH_FREESTYLE | |
3198 UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col4); | |
3199 #endif | |
3200 | |
3201 glEnable(GL_BLEND); | |
3202 glDepthMask(0); /* disable write in zbuffer, needed for nice tr
ansp */ | |
3203 | |
3204 /* don't draw unselected faces, only selected, this is MUCH nice
r when texturing */ | |
3205 if (check_object_draw_texture(scene, v3d, dt)) | |
3206 col1[3] = 0; | |
3207 | |
3208 #ifdef WITH_FREESTYLE | |
3209 if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE) || !CustomData_has_
layer(&em->bm->pdata, CD_FREESTYLE_FACE)) | |
3210 col4[3] = 0; | |
3211 | |
3212 draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); | |
3213 #else | |
3214 draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); | |
3215 #endif | |
3216 | |
3217 glDisable(GL_BLEND); | |
3218 glDepthMask(1); /* restore write in zbuffer */ | |
3219 } | |
3220 else if (efa_act) { | |
3221 /* even if draw faces is off it would be nice to draw the stippl
e face | |
3222 * Make all other faces zero alpha except for the active | |
3223 * */ | |
3224 /* col4 is only used by WITH_FREESTYLE, but keeping it here spar
es some #ifdef's... */ | |
3225 unsigned char col1[4], col2[4], col3[4], col4[4]; | |
3226 col1[3] = col2[3] = col4[3] = 0; /* don't draw */ | |
3227 UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); | |
3228 | |
3229 glEnable(GL_BLEND); | |
3230 glDepthMask(0); /* disable write in zbuffer, needed for nice tr
ansp */ | |
3231 | |
3232 #ifdef WITH_FREESTYLE | |
3233 draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); | |
3234 #else | |
3235 draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); | |
3236 #endif | |
3237 | |
3238 glDisable(GL_BLEND); | |
3239 glDepthMask(1); /* restore write in zbuffer */ | |
3240 | |
3241 } | |
3242 | |
3243 /* here starts all fancy draw-extra over */ | |
3244 if ((me->drawflag & ME_DRAWEDGES) == 0 && check_object_draw_texture(scen
e, v3d, dt)) { | |
3245 /* we are drawing textures and 'ME_DRAWEDGES' is disabled, don't
draw any edges */ | |
3246 ················ | |
3247 /* only draw selected edges otherwise there is no way of telling
if a face is selected */ | |
3248 draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act); | |
3249 ················ | |
3250 } | |
3251 else { | |
3252 if (me->drawflag & ME_DRAWSEAMS) { | |
3253 UI_ThemeColor(TH_EDGE_SEAM); | |
3254 glLineWidth(2); | |
3255 | |
3256 draw_dm_edges_seams(em, cageDM); | |
3257 | |
3258 glColor3ub(0, 0, 0); | |
3259 glLineWidth(1); | |
3260 } | |
3261 ················ | |
3262 if (me->drawflag & ME_DRAWSHARP) { | |
3263 UI_ThemeColor(TH_EDGE_SHARP); | |
3264 glLineWidth(2); | |
3265 | |
3266 draw_dm_edges_sharp(em, cageDM); | |
3267 | |
3268 glColor3ub(0, 0, 0); | |
3269 glLineWidth(1); | |
3270 } | |
3271 | |
3272 #ifdef WITH_FREESTYLE | |
3273 if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_laye
r(&em->bm->edata, CD_FREESTYLE_EDGE)) { | |
3274 UI_ThemeColor(TH_FREESTYLE_EDGE_MARK); | |
3275 glLineWidth(2); | |
3276 ········ | |
3277 draw_dm_edges_freestyle(em, cageDM); | |
3278 ········ | |
3279 glColor3ub(0, 0, 0); | |
3280 glLineWidth(1); | |
3281 } | |
3282 #endif | |
3283 ········ | |
3284 if (me->drawflag & ME_DRAWCREASES) { | |
3285 draw_dm_creases(em, cageDM); | |
3286 } | |
3287 if (me->drawflag & ME_DRAWBWEIGHTS) { | |
3288 draw_dm_bweights(em, scene, cageDM); | |
3289 } | |
3290 | |
3291 draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act); | |
3292 } | |
3293 | |
3294 { | |
3295 draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d); | |
3296 | |
3297 if (me->drawflag & ME_DRAWNORMALS) { | |
3298 UI_ThemeColor(TH_NORMAL); | |
3299 draw_dm_face_normals(em, scene, ob, cageDM); | |
3300 } | |
3301 if (me->drawflag & ME_DRAW_VNORMALS) { | |
3302 UI_ThemeColor(TH_VNORMAL); | |
3303 draw_dm_vert_normals(em, scene, ob, cageDM); | |
3304 } | |
3305 | |
3306 if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN | | |
3307 ME_DRAWEXTRA_FACEAREA | | |
3308 ME_DRAWEXTRA_FACEANG | | |
3309 ME_DRAWEXTRA_EDGEANG)) && | |
3310 !(v3d->flag2 & V3D_RENDER_OVERRIDE)) | |
3311 { | |
3312 draw_em_measure_stats(ar, v3d, ob, em, &scene->unit); | |
3313 } | |
3314 | |
3315 if ((G.debug & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES)
&& | |
3316 !(v3d->flag2 & V3D_RENDER_OVERRIDE)) | |
3317 { | |
3318 draw_em_indices(em); | |
3319 } | |
3320 } | |
3321 | |
3322 if (dt > OB_WIRE) { | |
3323 glDepthMask(1); | |
3324 bglPolygonOffset(rv3d->dist, 0.0); | |
3325 GPU_disable_material(); | |
3326 } | |
3327 #if 0 /* currently not needed */ | |
3328 else if (use_occlude_wire) { | |
3329 bglPolygonOffset(rv3d->dist, 0.0); | |
3330 } | |
3331 #endif | |
3332 } | |
3333 | |
3334 /* Mesh drawing routines */ | |
3335 | |
3336 static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) | |
3337 { | |
3338 if ((v3d->transp == false) && /* not when we draw the transparent pass
*/ | |
3339 (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its d
istracting) - campbell */ | |
3340 { | |
3341 glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); | |
3342 glDepthMask(0); | |
3343 | |
3344 /* if transparent, we cannot draw the edges for solid select...
edges have no material info. | |
3345 * drawFacesSolid() doesn't draw the transparent faces */ | |
3346 if (ob->dtx & OB_DRAWTRANSP) { | |
3347 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
3348 dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); | |
3349 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
3350 GPU_disable_material(); | |
3351 } | |
3352 else { | |
3353 dm->drawEdges(dm, 0, 1); | |
3354 } | |
3355 | |
3356 glLineWidth(1.0); | |
3357 glDepthMask(1); | |
3358 } | |
3359 } | |
3360 | |
3361 static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
*rv3d, Base *base, | |
3362 const char dt, const unsigned char ob_wire_col[4], c
onst short dflag) | |
3363 { | |
3364 Object *ob = base->object; | |
3365 Mesh *me = ob->data; | |
3366 Material *ma = give_current_material(ob, 1); | |
3367 const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !
BKE_scene_use_new_shading_nodes(scene)); | |
3368 eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; | |
3369 int /* totvert,*/ totedge, totface; | |
3370 DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_ma
sk); | |
3371 const bool is_obact = (ob == OBACT); | |
3372 int draw_flags = (is_obact && paint_facesel_test(ob)) ? DRAW_FACE_SELECT
: 0; | |
3373 | |
3374 if (!dm) | |
3375 return; | |
3376 | |
3377 /* Check to draw dynamic paint colors (or weights from WeightVG modifier
s). | |
3378 * Note: Last "preview-active" modifier in stack will win! */ | |
3379 if (DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL) && modifiers_isPrevi
ew(ob)) | |
3380 draw_flags |= DRAW_MODIFIERS_PREVIEW; | |
3381 | |
3382 /* Unwanted combination */ | |
3383 if (draw_flags & DRAW_FACE_SELECT) { | |
3384 draw_wire = OBDRAW_WIRE_OFF; | |
3385 } | |
3386 else if (ob->dtx & OB_DRAWWIRE) { | |
3387 draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using
zoffset and depth buffer adjusment */ | |
3388 } | |
3389 ········ | |
3390 /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/ | |
3391 totedge = dm->getNumEdges(dm); | |
3392 totface = dm->getNumTessFaces(dm); | |
3393 ········ | |
3394 /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ | |
3395 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); | |
3396 | |
3397 if (dt == OB_BOUNDBOX) { | |
3398 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_W
IRE) == 0) | |
3399 draw_bounding_volume(scene, ob, ob->boundtype); | |
3400 } | |
3401 else if (hasHaloMat || (totface == 0 && totedge == 0)) { | |
3402 glPointSize(1.5); | |
3403 dm->drawVerts(dm); | |
3404 glPointSize(1.0); | |
3405 } | |
3406 else if (dt == OB_WIRE || totface == 0) { | |
3407 draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer s
tuff */ | |
3408 } | |
3409 else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || | |
3410 check_object_draw_texture(scene, v3d, dt)) | |
3411 { | |
3412 if ((v3d->flag & V3D_SELECT_OUTLINE) && | |
3413 ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && | |
3414 (base->flag & SELECT) && | |
3415 !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && | |
3416 (draw_wire == OBDRAW_WIRE_OFF)) | |
3417 { | |
3418 draw_mesh_object_outline(v3d, ob, dm); | |
3419 } | |
3420 | |
3421 if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRA
W_MODIFIERS_PREVIEW)) { | |
3422 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_
CCW); | |
3423 | |
3424 dm->drawFacesGLSL(dm, GPU_enable_material); | |
3425 // if (BKE_bproperty_object_get(ob, "Text")) | |
3426 // XXX draw_mesh_text(ob, 1); | |
3427 GPU_disable_material(); | |
3428 | |
3429 glFrontFace(GL_CCW); | |
3430 | |
3431 if (draw_flags & DRAW_FACE_SELECT) | |
3432 draw_mesh_face_select(rv3d, me, dm); | |
3433 } | |
3434 else { | |
3435 draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags)
; | |
3436 } | |
3437 | |
3438 if (!(draw_flags & DRAW_FACE_SELECT)) { | |
3439 if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { | |
3440 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
3441 glColor3ubv(ob_wire_col); | |
3442 } | |
3443 dm->drawLooseEdges(dm); | |
3444 } | |
3445 } | |
3446 } | |
3447 else if (dt == OB_SOLID) { | |
3448 if (draw_flags & DRAW_MODIFIERS_PREVIEW) { | |
3449 /* for object selection draws no shade */ | |
3450 if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { | |
3451 dm->drawFacesSolid(dm, NULL, 0, GPU_enable_mater
ial); | |
3452 } | |
3453 else { | |
3454 const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47
f}; | |
3455 | |
3456 /* draw outline */ | |
3457 if ((v3d->flag & V3D_SELECT_OUTLINE) && | |
3458 ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && | |
3459 (base->flag & SELECT) && | |
3460 (draw_wire == OBDRAW_WIRE_OFF) && | |
3461 (ob->sculpt == NULL)) | |
3462 { | |
3463 draw_mesh_object_outline(v3d, ob, dm); | |
3464 } | |
3465 | |
3466 /* materials arent compatible with vertex colors
*/ | |
3467 GPU_end_object_materials(); | |
3468 | |
3469 GPU_enable_material(0, NULL); | |
3470 ································ | |
3471 /* set default spec */ | |
3472 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); | |
3473 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spe
c); | |
3474 /* diffuse */ | |
3475 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
3476 glEnable(GL_LIGHTING); | |
3477 glEnable(GL_COLOR_MATERIAL); | |
3478 | |
3479 dm->drawMappedFaces(dm, NULL, draw_dm_override_m
aterial_color, NULL, NULL, DM_DRAW_USE_COLORS); | |
3480 glDisable(GL_COLOR_MATERIAL); | |
3481 glDisable(GL_LIGHTING); | |
3482 | |
3483 GPU_disable_material(); | |
3484 } | |
3485 } | |
3486 else { | |
3487 Paint *p; | |
3488 | |
3489 if ((v3d->flag & V3D_SELECT_OUTLINE) && | |
3490 ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && | |
3491 (base->flag & SELECT) && | |
3492 (draw_wire == OBDRAW_WIRE_OFF) && | |
3493 (ob->sculpt == NULL)) | |
3494 { | |
3495 draw_mesh_object_outline(v3d, ob, dm); | |
3496 } | |
3497 | |
3498 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TW
OSIDED) ? GL_TRUE : GL_FALSE); | |
3499 | |
3500 glEnable(GL_LIGHTING); | |
3501 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_
CCW); | |
3502 | |
3503 if (ob->sculpt && (p = BKE_paint_get_active(scene))) { | |
3504 float planes[4][4]; | |
3505 float (*fpl)[4] = NULL; | |
3506 int fast = (p->flags & PAINT_FAST_NAVIGATE) && (
rv3d->rflag & RV3D_NAVIGATING); | |
3507 | |
3508 if (ob->sculpt->partial_redraw) { | |
3509 if (ar->do_draw & RGN_DRAW_PARTIAL) { | |
3510 sculpt_get_redraw_planes(planes,
ar, rv3d, ob); | |
3511 fpl = planes; | |
3512 ob->sculpt->partial_redraw = 0; | |
3513 } | |
3514 } | |
3515 | |
3516 dm->drawFacesSolid(dm, fpl, fast, GPU_enable_mat
erial); | |
3517 } | |
3518 else | |
3519 dm->drawFacesSolid(dm, NULL, 0, GPU_enable_mater
ial); | |
3520 | |
3521 GPU_disable_material(); | |
3522 | |
3523 glFrontFace(GL_CCW); | |
3524 glDisable(GL_LIGHTING); | |
3525 | |
3526 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); | |
3527 | |
3528 if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) ==
0) { | |
3529 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
3530 glColor3ubv(ob_wire_col); | |
3531 } | |
3532 dm->drawLooseEdges(dm); | |
3533 } | |
3534 } | |
3535 } | |
3536 else if (dt == OB_PAINT) { | |
3537 draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); | |
3538 | |
3539 /* since we already draw wire as wp guide, don't draw over the t
op */ | |
3540 draw_wire = OBDRAW_WIRE_OFF; | |
3541 } | |
3542 | |
3543 if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */ | |
3544 /* when overriding with render only, don't bother */ | |
3545 (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) =
= 0)) | |
3546 { | |
3547 /* When using wireframe object draw in particle edit mode | |
3548 * the mesh gets in the way of seeing the particles, fade the wi
re color | |
3549 * with the background. */ | |
3550 | |
3551 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
3552 if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) { | |
3553 ob_wire_color_blend_theme_id(ob_wire_col, TH_BAC
K, 0.15f); | |
3554 } | |
3555 else { | |
3556 glColor3ubv(ob_wire_col); | |
3557 } | |
3558 } | |
3559 | |
3560 /* If drawing wire and drawtype is not OB_WIRE then we are | |
3561 * overlaying the wires. | |
3562 * | |
3563 * UPDATE bug #10290 - With this wire-only objects can draw | |
3564 * behind other objects depending on their order in the scene. 2
x if 0's below. undo'ing zr's commit: r4059 | |
3565 * | |
3566 * if draw wire is 1 then just drawing wire, no need for depth b
uffer stuff, | |
3567 * otherwise this wire is to overlay solid mode faces so do some
depth buffer tricks. | |
3568 */ | |
3569 if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { | |
3570 bglPolygonOffset(rv3d->dist, 1.0); | |
3571 glDepthMask(0); /* disable write in zbuffer, selected e
dge wires show better */ | |
3572 } | |
3573 ················ | |
3574 dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB
_DRAW_ALL_EDGES)); | |
3575 | |
3576 if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { | |
3577 glDepthMask(1); | |
3578 bglPolygonOffset(rv3d->dist, 0.0); | |
3579 } | |
3580 } | |
3581 ········ | |
3582 if (is_obact && paint_vertsel_test(ob)) { | |
3583 const int use_depth = (v3d->flag & V3D_ZBUF_SELECT); | |
3584 glColor3f(0.0f, 0.0f, 0.0f); | |
3585 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); | |
3586 | |
3587 if (!use_depth) glDisable(GL_DEPTH_TEST); | |
3588 else bglPolygonOffset(rv3d->dist, 1.0); | |
3589 drawSelectedVertices(dm, ob->data); | |
3590 if (!use_depth) glEnable(GL_DEPTH_TEST); | |
3591 else bglPolygonOffset(rv3d->dist, 0.0); | |
3592 ················ | |
3593 glPointSize(1.0f); | |
3594 } | |
3595 dm->release(dm); | |
3596 } | |
3597 | |
3598 /* returns 1 if nothing was drawn, for detecting to draw an object center */ | |
3599 static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
D *rv3d, Base *base, | |
3600 const char dt, const unsigned char ob_wire_col[4],
const short dflag) | |
3601 { | |
3602 Object *ob = base->object; | |
3603 Object *obedit = scene->obedit; | |
3604 Mesh *me = ob->data; | |
3605 BMEditMesh *em = me->edit_btmesh; | |
3606 int i; | |
3607 bool do_alpha_after = false, drawlinked = false, retval = false; | |
3608 | |
3609 /* If we are drawing shadows and any of the materials don't cast a shado
w, | |
3610 * then don't draw the object */ | |
3611 if (v3d->flag2 & V3D_RENDER_SHADOW) { | |
3612 for (i = 0; i < ob->totcol; ++i) { | |
3613 Material *ma = give_current_material(ob, i); | |
3614 if (ma && !(ma->mode & MA_SHADBUF)) { | |
3615 return true; | |
3616 } | |
3617 } | |
3618 } | |
3619 ········ | |
3620 if (obedit && ob != obedit && ob->data == obedit->data) { | |
3621 if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} | |
3622 else if (ob->modifiers.first || obedit->modifiers.first) {} | |
3623 else drawlinked = true; | |
3624 } | |
3625 | |
3626 /* backface culling */ | |
3627 if (v3d->flag2 & V3D_BACKFACE_CULLING) { | |
3628 glEnable(GL_CULL_FACE); | |
3629 glCullFace(GL_BACK); | |
3630 } | |
3631 | |
3632 if (ob == obedit || drawlinked) { | |
3633 DerivedMesh *finalDM, *cageDM; | |
3634 ················ | |
3635 if (obedit != ob) | |
3636 finalDM = cageDM = editbmesh_get_derived_base(ob, em); | |
3637 else | |
3638 cageDM = editbmesh_get_derived_cage_and_final(scene, ob,
em, &finalDM, | |
3639 scene->cus
tomdata_mask); | |
3640 | |
3641 if (dt > OB_WIRE) { | |
3642 const bool glsl = draw_glsl_material(scene, ob, v3d, dt)
; | |
3643 | |
3644 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, N
ULL); | |
3645 } | |
3646 | |
3647 draw_em_fancy(scene, ar, v3d, ob, em, cageDM, finalDM, dt); | |
3648 | |
3649 GPU_end_object_materials(); | |
3650 | |
3651 if (obedit != ob && finalDM) | |
3652 finalDM->release(finalDM); | |
3653 } | |
3654 else { | |
3655 /* ob->bb was set by derived mesh system, do NULL check just to
be sure */ | |
3656 if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d
, ob->obmat, ob->bb))) { | |
3657 const bool glsl = draw_glsl_material(scene, ob, v3d, dt)
; | |
3658 const bool check_alpha = check_alpha_pass(base); | |
3659 | |
3660 if (dt == OB_SOLID || glsl) { | |
3661 GPU_begin_object_materials(v3d, rv3d, scene, ob,
glsl, | |
3662 (check_alpha) ? &do_a
lpha_after : NULL); | |
3663 } | |
3664 | |
3665 draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, ob_wire_
col, dflag); | |
3666 | |
3667 GPU_end_object_materials(); | |
3668 ························ | |
3669 if (me->totvert == 0) retval = true; | |
3670 } | |
3671 } | |
3672 ········ | |
3673 if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (
v3d->flag2 & V3D_RENDER_SHADOW) == 0) { | |
3674 /* GPU_begin_object_materials checked if this is needed */ | |
3675 if (do_alpha_after) { | |
3676 if (ob->dtx & OB_DRAWXRAY) { | |
3677 ED_view3d_after_add(&v3d->afterdraw_xraytransp,
base, dflag); | |
3678 } | |
3679 else { | |
3680 ED_view3d_after_add(&v3d->afterdraw_transp, base
, dflag); | |
3681 } | |
3682 } | |
3683 else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { | |
3684 /* special case xray+transp when alpha is 1.0, without t
his the object vanishes */ | |
3685 if (v3d->xray == 0 && v3d->transp == 0) { | |
3686 ED_view3d_after_add(&v3d->afterdraw_xray, base,
dflag); | |
3687 } | |
3688 } | |
3689 } | |
3690 | |
3691 if (v3d->flag2 & V3D_BACKFACE_CULLING) | |
3692 glDisable(GL_CULL_FACE); | |
3693 ········ | |
3694 return retval; | |
3695 } | |
3696 | |
3697 /* ************** DRAW DISPLIST ****************** */ | |
3698 | |
3699 static bool draw_index_wire = true; | |
3700 static bool index3_nors_incr = true; | |
3701 | |
3702 /* returns 1 when nothing was drawn */ | |
3703 static bool drawDispListwire(ListBase *dlbase) | |
3704 { | |
3705 DispList *dl; | |
3706 int parts, nr; | |
3707 float *data; | |
3708 | |
3709 if (dlbase == NULL) return 1; | |
3710 ········ | |
3711 glEnableClientState(GL_VERTEX_ARRAY); | |
3712 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
3713 | |
3714 for (dl = dlbase->first; dl; dl = dl->next) { | |
3715 if (dl->parts == 0 || dl->nr == 0) | |
3716 continue; | |
3717 ················ | |
3718 data = dl->verts; | |
3719 | |
3720 switch (dl->type) { | |
3721 case DL_SEGM: | |
3722 | |
3723 glVertexPointer(3, GL_FLOAT, 0, data); | |
3724 | |
3725 for (parts = 0; parts < dl->parts; parts++) | |
3726 glDrawArrays(GL_LINE_STRIP, parts * dl->
nr, dl->nr); | |
3727 ································ | |
3728 break; | |
3729 case DL_POLY: | |
3730 | |
3731 glVertexPointer(3, GL_FLOAT, 0, data); | |
3732 | |
3733 for (parts = 0; parts < dl->parts; parts++) | |
3734 glDrawArrays(GL_LINE_LOOP, parts * dl->n
r, dl->nr); | |
3735 | |
3736 break; | |
3737 case DL_SURF: | |
3738 | |
3739 glVertexPointer(3, GL_FLOAT, 0, data); | |
3740 | |
3741 for (parts = 0; parts < dl->parts; parts++) { | |
3742 if (dl->flag & DL_CYCL_U) | |
3743 glDrawArrays(GL_LINE_LOOP, parts
* dl->nr, dl->nr); | |
3744 else | |
3745 glDrawArrays(GL_LINE_STRIP, part
s * dl->nr, dl->nr); | |
3746 } | |
3747 | |
3748 for (nr = 0; nr < dl->nr; nr++) { | |
3749 int ofs = 3 * dl->nr; | |
3750 | |
3751 data = (dl->verts) + 3 * nr; | |
3752 parts = dl->parts; | |
3753 | |
3754 if (dl->flag & DL_CYCL_V) glBegin(GL_LIN
E_LOOP); | |
3755 else glBegin(GL_LINE_STRIP); | |
3756 | |
3757 while (parts--) { | |
3758 glVertex3fv(data); | |
3759 data += ofs; | |
3760 } | |
3761 glEnd(); | |
3762 | |
3763 #if 0 | |
3764 /* (ton) this code crashes for me when resolv is
86 or higher... no clue */ | |
3765 glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 *
dl->nr, data + 3 * nr); | |
3766 if (dl->flag & DL_CYCL_V) | |
3767 glDrawArrays(GL_LINE_LOOP, 0, dl->parts)
; | |
3768 else | |
3769 glDrawArrays(GL_LINE_STRIP, 0, dl->parts
); | |
3770 #endif | |
3771 } | |
3772 break; | |
3773 | |
3774 case DL_INDEX3: | |
3775 if (draw_index_wire) { | |
3776 glVertexPointer(3, GL_FLOAT, 0, dl->vert
s); | |
3777 glDrawElements(GL_TRIANGLES, 3 * dl->par
ts, GL_UNSIGNED_INT, dl->index); | |
3778 } | |
3779 break; | |
3780 | |
3781 case DL_INDEX4: | |
3782 if (draw_index_wire) { | |
3783 glVertexPointer(3, GL_FLOAT, 0, dl->vert
s); | |
3784 glDrawElements(GL_QUADS, 4 * dl->parts,
GL_UNSIGNED_INT, dl->index); | |
3785 } | |
3786 break; | |
3787 } | |
3788 } | |
3789 ········ | |
3790 glDisableClientState(GL_VERTEX_ARRAY); | |
3791 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
3792 ········ | |
3793 return false; | |
3794 } | |
3795 | |
3796 static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, | |
3797 const unsigned char ob_wire_col[4], const bool use
_glsl) | |
3798 { | |
3799 DispList *dl; | |
3800 GPUVertexAttribs gattribs; | |
3801 float *data; | |
3802 float *ndata; | |
3803 ········ | |
3804 if (lb == NULL) return; | |
3805 | |
3806 glEnable(GL_LIGHTING); | |
3807 glEnableClientState(GL_VERTEX_ARRAY); | |
3808 ········ | |
3809 ········ | |
3810 if (ob->type == OB_MBALL) { /* mball always smooth shaded */ | |
3811 if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); | |
3812 else glFrontFace(GL_CCW); | |
3813 glShadeModel(GL_SMOOTH); | |
3814 } | |
3815 else { | |
3816 if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CCW); | |
3817 else glFrontFace(GL_CW); | |
3818 } | |
3819 ········ | |
3820 dl = lb->first; | |
3821 while (dl) { | |
3822 data = dl->verts; | |
3823 ndata = dl->nors; | |
3824 | |
3825 switch (dl->type) { | |
3826 case DL_SEGM: | |
3827 if (ob->type == OB_SURF) { | |
3828 int nr; | |
3829 | |
3830 glDisable(GL_LIGHTING); | |
3831 | |
3832 if ((dflag & DRAW_CONSTCOLOR) == 0) | |
3833 glColor3ubv(ob_wire_col); | |
3834 | |
3835 // glVertexPointer(3, GL_FLOAT, 0, dl->v
erts); | |
3836 // glDrawArrays(GL_LINE_STRIP, 0, dl->nr
); | |
3837 | |
3838 glBegin(GL_LINE_STRIP); | |
3839 for (nr = dl->nr; nr; nr--, data += 3) | |
3840 glVertex3fv(data); | |
3841 glEnd(); | |
3842 | |
3843 glEnable(GL_LIGHTING); | |
3844 } | |
3845 break; | |
3846 case DL_POLY: | |
3847 if (ob->type == OB_SURF) { | |
3848 int nr; | |
3849 | |
3850 glDisable(GL_LIGHTING); | |
3851 | |
3852 /* for some reason glDrawArrays crashes
here in half of the platforms (not osx) */ | |
3853 //glVertexPointer(3, GL_FLOAT, 0, dl->ve
rts); | |
3854 //glDrawArrays(GL_LINE_LOOP, 0, dl->nr); | |
3855 | |
3856 glBegin(GL_LINE_LOOP); | |
3857 for (nr = dl->nr; nr; nr--, data += 3) | |
3858 glVertex3fv(data); | |
3859 glEnd(); | |
3860 | |
3861 glEnable(GL_LIGHTING); | |
3862 } | |
3863 break; | |
3864 case DL_SURF: | |
3865 | |
3866 if (dl->index) { | |
3867 GPU_enable_material(dl->col + 1, (use_gl
sl) ? &gattribs : NULL); | |
3868 | |
3869 if (dl->rt & CU_SMOOTH) glShadeModel(GL_
SMOOTH); | |
3870 else glShadeModel(GL_FLAT); | |
3871 | |
3872 glEnableClientState(GL_NORMAL_ARRAY); | |
3873 glVertexPointer(3, GL_FLOAT, 0, dl->vert
s); | |
3874 glNormalPointer(GL_FLOAT, 0, dl->nors); | |
3875 glDrawElements(GL_QUADS, 4 * dl->totinde
x, GL_UNSIGNED_INT, dl->index); | |
3876 glDisableClientState(GL_NORMAL_ARRAY); | |
3877 } | |
3878 break; | |
3879 | |
3880 case DL_INDEX3: | |
3881 GPU_enable_material(dl->col + 1, (use_glsl) ? &g
attribs : NULL); | |
3882 | |
3883 glVertexPointer(3, GL_FLOAT, 0, dl->verts); | |
3884 | |
3885 /* for polys only one normal needed */ | |
3886 if (index3_nors_incr) { | |
3887 glEnableClientState(GL_NORMAL_ARRAY); | |
3888 glNormalPointer(GL_FLOAT, 0, dl->nors); | |
3889 } | |
3890 else | |
3891 glNormal3fv(ndata); | |
3892 | |
3893 glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_U
NSIGNED_INT, dl->index); | |
3894 | |
3895 if (index3_nors_incr) | |
3896 glDisableClientState(GL_NORMAL_ARRAY); | |
3897 | |
3898 break; | |
3899 | |
3900 case DL_INDEX4: | |
3901 GPU_enable_material(dl->col + 1, (use_glsl) ? &g
attribs : NULL); | |
3902 | |
3903 glEnableClientState(GL_NORMAL_ARRAY); | |
3904 glVertexPointer(3, GL_FLOAT, 0, dl->verts); | |
3905 glNormalPointer(GL_FLOAT, 0, dl->nors); | |
3906 glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIG
NED_INT, dl->index); | |
3907 glDisableClientState(GL_NORMAL_ARRAY); | |
3908 | |
3909 break; | |
3910 } | |
3911 dl = dl->next; | |
3912 } | |
3913 | |
3914 glDisableClientState(GL_VERTEX_ARRAY); | |
3915 glShadeModel(GL_FLAT); | |
3916 glDisable(GL_LIGHTING); | |
3917 glFrontFace(GL_CCW); | |
3918 } | |
3919 | |
3920 static void drawCurveDMWired(Object *ob) | |
3921 { | |
3922 DerivedMesh *dm = ob->derivedFinal; | |
3923 dm->drawEdges(dm, 1, 0); | |
3924 } | |
3925 | |
3926 /* return true when nothing was drawn */ | |
3927 static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Base *base, const char dt) | |
3928 { | |
3929 Object *ob = base->object; | |
3930 DerivedMesh *dm = ob->derivedFinal; | |
3931 | |
3932 if (!dm) { | |
3933 return true; | |
3934 } | |
3935 | |
3936 if (dt > OB_WIRE && dm->getNumTessFaces(dm)) { | |
3937 int glsl = draw_glsl_material(scene, ob, v3d, dt); | |
3938 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); | |
3939 | |
3940 if (!glsl) { | |
3941 glEnable(GL_LIGHTING); | |
3942 dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); | |
3943 glDisable(GL_LIGHTING); | |
3944 } | |
3945 else | |
3946 dm->drawFacesGLSL(dm, GPU_enable_material); | |
3947 | |
3948 GPU_end_object_materials(); | |
3949 } | |
3950 else { | |
3951 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_S
OLID) == 0) | |
3952 drawCurveDMWired(ob); | |
3953 } | |
3954 | |
3955 return false; | |
3956 } | |
3957 | |
3958 /** | |
3959 * Only called by #drawDispList | |
3960 * \return 1 when nothing was drawn | |
3961 */ | |
3962 static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
d, Base *base, | |
3963 const char dt, const short dflag, const unsi
gned char ob_wire_col[4]) | |
3964 { | |
3965 Object *ob = base->object; | |
3966 ListBase *lb = NULL; | |
3967 DispList *dl; | |
3968 Curve *cu; | |
3969 const short render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE); | |
3970 const short solid = (dt > OB_WIRE); | |
3971 | |
3972 if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) { | |
3973 return false; | |
3974 } | |
3975 | |
3976 switch (ob->type) { | |
3977 case OB_FONT: | |
3978 case OB_CURVE: | |
3979 cu = ob->data; | |
3980 | |
3981 lb = &ob->curve_cache->disp; | |
3982 | |
3983 if (solid) { | |
3984 dl = lb->first; | |
3985 if (dl == NULL) { | |
3986 return true; | |
3987 } | |
3988 | |
3989 if (dl->nors == NULL) BKE_displist_normals_add(l
b); | |
3990 index3_nors_incr = false; | |
3991 | |
3992 if (BKE_displist_has_faces(lb) == false) { | |
3993 if (!render_only) { | |
3994 draw_index_wire = false; | |
3995 drawDispListwire(lb); | |
3996 draw_index_wire = true; | |
3997 } | |
3998 } | |
3999 else { | |
4000 if (draw_glsl_material(scene, ob, v3d, d
t)) { | |
4001 GPU_begin_object_materials(v3d,
rv3d, scene, ob, 1, NULL); | |
4002 drawDispListsolid(lb, ob, dflag,
ob_wire_col, true); | |
4003 GPU_end_object_materials(); | |
4004 } | |
4005 else { | |
4006 GPU_begin_object_materials(v3d,
rv3d, scene, ob, 0, NULL); | |
4007 drawDispListsolid(lb, ob, dflag,
ob_wire_col, false); | |
4008 GPU_end_object_materials(); | |
4009 } | |
4010 if (cu->editnurb && cu->bevobj == NULL &
& cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) { | |
4011 cpack(0); | |
4012 draw_index_wire = false; | |
4013 drawDispListwire(lb); | |
4014 draw_index_wire = true; | |
4015 } | |
4016 } | |
4017 index3_nors_incr = true; | |
4018 } | |
4019 else { | |
4020 if (!render_only || (render_only && BKE_displist
_has_faces(lb))) { | |
4021 int retval; | |
4022 draw_index_wire = false; | |
4023 retval = drawDispListwire(lb); | |
4024 draw_index_wire = true; | |
4025 return retval; | |
4026 } | |
4027 } | |
4028 break; | |
4029 case OB_SURF: | |
4030 | |
4031 lb = &ob->curve_cache->disp; | |
4032 | |
4033 if (solid) { | |
4034 dl = lb->first; | |
4035 if (dl == NULL) { | |
4036 return true; | |
4037 } | |
4038 | |
4039 if (dl->nors == NULL) BKE_displist_normals_add(l
b); | |
4040 | |
4041 if (draw_glsl_material(scene, ob, v3d, dt)) { | |
4042 GPU_begin_object_materials(v3d, rv3d, sc
ene, ob, 1, NULL); | |
4043 drawDispListsolid(lb, ob, dflag, ob_wire
_col, true); | |
4044 GPU_end_object_materials(); | |
4045 } | |
4046 else { | |
4047 GPU_begin_object_materials(v3d, rv3d, sc
ene, ob, 0, NULL); | |
4048 drawDispListsolid(lb, ob, dflag, ob_wire
_col, false); | |
4049 GPU_end_object_materials(); | |
4050 } | |
4051 } | |
4052 else { | |
4053 return drawDispListwire(lb); | |
4054 } | |
4055 break; | |
4056 case OB_MBALL: | |
4057 | |
4058 if (BKE_mball_is_basis(ob)) { | |
4059 lb = ob->curve_cache ? &ob->curve_cache->disp :
NULL; | |
4060 if (ELEM(lb, lb->first, NULL)) { | |
4061 BKE_displist_make_mball(scene, ob); | |
4062 lb = &ob->curve_cache->disp; | |
4063 } | |
4064 if (lb->first == NULL) { | |
4065 return true; | |
4066 } | |
4067 | |
4068 if (solid) { | |
4069 | |
4070 if (draw_glsl_material(scene, ob, v3d, d
t)) { | |
4071 GPU_begin_object_materials(v3d,
rv3d, scene, ob, 1, NULL); | |
4072 drawDispListsolid(lb, ob, dflag,
ob_wire_col, true); | |
4073 GPU_end_object_materials(); | |
4074 } | |
4075 else { | |
4076 GPU_begin_object_materials(v3d,
rv3d, scene, ob, 0, NULL); | |
4077 drawDispListsolid(lb, ob, dflag,
ob_wire_col, false); | |
4078 GPU_end_object_materials(); | |
4079 } | |
4080 } | |
4081 else { | |
4082 /* MetaBalls use DL_INDEX4 type of DispL
ist */ | |
4083 return drawDispListwire(lb); | |
4084 } | |
4085 } | |
4086 break; | |
4087 } | |
4088 | |
4089 return FALSE; | |
4090 } | |
4091 static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
se, | |
4092 const char dt, const short dflag, const unsigned char o
b_wire_col[4]) | |
4093 { | |
4094 bool retval; | |
4095 | |
4096 /* backface culling */ | |
4097 if (v3d->flag2 & V3D_BACKFACE_CULLING) { | |
4098 /* not all displists use same in/out normal direction convention
*/ | |
4099 glEnable(GL_CULL_FACE); | |
4100 glCullFace(GL_BACK); | |
4101 } | |
4102 | |
4103 retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_w
ire_col); | |
4104 | |
4105 if (v3d->flag2 & V3D_BACKFACE_CULLING) { | |
4106 glDisable(GL_CULL_FACE); | |
4107 } | |
4108 | |
4109 return retval; | |
4110 } | |
4111 | |
4112 /* *********** drawing for particles ************* */ | |
4113 static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int selec
t) | |
4114 { | |
4115 /* draw created data arrays */ | |
4116 switch (draw_as) { | |
4117 case PART_DRAW_AXIS: | |
4118 case PART_DRAW_CROSS: | |
4119 glDrawArrays(GL_LINES, 0, 6 * totpoint); | |
4120 break; | |
4121 case PART_DRAW_LINE: | |
4122 glDrawArrays(GL_LINES, 0, 2 * totpoint); | |
4123 break; | |
4124 case PART_DRAW_BB: | |
4125 if (ob_dt <= OB_WIRE || select) | |
4126 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
4127 else | |
4128 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
4129 | |
4130 glDrawArrays(GL_QUADS, 0, 4 * totpoint); | |
4131 break; | |
4132 default: | |
4133 glDrawArrays(GL_POINTS, 0, totpoint); | |
4134 break; | |
4135 } | |
4136 } | |
4137 static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
size, | |
4138 float imat[4][4], const float draw_line[2], ParticleBi
llboardData *bb, ParticleDrawData *pdd) | |
4139 { | |
4140 float vec[3], vec2[3]; | |
4141 float *vd = NULL; | |
4142 float *cd = NULL; | |
4143 float ma_col[3] = {0.0f, 0.0f, 0.0f}; | |
4144 | |
4145 /* null only for PART_DRAW_CIRC */ | |
4146 if (pdd) { | |
4147 vd = pdd->vd; | |
4148 cd = pdd->cd; | |
4149 | |
4150 if (pdd->ma_col) { | |
4151 copy_v3_v3(ma_col, pdd->ma_col); | |
4152 } | |
4153 } | |
4154 | |
4155 switch (draw_as) { | |
4156 case PART_DRAW_DOT: | |
4157 { | |
4158 if (vd) { | |
4159 copy_v3_v3(vd, state->co); pdd->vd += 3; | |
4160 } | |
4161 if (cd) { | |
4162 copy_v3_v3(cd, pdd->ma_col); | |
4163 pdd->cd += 3; | |
4164 } | |
4165 break; | |
4166 } | |
4167 case PART_DRAW_CROSS: | |
4168 case PART_DRAW_AXIS: | |
4169 { | |
4170 vec[0] = 2.0f * pixsize; | |
4171 vec[1] = vec[2] = 0.0; | |
4172 mul_qt_v3(state->rot, vec); | |
4173 if (draw_as == PART_DRAW_AXIS) { | |
4174 if (cd) { | |
4175 cd[1] = cd[2] = cd[4] = cd[5] = 0.0; | |
4176 cd[0] = cd[3] = 1.0; | |
4177 cd[6] = cd[8] = cd[9] = cd[11] = 0.0; | |
4178 cd[7] = cd[10] = 1.0; | |
4179 cd[13] = cd[12] = cd[15] = cd[16] = 0.0; | |
4180 cd[14] = cd[17] = 1.0; | |
4181 pdd->cd += 18; | |
4182 } | |
4183 | |
4184 copy_v3_v3(vec2, state->co); | |
4185 } | |
4186 else { | |
4187 if (cd) { | |
4188 cd[0] = cd[3] = cd[6] = cd[9] = cd[12] =
cd[15] = ma_col[0]; | |
4189 cd[1] = cd[4] = cd[7] = cd[10] = cd[13]
= cd[16] = ma_col[1]; | |
4190 cd[2] = cd[5] = cd[8] = cd[11] = cd[14]
= cd[17] = ma_col[2]; | |
4191 pdd->cd += 18; | |
4192 } | |
4193 sub_v3_v3v3(vec2, state->co, vec); | |
4194 } | |
4195 | |
4196 add_v3_v3(vec, state->co); | |
4197 copy_v3_v3(pdd->vd, vec); pdd->vd += 3; | |
4198 copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; | |
4199 | |
4200 vec[1] = 2.0f * pixsize; | |
4201 vec[0] = vec[2] = 0.0; | |
4202 mul_qt_v3(state->rot, vec); | |
4203 if (draw_as == PART_DRAW_AXIS) { | |
4204 copy_v3_v3(vec2, state->co); | |
4205 } | |
4206 else { | |
4207 sub_v3_v3v3(vec2, state->co, vec); | |
4208 } | |
4209 | |
4210 add_v3_v3(vec, state->co); | |
4211 copy_v3_v3(pdd->vd, vec); pdd->vd += 3; | |
4212 copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; | |
4213 | |
4214 vec[2] = 2.0f * pixsize; | |
4215 vec[0] = vec[1] = 0.0; | |
4216 mul_qt_v3(state->rot, vec); | |
4217 if (draw_as == PART_DRAW_AXIS) { | |
4218 copy_v3_v3(vec2, state->co); | |
4219 } | |
4220 else { | |
4221 sub_v3_v3v3(vec2, state->co, vec); | |
4222 } | |
4223 | |
4224 add_v3_v3(vec, state->co); | |
4225 | |
4226 copy_v3_v3(pdd->vd, vec); pdd->vd += 3; | |
4227 copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; | |
4228 break; | |
4229 } | |
4230 case PART_DRAW_LINE: | |
4231 { | |
4232 copy_v3_v3(vec, state->vel); | |
4233 normalize_v3(vec); | |
4234 if (draw & PART_DRAW_VEL_LENGTH) | |
4235 mul_v3_fl(vec, len_v3(state->vel)); | |
4236 madd_v3_v3v3fl(pdd->vd, state->co, vec, -draw_line[0]);
pdd->vd += 3; | |
4237 madd_v3_v3v3fl(pdd->vd, state->co, vec, draw_line[1]);
pdd->vd += 3; | |
4238 if (cd) { | |
4239 cd[0] = cd[3] = ma_col[0]; | |
4240 cd[1] = cd[4] = ma_col[1]; | |
4241 cd[2] = cd[5] = ma_col[2]; | |
4242 pdd->cd += 6; | |
4243 } | |
4244 break; | |
4245 } | |
4246 case PART_DRAW_CIRC: | |
4247 { | |
4248 drawcircball(GL_LINE_LOOP, state->co, pixsize, imat); | |
4249 break; | |
4250 } | |
4251 case PART_DRAW_BB: | |
4252 { | |
4253 float xvec[3], yvec[3], zvec[3], bb_center[3]; | |
4254 if (cd) { | |
4255 cd[0] = cd[3] = cd[6] = cd[9] = ma_col[0]; | |
4256 cd[1] = cd[4] = cd[7] = cd[10] = ma_col[1]; | |
4257 cd[2] = cd[5] = cd[8] = cd[11] = ma_col[2]; | |
4258 pdd->cd += 12; | |
4259 } | |
4260 | |
4261 | |
4262 copy_v3_v3(bb->vec, state->co); | |
4263 copy_v3_v3(bb->vel, state->vel); | |
4264 | |
4265 psys_make_billboard(bb, xvec, yvec, zvec, bb_center); | |
4266 ························ | |
4267 add_v3_v3v3(pdd->vd, bb_center, xvec); | |
4268 add_v3_v3(pdd->vd, yvec); pdd->vd += 3; | |
4269 | |
4270 sub_v3_v3v3(pdd->vd, bb_center, xvec); | |
4271 add_v3_v3(pdd->vd, yvec); pdd->vd += 3; | |
4272 | |
4273 sub_v3_v3v3(pdd->vd, bb_center, xvec); | |
4274 sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; | |
4275 | |
4276 add_v3_v3v3(pdd->vd, bb_center, xvec); | |
4277 sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; | |
4278 | |
4279 copy_v3_v3(pdd->nd, zvec); pdd->nd += 3; | |
4280 copy_v3_v3(pdd->nd, zvec); pdd->nd += 3; | |
4281 copy_v3_v3(pdd->nd, zvec); pdd->nd += 3; | |
4282 copy_v3_v3(pdd->nd, zvec); pdd->nd += 3; | |
4283 break; | |
4284 } | |
4285 } | |
4286 } | |
4287 static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d, | |
4288 ParticleKey *state, int draw_as, | |
4289 float imat[4][4], ParticleBillboardData *bb, Part
icleDrawData *pdd, | |
4290 const float ct, const float pa_size, const float
r_tilt, const float pixsize_scale) | |
4291 { | |
4292 ParticleSettings *part = psys->part; | |
4293 float pixsize; | |
4294 | |
4295 if (psys->parent) | |
4296 mul_m4_v3(psys->parent->obmat, state->co); | |
4297 | |
4298 /* create actiual particle data */ | |
4299 if (draw_as == PART_DRAW_BB) { | |
4300 bb->offset[0] = part->bb_offset[0]; | |
4301 bb->offset[1] = part->bb_offset[1]; | |
4302 bb->size[0] = part->bb_size[0] * pa_size; | |
4303 if (part->bb_align == PART_BB_VEL) { | |
4304 float pa_vel = len_v3(state->vel); | |
4305 float head = part->bb_vel_head * pa_vel; | |
4306 float tail = part->bb_vel_tail * pa_vel; | |
4307 bb->size[1] = part->bb_size[1] * pa_size + head + tail; | |
4308 /* use offset to adjust the particle center. this is rel
ative to size, so need to divide! */ | |
4309 if (bb->size[1] > 0.0f) | |
4310 bb->offset[1] += (head - tail) / bb->size[1]; | |
4311 } | |
4312 else { | |
4313 bb->size[1] = part->bb_size[1] * pa_size; | |
4314 } | |
4315 bb->tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); | |
4316 bb->time = ct; | |
4317 } | |
4318 | |
4319 pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale; | |
4320 | |
4321 draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line
, bb, pdd); | |
4322 } | |
4323 /* unified drawing of all new particle systems draw types except dupli ob & grou
p */ | |
4324 /* mostly tries to use vertex arrays for speed
*/ | |
4325 | |
4326 /* 1. check that everything is ok & updated */ | |
4327 /* 2. start initializing things */ | |
4328 /* 3. initialize according to draw type */ | |
4329 /* 4. allocate drawing data arrays */ | |
4330 /* 5. start filling the arrays */ | |
4331 /* 6. draw the arrays */ | |
4332 /* 7. clean up */ | |
4333 static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
3d, | |
4334 Base *base, ParticleSystem *psys, int ob_dt
) | |
4335 { | |
4336 Object *ob = base->object; | |
4337 ParticleEditSettings *pset = PE_settings(scene); | |
4338 ParticleSettings *part = psys->part; | |
4339 ParticleData *pars = psys->particles; | |
4340 ParticleData *pa; | |
4341 ParticleKey state, *states = NULL; | |
4342 ParticleBillboardData bb; | |
4343 ParticleSimulationData sim = {NULL}; | |
4344 ParticleDrawData *pdd = psys->pdd; | |
4345 Material *ma; | |
4346 float vel[3], imat[4][4]; | |
4347 float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length; | |
4348 float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; | |
4349 float cfra; | |
4350 float ma_col[3] = {0.0f, 0.0f, 0.0f}; | |
4351 int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0; | |
4352 int select = ob->flag & SELECT, create_cdata = 0, need_v = 0; | |
4353 GLint polygonmode[2]; | |
4354 char numstr[32]; | |
4355 unsigned char tcol[4] = {0, 0, 0, 255}; | |
4356 | |
4357 /* 1. */ | |
4358 if (part == NULL || !psys_check_enabled(ob, psys)) | |
4359 return; | |
4360 | |
4361 if (pars == NULL) return; | |
4362 | |
4363 /* don't draw normal paths in edit mode */ | |
4364 if (psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART) == 0) | |
4365 return; | |
4366 | |
4367 if (part->draw_as == PART_DRAW_REND) | |
4368 draw_as = part->ren_as; | |
4369 else | |
4370 draw_as = part->draw_as; | |
4371 | |
4372 if (draw_as == PART_DRAW_NOT) | |
4373 return; | |
4374 | |
4375 /* 2. */ | |
4376 sim.scene = scene; | |
4377 sim.ob = ob; | |
4378 sim.psys = psys; | |
4379 sim.psmd = psys_get_modifier(ob, psys); | |
4380 | |
4381 if (part->phystype == PART_PHYS_KEYED) { | |
4382 if (psys->flag & PSYS_KEYED) { | |
4383 psys_count_keyed_targets(&sim); | |
4384 if (psys->totkeyed == 0) | |
4385 return; | |
4386 } | |
4387 } | |
4388 | |
4389 if (select) { | |
4390 select = 0; | |
4391 if (psys_get_current(ob) == psys) | |
4392 select = 1; | |
4393 } | |
4394 | |
4395 psys->flag |= PSYS_DRAWING; | |
4396 | |
4397 if (part->type == PART_HAIR && !psys->childcache) | |
4398 totchild = 0; | |
4399 else | |
4400 totchild = psys->totchild * part->disp / 100; | |
4401 | |
4402 ma = give_current_material(ob, part->omat); | |
4403 | |
4404 if (v3d->zbuf) glDepthMask(1); | |
4405 | |
4406 if ((ma) && (part->draw_col == PART_DRAW_COL_MAT)) { | |
4407 rgb_float_to_uchar(tcol, &(ma->r)); | |
4408 copy_v3_v3(ma_col, &ma->r); | |
4409 } | |
4410 | |
4411 glColor3ubv(tcol); | |
4412 | |
4413 timestep = psys_get_timestep(&sim); | |
4414 | |
4415 if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) { | |
4416 float mat[4][4]; | |
4417 mul_m4_m4m4(mat, ob->obmat, psys->imat); | |
4418 glMultMatrixf(mat); | |
4419 } | |
4420 | |
4421 /* needed for text display */ | |
4422 invert_m4_m4(ob->imat, ob->obmat); | |
4423 | |
4424 totpart = psys->totpart; | |
4425 | |
4426 cfra = BKE_scene_frame_get(scene); | |
4427 | |
4428 if (draw_as == PART_DRAW_PATH && psys->pathcache == NULL && psys->childc
ache == NULL) | |
4429 draw_as = PART_DRAW_DOT; | |
4430 | |
4431 /* 3. */ | |
4432 switch (draw_as) { | |
4433 case PART_DRAW_DOT: | |
4434 if (part->draw_size) | |
4435 glPointSize(part->draw_size); | |
4436 else | |
4437 glPointSize(2.0); /* default dot size */ | |
4438 break; | |
4439 case PART_DRAW_CIRC: | |
4440 /* calculate view aligned matrix: */ | |
4441 copy_m4_m4(imat, rv3d->viewinv); | |
4442 normalize_v3(imat[0]); | |
4443 normalize_v3(imat[1]); | |
4444 /* fall-through */ | |
4445 case PART_DRAW_CROSS: | |
4446 case PART_DRAW_AXIS: | |
4447 /* lets calculate the scale: */ | |
4448 ························ | |
4449 if (part->draw_size == 0.0) | |
4450 pixsize_scale = 2.0f; | |
4451 else | |
4452 pixsize_scale = part->draw_size; | |
4453 | |
4454 if (draw_as == PART_DRAW_AXIS) | |
4455 create_cdata = 1; | |
4456 break; | |
4457 case PART_DRAW_OB: | |
4458 if (part->dup_ob == NULL) | |
4459 draw_as = PART_DRAW_DOT; | |
4460 else | |
4461 draw_as = 0; | |
4462 break; | |
4463 case PART_DRAW_GR: | |
4464 if (part->dup_group == NULL) | |
4465 draw_as = PART_DRAW_DOT; | |
4466 else | |
4467 draw_as = 0; | |
4468 break; | |
4469 case PART_DRAW_BB: | |
4470 if (v3d->camera == NULL && part->bb_ob == NULL) { | |
4471 printf("Billboards need an active camera or a ta
rget object!\n"); | |
4472 | |
4473 draw_as = part->draw_as = PART_DRAW_DOT; | |
4474 | |
4475 if (part->draw_size) | |
4476 glPointSize(part->draw_size); | |
4477 else | |
4478 glPointSize(2.0); /* default dot size *
/ | |
4479 } | |
4480 else if (part->bb_ob) | |
4481 bb.ob = part->bb_ob; | |
4482 else | |
4483 bb.ob = v3d->camera; | |
4484 | |
4485 bb.align = part->bb_align; | |
4486 bb.anim = part->bb_anim; | |
4487 bb.lock = part->draw & PART_DRAW_BB_LOCK; | |
4488 break; | |
4489 case PART_DRAW_PATH: | |
4490 break; | |
4491 case PART_DRAW_LINE: | |
4492 need_v = 1; | |
4493 break; | |
4494 } | |
4495 if (part->draw & PART_DRAW_SIZE && part->draw_as != PART_DRAW_CIRC) { | |
4496 copy_m4_m4(imat, rv3d->viewinv); | |
4497 normalize_v3(imat[0]); | |
4498 normalize_v3(imat[1]); | |
4499 } | |
4500 | |
4501 if (ELEM3(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) && | |
4502 (part->draw_col > PART_DRAW_COL_MAT)) | |
4503 { | |
4504 create_cdata = 1; | |
4505 } | |
4506 | |
4507 if (!create_cdata && pdd && pdd->cdata) { | |
4508 MEM_freeN(pdd->cdata); | |
4509 pdd->cdata = pdd->cd = NULL; | |
4510 } | |
4511 | |
4512 /* 4. */ | |
4513 if (draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC) == 0) { | |
4514 int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); | |
4515 int create_ndata = 0; | |
4516 | |
4517 if (!pdd) | |
4518 pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData),
"ParticlDrawData"); | |
4519 | |
4520 if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) { | |
4521 tot_vec_size *= part->trail_count; | |
4522 psys_make_temp_pointcache(ob, psys); | |
4523 } | |
4524 | |
4525 switch (draw_as) { | |
4526 case PART_DRAW_AXIS: | |
4527 case PART_DRAW_CROSS: | |
4528 tot_vec_size *= 6; | |
4529 if (draw_as != PART_DRAW_CROSS) | |
4530 create_cdata = 1; | |
4531 break; | |
4532 case PART_DRAW_LINE: | |
4533 tot_vec_size *= 2; | |
4534 break; | |
4535 case PART_DRAW_BB: | |
4536 tot_vec_size *= 4; | |
4537 create_ndata = 1; | |
4538 break; | |
4539 } | |
4540 | |
4541 if (pdd->tot_vec_size != tot_vec_size) | |
4542 psys_free_pdd(psys); | |
4543 | |
4544 if (!pdd->vdata) | |
4545 pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata")
; | |
4546 if (create_cdata && !pdd->cdata) | |
4547 pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata")
; | |
4548 if (create_ndata && !pdd->ndata) | |
4549 pdd->ndata = MEM_callocN(tot_vec_size, "particle_ndata")
; | |
4550 | |
4551 if (part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { | |
4552 if (!pdd->vedata) | |
4553 pdd->vedata = MEM_callocN(2 * (totpart + totchil
d) * 3 * sizeof(float), "particle_vedata"); | |
4554 | |
4555 need_v = 1; | |
4556 } | |
4557 else if (pdd->vedata) { | |
4558 /* velocity data not needed, so free it */ | |
4559 MEM_freeN(pdd->vedata); | |
4560 pdd->vedata = NULL; | |
4561 } | |
4562 | |
4563 pdd->vd = pdd->vdata; | |
4564 pdd->ved = pdd->vedata; | |
4565 pdd->cd = pdd->cdata; | |
4566 pdd->nd = pdd->ndata; | |
4567 pdd->tot_vec_size = tot_vec_size; | |
4568 } | |
4569 else if (psys->pdd) { | |
4570 psys_free_pdd(psys); | |
4571 MEM_freeN(psys->pdd); | |
4572 pdd = psys->pdd = NULL; | |
4573 } | |
4574 | |
4575 if (pdd) { | |
4576 pdd->ma_col = ma_col; | |
4577 } | |
4578 | |
4579 psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | |
4580 | |
4581 /* circles don't use drawdata, so have to add a special case here */ | |
4582 if ((pdd || draw_as == PART_DRAW_CIRC) && draw_as != PART_DRAW_PATH) { | |
4583 /* 5. */ | |
4584 if (pdd && (pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && | |
4585 (pdd->vedata || part->draw & (PART_DRAW_SIZE | PART_DRAW_NUM
| PART_DRAW_HEALTH)) == 0) | |
4586 { | |
4587 totpoint = pdd->totpoint; /* draw data is up to date */ | |
4588 } | |
4589 else { | |
4590 for (a = 0, pa = pars; a < totpart + totchild; a++, pa++
) { | |
4591 /* setup per particle individual stuff */ | |
4592 if (a < totpart) { | |
4593 if (totchild && (part->draw & PART_DRAW_
PARENT) == 0) continue; | |
4594 if (pa->flag & PARS_NO_DISP || pa->flag
& PARS_UNEXIST) continue; | |
4595 | |
4596 pa_time = (cfra - pa->time) / pa->lifeti
me; | |
4597 pa_birthtime = pa->time; | |
4598 pa_dietime = pa->dietime; | |
4599 pa_size = pa->size; | |
4600 if (part->phystype == PART_PHYS_BOIDS) | |
4601 pa_health = pa->boid->data.healt
h; | |
4602 else | |
4603 pa_health = -1.0; | |
4604 | |
4605 r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.
5f); | |
4606 r_length = PSYS_FRAND(a + 22); | |
4607 | |
4608 if (part->draw_col > PART_DRAW_COL_MAT)
{ | |
4609 switch (part->draw_col) { | |
4610 case PART_DRAW_COL_VEL: | |
4611 intensity = len_
v3(pa->state.vel) / part->color_vec_max; | |
4612 break; | |
4613 case PART_DRAW_COL_ACC: | |
4614 intensity = len_
v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time
) * part->color_vec_max); | |
4615 break; | |
4616 default: | |
4617 intensity = 1.0f
; /* should never happen */ | |
4618 BLI_assert(0); | |
4619 break; | |
4620 } | |
4621 CLAMP(intensity, 0.f, 1.f); | |
4622 weight_to_rgb(ma_col, intensity)
; | |
4623 } | |
4624 } | |
4625 else { | |
4626 ChildParticle *cpa = &psys->child[a - to
tpart]; | |
4627 | |
4628 pa_time = psys_get_child_time(psys, cpa,
cfra, &pa_birthtime, &pa_dietime); | |
4629 pa_size = psys_get_child_size(psys, cpa,
cfra, NULL); | |
4630 | |
4631 pa_health = -1.0; | |
4632 | |
4633 r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.
5f); | |
4634 r_length = PSYS_FRAND(a + 22); | |
4635 } | |
4636 | |
4637 drawn = 0; | |
4638 if (part->draw_as == PART_DRAW_REND && part->tra
il_count > 1) { | |
4639 float length = part->path_end * (1.0f -
part->randlength * r_length); | |
4640 int trail_count = part->trail_count * (1
.0f - part->randlength * r_length); | |
4641 float ct = ((part->draw & PART_ABS_PATH_
TIME) ? cfra : pa_time) - length; | |
4642 float dt = length / (trail_count ? (floa
t)trail_count : 1.0f); | |
4643 int i = 0; | |
4644 | |
4645 ct += dt; | |
4646 for (i = 0; i < trail_count; i++, ct +=
dt) { | |
4647 | |
4648 if (part->draw & PART_ABS_PATH_T
IME) { | |
4649 if (ct < pa_birthtime ||
ct > pa_dietime) | |
4650 continue; | |
4651 } | |
4652 else if (ct < 0.0f || ct > 1.0f) | |
4653 continue; | |
4654 | |
4655 state.time = (part->draw & PART_
ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); | |
4656 psys_get_particle_on_path(&sim,
a, &state, need_v); | |
4657 | |
4658 draw_particle_data(psys, rv3d, | |
4659 &state, draw_
as, imat, &bb, psys->pdd, | |
4660 ct, pa_size,
r_tilt, pixsize_scale); | |
4661 | |
4662 totpoint++; | |
4663 drawn = 1; | |
4664 } | |
4665 } | |
4666 else { | |
4667 state.time = cfra; | |
4668 if (psys_get_particle_state(&sim, a, &st
ate, 0)) { | |
4669 | |
4670 draw_particle_data(psys, rv3d, | |
4671 &state, draw_
as, imat, &bb, psys->pdd, | |
4672 pa_time, pa_s
ize, r_tilt, pixsize_scale); | |
4673 | |
4674 totpoint++; | |
4675 drawn = 1; | |
4676 } | |
4677 } | |
4678 | |
4679 if (drawn) { | |
4680 /* additional things to draw for each pa
rticle */ | |
4681 /* (velocity, size and number)
*/ | |
4682 if ((part->draw & PART_DRAW_VEL) && pdd
&& pdd->vedata) { | |
4683 copy_v3_v3(pdd->ved, state.co); | |
4684 pdd->ved += 3; | |
4685 mul_v3_v3fl(vel, state.vel, time
step); | |
4686 add_v3_v3v3(pdd->ved, state.co,
vel); | |
4687 pdd->ved += 3; | |
4688 | |
4689 totve++; | |
4690 } | |
4691 | |
4692 if (part->draw & PART_DRAW_SIZE) { | |
4693 setlinestyle(3); | |
4694 drawcircball(GL_LINE_LOOP, state
.co, pa_size, imat); | |
4695 setlinestyle(0); | |
4696 } | |
4697 | |
4698 | |
4699 if ((part->draw & PART_DRAW_NUM || part-
>draw & PART_DRAW_HEALTH) && | |
4700 (v3d->flag2 & V3D_RENDER_OVERRIDE) =
= 0) | |
4701 { | |
4702 float vec_txt[3]; | |
4703 char *val_pos = numstr; | |
4704 numstr[0] = '\0'; | |
4705 | |
4706 if (part->draw & PART_DRAW_NUM)
{ | |
4707 if (a < totpart && (part
->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { | |
4708 BLI_snprintf(val
_pos, sizeof(numstr), "%d:%.2f", a, pa_health); | |
4709 } | |
4710 else { | |
4711 BLI_snprintf(val
_pos, sizeof(numstr), "%d", a); | |
4712 } | |
4713 } | |
4714 else { | |
4715 if (a < totpart && (part
->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { | |
4716 BLI_snprintf(val
_pos, sizeof(numstr), "%.2f", pa_health); | |
4717 } | |
4718 } | |
4719 | |
4720 /* in path drawing state.co is t
he end point */ | |
4721 /* use worldspace beause object
matrix is already applied */ | |
4722 mul_v3_m4v3(vec_txt, ob->imat, s
tate.co); | |
4723 view3d_cached_text_draw_add(vec_
txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); | |
4724 } | |
4725 } | |
4726 } | |
4727 } | |
4728 } | |
4729 /* 6. */ | |
4730 | |
4731 glGetIntegerv(GL_POLYGON_MODE, polygonmode); | |
4732 glEnableClientState(GL_VERTEX_ARRAY); | |
4733 | |
4734 if (draw_as == PART_DRAW_PATH) { | |
4735 ParticleCacheKey **cache, *path; | |
4736 float /* *cd2=NULL, */ /* UNUSED */ *cdata2 = NULL; | |
4737 | |
4738 /* setup gl flags */ | |
4739 if (1) { //ob_dt > OB_WIRE) { | |
4740 glEnableClientState(GL_NORMAL_ARRAY); | |
4741 | |
4742 if (part->draw_col == PART_DRAW_COL_MAT) | |
4743 glEnableClientState(GL_COLOR_ARRAY); | |
4744 | |
4745 glEnable(GL_LIGHTING); | |
4746 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
4747 glEnable(GL_COLOR_MATERIAL); | |
4748 } | |
4749 #if 0 | |
4750 else { | |
4751 glDisableClientState(GL_NORMAL_ARRAY); | |
4752 | |
4753 glDisable(GL_COLOR_MATERIAL); | |
4754 glDisable(GL_LIGHTING); | |
4755 UI_ThemeColor(TH_WIRE); | |
4756 } | |
4757 #endif | |
4758 | |
4759 if (totchild && (part->draw & PART_DRAW_PARENT) == 0) | |
4760 totpart = 0; | |
4761 else if (psys->pathcache == NULL) | |
4762 totpart = 0; | |
4763 | |
4764 /* draw actual/parent particles */ | |
4765 cache = psys->pathcache; | |
4766 for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { | |
4767 path = cache[a]; | |
4768 if (path->steps > 0) { | |
4769 glVertexPointer(3, GL_FLOAT, sizeof(ParticleCach
eKey), path->co); | |
4770 | |
4771 if (1) { //ob_dt > OB_WIRE) { | |
4772 glNormalPointer(GL_FLOAT, sizeof(Particl
eCacheKey), path->vel); | |
4773 if (part->draw_col == PART_DRAW_COL_MAT) | |
4774 glColorPointer(3, GL_FLOAT, size
of(ParticleCacheKey), path->col); | |
4775 } | |
4776 | |
4777 glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); | |
4778 } | |
4779 } | |
4780 ················ | |
4781 /* draw child particles */ | |
4782 cache = psys->childcache; | |
4783 for (a = 0; a < totchild; a++) { | |
4784 path = cache[a]; | |
4785 glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), p
ath->co); | |
4786 | |
4787 if (1) { //ob_dt > OB_WIRE) { | |
4788 glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKe
y), path->vel); | |
4789 if (part->draw_col == PART_DRAW_COL_MAT) | |
4790 glColorPointer(3, GL_FLOAT, sizeof(Parti
cleCacheKey), path->col); | |
4791 } | |
4792 | |
4793 glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); | |
4794 } | |
4795 | |
4796 | |
4797 /* restore & clean up */ | |
4798 if (1) { //ob_dt > OB_WIRE) { | |
4799 if (part->draw_col == PART_DRAW_COL_MAT) | |
4800 glDisable(GL_COLOR_ARRAY); | |
4801 glDisable(GL_COLOR_MATERIAL); | |
4802 } | |
4803 | |
4804 if (cdata2) | |
4805 MEM_freeN(cdata2); | |
4806 /* cd2 = */ /* UNUSED */ cdata2 = NULL; | |
4807 | |
4808 glLineWidth(1.0f); | |
4809 | |
4810 if ((part->draw & PART_DRAW_NUM) && (v3d->flag2 & V3D_RENDER_OVE
RRIDE) == 0) { | |
4811 cache = psys->pathcache; | |
4812 | |
4813 for (a = 0, pa = psys->particles; a < totpart; a++, pa++
) { | |
4814 float vec_txt[3]; | |
4815 BLI_snprintf(numstr, sizeof(numstr), "%i", a); | |
4816 /* use worldspace beause object matrix is alread
y applied */ | |
4817 mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co); | |
4818 view3d_cached_text_draw_add(vec_txt, numstr, 10,
V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); | |
4819 } | |
4820 } | |
4821 } | |
4822 else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) { | |
4823 glDisableClientState(GL_COLOR_ARRAY); | |
4824 | |
4825 /* enable point data array */ | |
4826 if (pdd->vdata) { | |
4827 glEnableClientState(GL_VERTEX_ARRAY); | |
4828 glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); | |
4829 } | |
4830 else | |
4831 glDisableClientState(GL_VERTEX_ARRAY); | |
4832 | |
4833 if (select) { | |
4834 UI_ThemeColor(TH_ACTIVE); | |
4835 ························ | |
4836 if (part->draw_size) | |
4837 glPointSize(part->draw_size + 2); | |
4838 else | |
4839 glPointSize(4.0); | |
4840 | |
4841 glLineWidth(3.0); | |
4842 | |
4843 draw_particle_arrays(draw_as, totpoint, ob_dt, 1); | |
4844 } | |
4845 | |
4846 /* restore from select */ | |
4847 glColor3fv(ma_col); | |
4848 glPointSize(part->draw_size ? part->draw_size : 2.0); | |
4849 glLineWidth(1.0); | |
4850 | |
4851 /* enable other data arrays */ | |
4852 | |
4853 /* billboards are drawn this way */ | |
4854 if (pdd->ndata && ob_dt > OB_WIRE) { | |
4855 glEnableClientState(GL_NORMAL_ARRAY); | |
4856 glNormalPointer(GL_FLOAT, 0, pdd->ndata); | |
4857 glEnable(GL_LIGHTING); | |
4858 } | |
4859 else { | |
4860 glDisableClientState(GL_NORMAL_ARRAY); | |
4861 glDisable(GL_LIGHTING); | |
4862 } | |
4863 | |
4864 if (pdd->cdata) { | |
4865 glEnableClientState(GL_COLOR_ARRAY); | |
4866 glColorPointer(3, GL_FLOAT, 0, pdd->cdata); | |
4867 } | |
4868 | |
4869 draw_particle_arrays(draw_as, totpoint, ob_dt, 0); | |
4870 | |
4871 pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; | |
4872 pdd->totpoint = totpoint; | |
4873 } | |
4874 | |
4875 if (pdd && pdd->vedata) { | |
4876 glDisableClientState(GL_COLOR_ARRAY); | |
4877 cpack(0xC0C0C0); | |
4878 ················ | |
4879 glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); | |
4880 ················ | |
4881 glDrawArrays(GL_LINES, 0, 2 * totve); | |
4882 } | |
4883 | |
4884 glPolygonMode(GL_FRONT, polygonmode[0]); | |
4885 glPolygonMode(GL_BACK, polygonmode[1]); | |
4886 | |
4887 /* 7. */ | |
4888 ········ | |
4889 glDisable(GL_LIGHTING); | |
4890 glDisableClientState(GL_COLOR_ARRAY); | |
4891 glDisableClientState(GL_VERTEX_ARRAY); | |
4892 glDisableClientState(GL_NORMAL_ARRAY); | |
4893 | |
4894 if (states) | |
4895 MEM_freeN(states); | |
4896 | |
4897 psys->flag &= ~PSYS_DRAWING; | |
4898 | |
4899 /* draw data can't be saved for billboards as they must update to target
changes */ | |
4900 if (draw_as == PART_DRAW_BB) { | |
4901 psys_free_pdd(psys); | |
4902 pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; | |
4903 } | |
4904 | |
4905 if (psys->lattice_deform_data) { | |
4906 end_latt_deform(psys->lattice_deform_data); | |
4907 psys->lattice_deform_data = NULL; | |
4908 } | |
4909 | |
4910 if (pdd) { | |
4911 /* drop references to stack memory */ | |
4912 pdd->ma_col = NULL; | |
4913 } | |
4914 | |
4915 if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) { | |
4916 glLoadMatrixf(rv3d->viewmat); | |
4917 } | |
4918 } | |
4919 | |
4920 static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit
) | |
4921 { | |
4922 if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) | |
4923 PE_update_object(scene, ob, 0); | |
4924 | |
4925 /* create path and child path cache if it doesn't exist already */ | |
4926 if (edit->pathcache == NULL) | |
4927 psys_cache_edit_paths(scene, ob, edit, CFRA); | |
4928 } | |
4929 | |
4930 static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) | |
4931 { | |
4932 ParticleCacheKey **cache, *path, *pkey; | |
4933 PTCacheEditPoint *point; | |
4934 PTCacheEditKey *key; | |
4935 ParticleEditSettings *pset = PE_settings(scene); | |
4936 int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ?
pset->fade_frames : 0; | |
4937 int steps = 1; | |
4938 float sel_col[3]; | |
4939 float nosel_col[3]; | |
4940 float *pathcol = NULL, *pcol; | |
4941 | |
4942 if (edit->pathcache == NULL) | |
4943 return; | |
4944 | |
4945 PE_hide_keys_time(scene, edit, CFRA); | |
4946 | |
4947 /* opengl setup */ | |
4948 if ((v3d->flag & V3D_ZBUF_SELECT) == 0) | |
4949 glDisable(GL_DEPTH_TEST); | |
4950 | |
4951 /* get selection theme colors */ | |
4952 UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col); | |
4953 UI_GetThemeColor3fv(TH_VERTEX, nosel_col); | |
4954 | |
4955 /* draw paths */ | |
4956 steps = (*edit->pathcache)->steps + 1; | |
4957 | |
4958 glEnable(GL_BLEND); | |
4959 pathcol = MEM_callocN(steps * 4 * sizeof(float), "particle path color da
ta"); | |
4960 | |
4961 glEnableClientState(GL_VERTEX_ARRAY); | |
4962 glEnableClientState(GL_COLOR_ARRAY); | |
4963 | |
4964 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
4965 glEnable(GL_COLOR_MATERIAL); | |
4966 glShadeModel(GL_SMOOTH); | |
4967 | |
4968 if (pset->brushtype == PE_BRUSH_WEIGHT) { | |
4969 glLineWidth(2.0f); | |
4970 glDisable(GL_LIGHTING); | |
4971 } | |
4972 | |
4973 cache = edit->pathcache; | |
4974 for (i = 0, point = edit->points; i < totpoint; i++, point++) { | |
4975 path = cache[i]; | |
4976 glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co)
; | |
4977 | |
4978 if (point->flag & PEP_HIDE) { | |
4979 for (k = 0, pcol = pathcol; k < steps; k++, pcol += 4) { | |
4980 copy_v3_v3(pcol, path->col); | |
4981 pcol[3] = 0.25f; | |
4982 } | |
4983 | |
4984 glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol); | |
4985 } | |
4986 else if (timed) { | |
4987 for (k = 0, pcol = pathcol, pkey = path; k < steps; k++,
pkey++, pcol += 4) { | |
4988 copy_v3_v3(pcol, pkey->col); | |
4989 pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time
) / (float)pset->fade_frames; | |
4990 } | |
4991 | |
4992 glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol); | |
4993 } | |
4994 else | |
4995 glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), pa
th->col); | |
4996 | |
4997 glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); | |
4998 } | |
4999 | |
5000 if (pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; } | |
5001 | |
5002 | |
5003 /* draw edit vertices */ | |
5004 if (pset->selectmode != SCE_SELECT_PATH) { | |
5005 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); | |
5006 | |
5007 if (pset->selectmode == SCE_SELECT_POINT) { | |
5008 float *pd = NULL, *pdata = NULL; | |
5009 float *cd = NULL, *cdata = NULL; | |
5010 int totkeys = 0; | |
5011 | |
5012 for (i = 0, point = edit->points; i < totpoint; i++, poi
nt++) | |
5013 if (!(point->flag & PEP_HIDE)) | |
5014 totkeys += point->totkey; | |
5015 | |
5016 if (totkeys) { | |
5017 if (edit->points && !(edit->points->keys->flag &
PEK_USE_WCO)) | |
5018 pd = pdata = MEM_callocN(totkeys * 3 * s
izeof(float), "particle edit point data"); | |
5019 cd = cdata = MEM_callocN(totkeys * (timed ? 4 :
3) * sizeof(float), "particle edit color data"); | |
5020 } | |
5021 | |
5022 for (i = 0, point = edit->points; i < totpoint; i++, poi
nt++) { | |
5023 if (point->flag & PEP_HIDE) | |
5024 continue; | |
5025 | |
5026 for (k = 0, key = point->keys; k < point->totkey
; k++, key++) { | |
5027 if (pd) { | |
5028 copy_v3_v3(pd, key->co); | |
5029 pd += 3; | |
5030 } | |
5031 | |
5032 if (key->flag & PEK_SELECT) { | |
5033 copy_v3_v3(cd, sel_col); | |
5034 } | |
5035 else { | |
5036 copy_v3_v3(cd, nosel_col); | |
5037 } | |
5038 | |
5039 if (timed) | |
5040 *(cd + 3) = 1.0f - fabsf((float)
CFRA - *key->time) / (float)pset->fade_frames; | |
5041 | |
5042 cd += (timed ? 4 : 3); | |
5043 } | |
5044 } | |
5045 cd = cdata; | |
5046 pd = pdata; | |
5047 for (i = 0, point = edit->points; i < totpoint; i++, poi
nt++) { | |
5048 if (point->flag & PEP_HIDE || point->totkey == 0
) | |
5049 continue; | |
5050 | |
5051 if (point->keys->flag & PEK_USE_WCO) | |
5052 glVertexPointer(3, GL_FLOAT, sizeof(PTCa
cheEditKey), point->keys->world_co); | |
5053 else | |
5054 glVertexPointer(3, GL_FLOAT, 3 * sizeof(
float), pd); | |
5055 | |
5056 glColorPointer((timed ? 4 : 3), GL_FLOAT, (timed
? 4 : 3) * sizeof(float), cd); | |
5057 | |
5058 glDrawArrays(GL_POINTS, 0, point->totkey); | |
5059 | |
5060 pd += pd ? 3 * point->totkey : 0; | |
5061 cd += (timed ? 4 : 3) * point->totkey; | |
5062 } | |
5063 if (pdata) { MEM_freeN(pdata); pd = pdata = NULL; } | |
5064 if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; } | |
5065 } | |
5066 else if (pset->selectmode == SCE_SELECT_END) { | |
5067 for (i = 0, point = edit->points; i < totpoint; i++, poi
nt++) { | |
5068 if ((point->flag & PEP_HIDE) == 0 && point->totk
ey) { | |
5069 key = point->keys + point->totkey - 1; | |
5070 if (key->flag & PEK_SELECT) | |
5071 glColor3fv(sel_col); | |
5072 else | |
5073 glColor3fv(nosel_col); | |
5074 /* has to be like this.. otherwise selec
tion won't work, have try glArrayElement later..*/ | |
5075 glBegin(GL_POINTS); | |
5076 glVertex3fv(key->flag & PEK_USE_WCO ? ke
y->world_co : key->co); | |
5077 glEnd(); | |
5078 } | |
5079 } | |
5080 } | |
5081 } | |
5082 | |
5083 glDisable(GL_BLEND); | |
5084 glDisable(GL_LIGHTING); | |
5085 glDisable(GL_COLOR_MATERIAL); | |
5086 glDisableClientState(GL_COLOR_ARRAY); | |
5087 glDisableClientState(GL_NORMAL_ARRAY); | |
5088 glDisableClientState(GL_VERTEX_ARRAY); | |
5089 glShadeModel(GL_FLAT); | |
5090 if (v3d->zbuf) glEnable(GL_DEPTH_TEST); | |
5091 glLineWidth(1.0f); | |
5092 glPointSize(1.0); | |
5093 } | |
5094 //static void ob_draw_RE_motion(float com[3],float rotscale[3][3],float tw,float
th) | |
5095 static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
at ith, float drw_size) | |
5096 { | |
5097 float tr[3][3]; | |
5098 float root[3], tip[3]; | |
5099 float tw, th; | |
5100 /* take a copy for not spoiling original */ | |
5101 copy_m3_m3(tr, rotscale); | |
5102 tw = itw * drw_size; | |
5103 th = ith * drw_size; | |
5104 | |
5105 glColor4ub(0x7F, 0x00, 0x00, 155); | |
5106 glBegin(GL_LINES); | |
5107 root[1] = root[2] = 0.0f; | |
5108 root[0] = -drw_size; | |
5109 mul_m3_v3(tr, root); | |
5110 add_v3_v3(root, com); | |
5111 glVertex3fv(root); | |
5112 tip[1] = tip[2] = 0.0f; | |
5113 tip[0] = drw_size; | |
5114 mul_m3_v3(tr, tip); | |
5115 add_v3_v3(tip, com); | |
5116 glVertex3fv(tip); | |
5117 glEnd(); | |
5118 | |
5119 root[1] = 0.0f; root[2] = tw; | |
5120 root[0] = th; | |
5121 glBegin(GL_LINES); | |
5122 mul_m3_v3(tr, root); | |
5123 add_v3_v3(root, com); | |
5124 glVertex3fv(root); | |
5125 glVertex3fv(tip); | |
5126 glEnd(); | |
5127 | |
5128 root[1] = 0.0f; root[2] = -tw; | |
5129 root[0] = th; | |
5130 glBegin(GL_LINES); | |
5131 mul_m3_v3(tr, root); | |
5132 add_v3_v3(root, com); | |
5133 glVertex3fv(root); | |
5134 glVertex3fv(tip); | |
5135 glEnd(); | |
5136 | |
5137 root[1] = tw; root[2] = 0.0f; | |
5138 root[0] = th; | |
5139 glBegin(GL_LINES); | |
5140 mul_m3_v3(tr, root); | |
5141 add_v3_v3(root, com); | |
5142 glVertex3fv(root); | |
5143 glVertex3fv(tip); | |
5144 glEnd(); | |
5145 | |
5146 root[1] = -tw; root[2] = 0.0f; | |
5147 root[0] = th; | |
5148 glBegin(GL_LINES); | |
5149 mul_m3_v3(tr, root); | |
5150 add_v3_v3(root, com); | |
5151 glVertex3fv(root); | |
5152 glVertex3fv(tip); | |
5153 glEnd(); | |
5154 | |
5155 glColor4ub(0x00, 0x7F, 0x00, 155); | |
5156 | |
5157 glBegin(GL_LINES); | |
5158 root[0] = root[2] = 0.0f; | |
5159 root[1] = -drw_size; | |
5160 mul_m3_v3(tr, root); | |
5161 add_v3_v3(root, com); | |
5162 glVertex3fv(root); | |
5163 tip[0] = tip[2] = 0.0f; | |
5164 tip[1] = drw_size; | |
5165 mul_m3_v3(tr, tip); | |
5166 add_v3_v3(tip, com); | |
5167 glVertex3fv(tip); | |
5168 glEnd(); | |
5169 | |
5170 root[0] = 0.0f; root[2] = tw; | |
5171 root[1] = th; | |
5172 glBegin(GL_LINES); | |
5173 mul_m3_v3(tr, root); | |
5174 add_v3_v3(root, com); | |
5175 glVertex3fv(root); | |
5176 glVertex3fv(tip); | |
5177 glEnd(); | |
5178 | |
5179 root[0] = 0.0f; root[2] = -tw; | |
5180 root[1] = th; | |
5181 glBegin(GL_LINES); | |
5182 mul_m3_v3(tr, root); | |
5183 add_v3_v3(root, com); | |
5184 glVertex3fv(root); | |
5185 glVertex3fv(tip); | |
5186 glEnd(); | |
5187 | |
5188 root[0] = tw; root[2] = 0.0f; | |
5189 root[1] = th; | |
5190 glBegin(GL_LINES); | |
5191 mul_m3_v3(tr, root); | |
5192 add_v3_v3(root, com); | |
5193 glVertex3fv(root); | |
5194 glVertex3fv(tip); | |
5195 glEnd(); | |
5196 | |
5197 root[0] = -tw; root[2] = 0.0f; | |
5198 root[1] = th; | |
5199 glBegin(GL_LINES); | |
5200 mul_m3_v3(tr, root); | |
5201 add_v3_v3(root, com); | |
5202 glVertex3fv(root); | |
5203 glVertex3fv(tip); | |
5204 glEnd(); | |
5205 | |
5206 glColor4ub(0x00, 0x00, 0x7F, 155); | |
5207 glBegin(GL_LINES); | |
5208 root[0] = root[1] = 0.0f; | |
5209 root[2] = -drw_size; | |
5210 mul_m3_v3(tr, root); | |
5211 add_v3_v3(root, com); | |
5212 glVertex3fv(root); | |
5213 tip[0] = tip[1] = 0.0f; | |
5214 tip[2] = drw_size; | |
5215 mul_m3_v3(tr, tip); | |
5216 add_v3_v3(tip, com); | |
5217 glVertex3fv(tip); | |
5218 glEnd(); | |
5219 | |
5220 root[0] = 0.0f; root[1] = tw; | |
5221 root[2] = th; | |
5222 glBegin(GL_LINES); | |
5223 mul_m3_v3(tr, root); | |
5224 add_v3_v3(root, com); | |
5225 glVertex3fv(root); | |
5226 glVertex3fv(tip); | |
5227 glEnd(); | |
5228 | |
5229 root[0] = 0.0f; root[1] = -tw; | |
5230 root[2] = th; | |
5231 glBegin(GL_LINES); | |
5232 mul_m3_v3(tr, root); | |
5233 add_v3_v3(root, com); | |
5234 glVertex3fv(root); | |
5235 glVertex3fv(tip); | |
5236 glEnd(); | |
5237 | |
5238 root[0] = tw; root[1] = 0.0f; | |
5239 root[2] = th; | |
5240 glBegin(GL_LINES); | |
5241 mul_m3_v3(tr, root); | |
5242 add_v3_v3(root, com); | |
5243 glVertex3fv(root); | |
5244 glVertex3fv(tip); | |
5245 glEnd(); | |
5246 | |
5247 root[0] = -tw; root[1] = 0.0f; | |
5248 root[2] = th; | |
5249 glBegin(GL_LINES); | |
5250 mul_m3_v3(tr, root); | |
5251 add_v3_v3(root, com); | |
5252 glVertex3fv(root); | |
5253 glVertex3fv(tip); | |
5254 glEnd(); | |
5255 } | |
5256 | |
5257 /* place to add drawers */ | |
5258 | |
5259 static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles) | |
5260 { | |
5261 BezTriple *bezt; | |
5262 float *fp; | |
5263 int a; | |
5264 | |
5265 if (nu->hide || hide_handles) return; | |
5266 | |
5267 glBegin(GL_LINES); | |
5268 | |
5269 if (nu->type == CU_BEZIER) { | |
5270 | |
5271 #define TH_HANDLE_COL_TOT ((TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) + 1) | |
5272 /* use MIN2 when indexing to ensure newer files don't read outsi
de the array */ | |
5273 unsigned char handle_cols[TH_HANDLE_COL_TOT][3]; | |
5274 const int basecol = sel ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE; | |
5275 | |
5276 for (a = 0; a < TH_HANDLE_COL_TOT; a++) { | |
5277 UI_GetThemeColor3ubv(basecol + a, handle_cols[a]); | |
5278 } | |
5279 | |
5280 bezt = nu->bezt; | |
5281 a = nu->pntsu; | |
5282 while (a--) { | |
5283 if (bezt->hide == 0) { | |
5284 if ((bezt->f2 & SELECT) == sel) { | |
5285 fp = bezt->vec[0]; | |
5286 | |
5287 glColor3ubv(handle_cols[MIN2(bezt->h1, T
H_HANDLE_COL_TOT - 1)]); | |
5288 glVertex3fv(fp); | |
5289 glVertex3fv(fp + 3); | |
5290 | |
5291 glColor3ubv(handle_cols[MIN2(bezt->h2, T
H_HANDLE_COL_TOT - 1)]); | |
5292 glVertex3fv(fp + 3); | |
5293 glVertex3fv(fp + 6); | |
5294 } | |
5295 else if ((bezt->f1 & SELECT) == sel) { | |
5296 fp = bezt->vec[0]; | |
5297 | |
5298 glColor3ubv(handle_cols[MIN2(bezt->h1, T
H_HANDLE_COL_TOT - 1)]); | |
5299 glVertex3fv(fp); | |
5300 glVertex3fv(fp + 3); | |
5301 } | |
5302 else if ((bezt->f3 & SELECT) == sel) { | |
5303 fp = bezt->vec[1]; | |
5304 | |
5305 glColor3ubv(handle_cols[MIN2(bezt->h2, T
H_HANDLE_COL_TOT - 1)]); | |
5306 glVertex3fv(fp); | |
5307 glVertex3fv(fp + 3); | |
5308 } | |
5309 } | |
5310 bezt++; | |
5311 } | |
5312 | |
5313 #undef TH_HANDLE_COL_TOT | |
5314 | |
5315 } | |
5316 glEnd(); | |
5317 } | |
5318 | |
5319 static void drawhandlesN_active(Nurb *nu) | |
5320 { | |
5321 BezTriple *bezt; | |
5322 float *fp; | |
5323 int a; | |
5324 | |
5325 if (nu->hide) return; | |
5326 | |
5327 UI_ThemeColor(TH_ACTIVE_SPLINE); | |
5328 glLineWidth(2); | |
5329 | |
5330 glBegin(GL_LINES); | |
5331 | |
5332 if (nu->type == CU_BEZIER) { | |
5333 bezt = nu->bezt; | |
5334 a = nu->pntsu; | |
5335 while (a--) { | |
5336 if (bezt->hide == 0) { | |
5337 fp = bezt->vec[0]; | |
5338 | |
5339 glVertex3fv(fp); | |
5340 glVertex3fv(fp + 3); | |
5341 | |
5342 glVertex3fv(fp + 3); | |
5343 glVertex3fv(fp + 6); | |
5344 } | |
5345 bezt++; | |
5346 } | |
5347 } | |
5348 glEnd(); | |
5349 | |
5350 glColor3ub(0, 0, 0); | |
5351 glLineWidth(1); | |
5352 } | |
5353 | |
5354 static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *
lastsel) | |
5355 { | |
5356 BezTriple *bezt; | |
5357 BPoint *bp; | |
5358 float size; | |
5359 int a, color; | |
5360 | |
5361 if (nu->hide) return; | |
5362 | |
5363 if (sel) color = TH_VERTEX_SELECT; | |
5364 else color = TH_VERTEX; | |
5365 | |
5366 UI_ThemeColor(color); | |
5367 | |
5368 size = UI_GetThemeValuef(TH_VERTEX_SIZE); | |
5369 glPointSize(size); | |
5370 ········ | |
5371 bglBegin(GL_POINTS); | |
5372 ········ | |
5373 if (nu->type == CU_BEZIER) { | |
5374 | |
5375 bezt = nu->bezt; | |
5376 a = nu->pntsu; | |
5377 while (a--) { | |
5378 if (bezt->hide == 0) { | |
5379 if (sel == 1 && bezt == lastsel) { | |
5380 UI_ThemeColor(TH_LASTSEL_POINT); | |
5381 bglVertex3fv(bezt->vec[1]); | |
5382 | |
5383 if (!hide_handles) { | |
5384 if (bezt->f1 & SELECT) bglVertex
3fv(bezt->vec[0]); | |
5385 if (bezt->f3 & SELECT) bglVertex
3fv(bezt->vec[2]); | |
5386 } | |
5387 | |
5388 UI_ThemeColor(color); | |
5389 } | |
5390 else if (hide_handles) { | |
5391 if ((bezt->f2 & SELECT) == sel) bglVerte
x3fv(bezt->vec[1]); | |
5392 } | |
5393 else { | |
5394 if ((bezt->f1 & SELECT) == sel) bglVerte
x3fv(bezt->vec[0]); | |
5395 if ((bezt->f2 & SELECT) == sel) bglVerte
x3fv(bezt->vec[1]); | |
5396 if ((bezt->f3 & SELECT) == sel) bglVerte
x3fv(bezt->vec[2]); | |
5397 } | |
5398 } | |
5399 bezt++; | |
5400 } | |
5401 } | |
5402 else { | |
5403 bp = nu->bp; | |
5404 a = nu->pntsu * nu->pntsv; | |
5405 while (a--) { | |
5406 if (bp->hide == 0) { | |
5407 if (bp == lastsel) { | |
5408 UI_ThemeColor(TH_LASTSEL_POINT); | |
5409 bglVertex3fv(bp->vec); | |
5410 UI_ThemeColor(color); | |
5411 } | |
5412 else { | |
5413 if ((bp->f1 & SELECT) == sel) bglVertex3
fv(bp->vec); | |
5414 } | |
5415 } | |
5416 bp++; | |
5417 } | |
5418 } | |
5419 ········ | |
5420 bglEnd(); | |
5421 glPointSize(1.0); | |
5422 } | |
5423 | |
5424 static void editnurb_draw_active_poly(Nurb *nu) | |
5425 { | |
5426 BPoint *bp; | |
5427 int a, b; | |
5428 | |
5429 UI_ThemeColor(TH_ACTIVE_SPLINE); | |
5430 glLineWidth(2); | |
5431 | |
5432 bp = nu->bp; | |
5433 for (b = 0; b < nu->pntsv; b++) { | |
5434 if (nu->flagu & 1) glBegin(GL_LINE_LOOP); | |
5435 else glBegin(GL_LINE_STRIP); | |
5436 | |
5437 for (a = 0; a < nu->pntsu; a++, bp++) { | |
5438 glVertex3fv(bp->vec); | |
5439 } | |
5440 | |
5441 glEnd(); | |
5442 } | |
5443 | |
5444 glColor3ub(0, 0, 0); | |
5445 glLineWidth(1); | |
5446 } | |
5447 | |
5448 static void editnurb_draw_active_nurbs(Nurb *nu) | |
5449 { | |
5450 BPoint *bp, *bp1; | |
5451 int a, b, ofs; | |
5452 | |
5453 UI_ThemeColor(TH_ACTIVE_SPLINE); | |
5454 glLineWidth(2); | |
5455 | |
5456 glBegin(GL_LINES); | |
5457 bp = nu->bp; | |
5458 for (b = 0; b < nu->pntsv; b++) { | |
5459 bp1 = bp; | |
5460 bp++; | |
5461 | |
5462 for (a = nu->pntsu - 1; a > 0; a--, bp++) { | |
5463 if (bp->hide == 0 && bp1->hide == 0) { | |
5464 glVertex3fv(bp->vec); | |
5465 glVertex3fv(bp1->vec); | |
5466 } | |
5467 bp1 = bp; | |
5468 } | |
5469 } | |
5470 | |
5471 if (nu->pntsv > 1) { /* surface */ | |
5472 | |
5473 ofs = nu->pntsu; | |
5474 for (b = 0; b < nu->pntsu; b++) { | |
5475 bp1 = nu->bp + b; | |
5476 bp = bp1 + ofs; | |
5477 for (a = nu->pntsv - 1; a > 0; a--, bp += ofs) { | |
5478 if (bp->hide == 0 && bp1->hide == 0) { | |
5479 glVertex3fv(bp->vec); | |
5480 glVertex3fv(bp1->vec); | |
5481 } | |
5482 bp1 = bp; | |
5483 } | |
5484 } | |
5485 } | |
5486 | |
5487 glEnd(); | |
5488 | |
5489 glColor3ub(0, 0, 0); | |
5490 glLineWidth(1); | |
5491 } | |
5492 | |
5493 static void draw_editnurb(Object *ob, Nurb *nurb, int sel) | |
5494 { | |
5495 Nurb *nu; | |
5496 BPoint *bp, *bp1; | |
5497 int a, b, ofs, index; | |
5498 Curve *cu = (Curve *)ob->data; | |
5499 | |
5500 index = 0; | |
5501 nu = nurb; | |
5502 while (nu) { | |
5503 if (nu->hide == 0) { | |
5504 switch (nu->type) { | |
5505 case CU_POLY: | |
5506 if (!sel && index == cu->actnu) { | |
5507 /* we should draw active spline
highlight below everything */ | |
5508 editnurb_draw_active_poly(nu); | |
5509 } | |
5510 | |
5511 UI_ThemeColor(TH_NURB_ULINE); | |
5512 bp = nu->bp; | |
5513 for (b = 0; b < nu->pntsv; b++) { | |
5514 if (nu->flagu & 1) glBegin(GL_LI
NE_LOOP); | |
5515 else glBegin(GL_LINE_STRIP); | |
5516 | |
5517 for (a = 0; a < nu->pntsu; a++,
bp++) { | |
5518 glVertex3fv(bp->vec); | |
5519 } | |
5520 | |
5521 glEnd(); | |
5522 } | |
5523 break; | |
5524 case CU_NURBS: | |
5525 if (!sel && index == cu->actnu) { | |
5526 /* we should draw active spline
highlight below everything */ | |
5527 editnurb_draw_active_nurbs(nu); | |
5528 } | |
5529 | |
5530 bp = nu->bp; | |
5531 for (b = 0; b < nu->pntsv; b++) { | |
5532 bp1 = bp; | |
5533 bp++; | |
5534 for (a = nu->pntsu - 1; a > 0; a
--, bp++) { | |
5535 if (bp->hide == 0 && bp1
->hide == 0) { | |
5536 if (sel) { | |
5537 if ((bp-
>f1 & SELECT) && (bp1->f1 & SELECT)) { | |
5538
UI_ThemeColor(TH_NURB_SEL_ULINE); | |
5539 | |
5540
glBegin(GL_LINE_STRIP); | |
5541
glVertex3fv(bp->vec); | |
5542
glVertex3fv(bp1->vec); | |
5543
glEnd(); | |
5544 } | |
5545 } | |
5546 else { | |
5547 if ((bp-
>f1 & SELECT) && (bp1->f1 & SELECT)) { | |
5548
/* pass */ | |
5549 } | |
5550 else { | |
5551
UI_ThemeColor(TH_NURB_ULINE); | |
5552 | |
5553
glBegin(GL_LINE_STRIP); | |
5554
glVertex3fv(bp->vec); | |
5555
glVertex3fv(bp1->vec); | |
5556
glEnd(); | |
5557 } | |
5558 } | |
5559 } | |
5560 bp1 = bp; | |
5561 } | |
5562 } | |
5563 if (nu->pntsv > 1) { /* surface */ | |
5564 | |
5565 ofs = nu->pntsu; | |
5566 for (b = 0; b < nu->pntsu; b++)
{ | |
5567 bp1 = nu->bp + b; | |
5568 bp = bp1 + ofs; | |
5569 for (a = nu->pntsv - 1;
a > 0; a--, bp += ofs) { | |
5570 if (bp->hide ==
0 && bp1->hide == 0) { | |
5571 if (sel)
{ | |
5572
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { | |
5573
UI_ThemeColor(TH_NURB_SEL_VLINE); | |
5574 | |
5575
glBegin(GL_LINE_STRIP); | |
5576
glVertex3fv(bp->vec); | |
5577
glVertex3fv(bp1->vec); | |
5578
glEnd(); | |
5579
} | |
5580 } | |
5581 else { | |
5582
if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { | |
5583
/* pass */ | |
5584
} | |
5585
else { | |
5586
UI_ThemeColor(TH_NURB_VLINE); | |
5587 | |
5588
glBegin(GL_LINE_STRIP); | |
5589
glVertex3fv(bp->vec); | |
5590
glVertex3fv(bp1->vec); | |
5591
glEnd(); | |
5592
} | |
5593 } | |
5594 } | |
5595 bp1 = bp; | |
5596 } | |
5597 } | |
5598 | |
5599 } | |
5600 break; | |
5601 } | |
5602 } | |
5603 | |
5604 index++; | |
5605 nu = nu->next; | |
5606 } | |
5607 } | |
5608 | |
5609 static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
Nurb *nurb, | |
5610 const char dt, const short dflag, const unsigned char ob_wi
re_col[4]) | |
5611 { | |
5612 ToolSettings *ts = scene->toolsettings; | |
5613 Object *ob = base->object; | |
5614 Curve *cu = ob->data; | |
5615 Nurb *nu; | |
5616 BevList *bl; | |
5617 const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; | |
5618 int index; | |
5619 unsigned char wire_col[3]; | |
5620 | |
5621 /* DispList */ | |
5622 UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col); | |
5623 glColor3ubv(wire_col); | |
5624 | |
5625 drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); | |
5626 | |
5627 if (v3d->zbuf) glDepthFunc(GL_ALWAYS); | |
5628 ········ | |
5629 /* first non-selected and active handles */ | |
5630 index = 0; | |
5631 for (nu = nurb; nu; nu = nu->next) { | |
5632 if (nu->type == CU_BEZIER) { | |
5633 if (index == cu->actnu && !hide_handles) | |
5634 drawhandlesN_active(nu); | |
5635 drawhandlesN(nu, 0, hide_handles); | |
5636 } | |
5637 index++; | |
5638 } | |
5639 draw_editnurb(ob, nurb, 0); | |
5640 draw_editnurb(ob, nurb, 1); | |
5641 /* selected handles */ | |
5642 for (nu = nurb; nu; nu = nu->next) { | |
5643 if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) ==
0) | |
5644 drawhandlesN(nu, 1, hide_handles); | |
5645 drawvertsN(nu, 0, hide_handles, NULL); | |
5646 } | |
5647 ········ | |
5648 if (v3d->zbuf) glDepthFunc(GL_LEQUAL); | |
5649 | |
5650 /* direction vectors for 3d curve paths | |
5651 * when at its lowest, don't render normals */ | |
5652 if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag &
CU_HIDE_NORMALS) == 0) { | |
5653 | |
5654 UI_ThemeColor(TH_WIRE_EDIT); | |
5655 for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl =
bl->next, nu = nu->next) { | |
5656 BevPoint *bevp = (BevPoint *)(bl + 1); | |
5657 int nr = bl->nr; | |
5658 int skip = nu->resolu / 16; | |
5659 ························ | |
5660 while (nr-- > 0) { /* accounts for empty bevel lists */ | |
5661 const float fac = bevp->radius * ts->normalsize; | |
5662 float vec_a[3]; /* Offset perpendicular to the c
urve */ | |
5663 float vec_b[3]; /* Delta along the curve */ | |
5664 | |
5665 vec_a[0] = fac; | |
5666 vec_a[1] = 0.0f; | |
5667 vec_a[2] = 0.0f; | |
5668 | |
5669 vec_b[0] = -fac; | |
5670 vec_b[1] = 0.0f; | |
5671 vec_b[2] = 0.0f; | |
5672 ································ | |
5673 mul_qt_v3(bevp->quat, vec_a); | |
5674 mul_qt_v3(bevp->quat, vec_b); | |
5675 add_v3_v3(vec_a, bevp->vec); | |
5676 add_v3_v3(vec_b, bevp->vec); | |
5677 | |
5678 madd_v3_v3fl(vec_a, bevp->dir, -fac); | |
5679 madd_v3_v3fl(vec_b, bevp->dir, -fac); | |
5680 | |
5681 glBegin(GL_LINE_STRIP); | |
5682 glVertex3fv(vec_a); | |
5683 glVertex3fv(bevp->vec); | |
5684 glVertex3fv(vec_b); | |
5685 glEnd(); | |
5686 ································ | |
5687 bevp += skip + 1; | |
5688 nr -= skip; | |
5689 } | |
5690 } | |
5691 } | |
5692 | |
5693 if (v3d->zbuf) glDepthFunc(GL_ALWAYS); | |
5694 ········ | |
5695 for (nu = nurb; nu; nu = nu->next) { | |
5696 drawvertsN(nu, 1, hide_handles, cu->lastsel); | |
5697 } | |
5698 ········ | |
5699 if (v3d->zbuf) glDepthFunc(GL_LEQUAL); | |
5700 } | |
5701 | |
5702 /* draw a sphere for use as an empty drawtype */ | |
5703 static void draw_empty_sphere(float size) | |
5704 { | |
5705 static GLuint displist = 0; | |
5706 ········ | |
5707 if (displist == 0) { | |
5708 GLUquadricObj *qobj; | |
5709 ················ | |
5710 displist = glGenLists(1); | |
5711 glNewList(displist, GL_COMPILE); | |
5712 ················ | |
5713 glPushMatrix(); | |
5714 ················ | |
5715 qobj = gluNewQuadric(); | |
5716 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); | |
5717 gluDisk(qobj, 0.0, 1, 16, 1); | |
5718 ················ | |
5719 glRotatef(90, 0, 1, 0); | |
5720 gluDisk(qobj, 0.0, 1, 16, 1); | |
5721 ················ | |
5722 glRotatef(90, 1, 0, 0); | |
5723 gluDisk(qobj, 0.0, 1, 16, 1); | |
5724 ················ | |
5725 gluDeleteQuadric(qobj); | |
5726 ················ | |
5727 glPopMatrix(); | |
5728 glEndList(); | |
5729 } | |
5730 ········ | |
5731 glScalef(size, size, size); | |
5732 glCallList(displist); | |
5733 glScalef(1.0f / size, 1.0f / size, 1.0f / size); | |
5734 } | |
5735 | |
5736 /* draw a cone for use as an empty drawtype */ | |
5737 static void draw_empty_cone(float size) | |
5738 { | |
5739 float cent = 0; | |
5740 float radius; | |
5741 GLUquadricObj *qobj = gluNewQuadric(); | |
5742 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); | |
5743 ········ | |
5744 ········ | |
5745 glPushMatrix(); | |
5746 ········ | |
5747 radius = size; | |
5748 glTranslatef(cent, cent, cent); | |
5749 glScalef(radius, size * 2.0f, radius); | |
5750 glRotatef(-90.0, 1.0, 0.0, 0.0); | |
5751 gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1); | |
5752 | |
5753 glPopMatrix(); | |
5754 ········ | |
5755 gluDeleteQuadric(qobj); | |
5756 } | |
5757 | |
5758 static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2]) | |
5759 { | |
5760 cpack(0); | |
5761 bglPolygonOffset(rv3d->dist, -1.0); | |
5762 set_inverted_drawing(1); | |
5763 glBegin(GL_QUADS); | |
5764 glVertex2fv(textcurs[0]); | |
5765 glVertex2fv(textcurs[1]); | |
5766 glVertex2fv(textcurs[2]); | |
5767 glVertex2fv(textcurs[3]); | |
5768 glEnd(); | |
5769 set_inverted_drawing(0); | |
5770 bglPolygonOffset(rv3d->dist, 0.0); | |
5771 } | |
5772 | |
5773 static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
rt) | |
5774 { | |
5775 float vec[3], vx[3], vy[3]; | |
5776 const float tot_inv = (1.0f / (float)CIRCLE_RESOL); | |
5777 int a; | |
5778 bool inverse = false; | |
5779 float x, y, fac; | |
5780 | |
5781 if (start < 0) { | |
5782 inverse = true; | |
5783 start = -start; | |
5784 } | |
5785 | |
5786 mul_v3_v3fl(vx, tmat[0], rad); | |
5787 mul_v3_v3fl(vy, tmat[1], rad); | |
5788 | |
5789 glBegin(GL_LINE_STRIP); | |
5790 | |
5791 if (inverse == 0) { | |
5792 copy_v3_v3(vec, cent); | |
5793 glVertex3fv(vec); | |
5794 | |
5795 for (a = 0; a < CIRCLE_RESOL; a++) { | |
5796 if (a + start >= CIRCLE_RESOL) | |
5797 start = -a + 1; | |
5798 | |
5799 fac = (float)a * tot_inv; | |
5800 x = sinval[a + start] * fac; | |
5801 y = cosval[a + start] * fac; | |
5802 | |
5803 vec[0] = cent[0] + (x * vx[0] + y * vy[0]); | |
5804 vec[1] = cent[1] + (x * vx[1] + y * vy[1]); | |
5805 vec[2] = cent[2] + (x * vx[2] + y * vy[2]); | |
5806 | |
5807 glVertex3fv(vec); | |
5808 } | |
5809 } | |
5810 else { | |
5811 fac = (float)(CIRCLE_RESOL - 1) * tot_inv; | |
5812 x = sinval[start] * fac; | |
5813 y = cosval[start] * fac; | |
5814 | |
5815 vec[0] = cent[0] + (x * vx[0] + y * vy[0]); | |
5816 vec[1] = cent[1] + (x * vx[1] + y * vy[1]); | |
5817 vec[2] = cent[2] + (x * vx[2] + y * vy[2]); | |
5818 | |
5819 glVertex3fv(vec); | |
5820 | |
5821 for (a = 0; a < CIRCLE_RESOL; a++) { | |
5822 if (a + start >= CIRCLE_RESOL) | |
5823 start = -a + 1; | |
5824 | |
5825 fac = (float)(-a + (CIRCLE_RESOL - 1)) * tot_inv; | |
5826 x = sinval[a + start] * fac; | |
5827 y = cosval[a + start] * fac; | |
5828 | |
5829 vec[0] = cent[0] + (x * vx[0] + y * vy[0]); | |
5830 vec[1] = cent[1] + (x * vx[1] + y * vy[1]); | |
5831 vec[2] = cent[2] + (x * vx[2] + y * vy[2]); | |
5832 glVertex3fv(vec); | |
5833 } | |
5834 } | |
5835 | |
5836 glEnd(); | |
5837 } | |
5838 | |
5839 /* draws a circle on x-z plane given the scaling of the circle, assuming that | |
5840 * all required matrices have been set (used for drawing empties) | |
5841 */ | |
5842 static void drawcircle_size(float size) | |
5843 { | |
5844 float x, y; | |
5845 short degrees; | |
5846 | |
5847 glBegin(GL_LINE_LOOP); | |
5848 | |
5849 /* coordinates are: cos(degrees * 11.25) = x, sin(degrees*11.25) = y, 0.
0f = z */ | |
5850 for (degrees = 0; degrees < CIRCLE_RESOL; degrees++) { | |
5851 x = cosval[degrees]; | |
5852 y = sinval[degrees]; | |
5853 ················ | |
5854 glVertex3f(x * size, 0.0f, y * size); | |
5855 } | |
5856 ········ | |
5857 glEnd(); | |
5858 | |
5859 } | |
5860 | |
5861 /* needs fixing if non-identity matrix used */ | |
5862 static void drawtube(const float vec[3], float radius, float height, float tmat[
4][4]) | |
5863 { | |
5864 float cur[3]; | |
5865 drawcircball(GL_LINE_LOOP, vec, radius, tmat); | |
5866 | |
5867 copy_v3_v3(cur, vec); | |
5868 cur[2] += height; | |
5869 | |
5870 drawcircball(GL_LINE_LOOP, cur, radius, tmat); | |
5871 | |
5872 glBegin(GL_LINES); | |
5873 glVertex3f(vec[0] + radius, vec[1], vec[2]); | |
5874 glVertex3f(cur[0] + radius, cur[1], cur[2]); | |
5875 glVertex3f(vec[0] - radius, vec[1], vec[2]); | |
5876 glVertex3f(cur[0] - radius, cur[1], cur[2]); | |
5877 glVertex3f(vec[0], vec[1] + radius, vec[2]); | |
5878 glVertex3f(cur[0], cur[1] + radius, cur[2]); | |
5879 glVertex3f(vec[0], vec[1] - radius, vec[2]); | |
5880 glVertex3f(cur[0], cur[1] - radius, cur[2]); | |
5881 glEnd(); | |
5882 } | |
5883 | |
5884 /* needs fixing if non-identity matrix used */ | |
5885 static void drawcone(const float vec[3], float radius, float height, float tmat[
4][4]) | |
5886 { | |
5887 float cur[3]; | |
5888 | |
5889 copy_v3_v3(cur, vec); | |
5890 cur[2] += height; | |
5891 | |
5892 drawcircball(GL_LINE_LOOP, cur, radius, tmat); | |
5893 | |
5894 glBegin(GL_LINES); | |
5895 glVertex3f(vec[0], vec[1], vec[2]); | |
5896 glVertex3f(cur[0] + radius, cur[1], cur[2]); | |
5897 glVertex3f(vec[0], vec[1], vec[2]); | |
5898 glVertex3f(cur[0] - radius, cur[1], cur[2]); | |
5899 glVertex3f(vec[0], vec[1], vec[2]); | |
5900 glVertex3f(cur[0], cur[1] + radius, cur[2]); | |
5901 glVertex3f(vec[0], vec[1], vec[2]); | |
5902 glVertex3f(cur[0], cur[1] - radius, cur[2]); | |
5903 glEnd(); | |
5904 } | |
5905 | |
5906 /* return true if nothing was drawn */ | |
5907 static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, | |
5908 const char dt, const short dflag, const unsigned char ob_w
ire_col[4]) | |
5909 { | |
5910 Object *ob = base->object; | |
5911 MetaBall *mb; | |
5912 MetaElem *ml; | |
5913 float imat[4][4]; | |
5914 int code = 1; | |
5915 ········ | |
5916 mb = ob->data; | |
5917 | |
5918 if (mb->editelems) { | |
5919 if ((G.f & G_PICKSEL) == 0) { | |
5920 unsigned char wire_col[4]; | |
5921 UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col); | |
5922 glColor3ubv(wire_col); | |
5923 | |
5924 drawDispList(scene, v3d, rv3d, base, dt, dflag, wire_col
); | |
5925 } | |
5926 ml = mb->editelems->first; | |
5927 } | |
5928 else { | |
5929 if ((base->flag & OB_FROMDUPLI) == 0) { | |
5930 drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_
col); | |
5931 } | |
5932 ml = mb->elems.first; | |
5933 } | |
5934 | |
5935 if (ml == NULL) { | |
5936 return true; | |
5937 } | |
5938 | |
5939 if (v3d->flag2 & V3D_RENDER_OVERRIDE) { | |
5940 return false; | |
5941 } | |
5942 | |
5943 invert_m4_m4(imat, rv3d->viewmatob); | |
5944 normalize_v3(imat[0]); | |
5945 normalize_v3(imat[1]); | |
5946 | |
5947 if (mb->editelems == NULL) { | |
5948 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
5949 glColor3ubv(ob_wire_col); | |
5950 } | |
5951 } | |
5952 ········ | |
5953 while (ml) { | |
5954 /* draw radius */ | |
5955 if (mb->editelems) { | |
5956 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
5957 if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_
RAD)) cpack(0xA0A0F0); | |
5958 else cpack(0x3030A0); | |
5959 } | |
5960 ························ | |
5961 if (G.f & G_PICKSEL) { | |
5962 ml->selcol1 = code; | |
5963 glLoadName(code++); | |
5964 } | |
5965 } | |
5966 drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat); | |
5967 | |
5968 /* draw stiffness */ | |
5969 if (mb->editelems) { | |
5970 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
5971 if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE
_RAD)) cpack(0xA0F0A0); | |
5972 else cpack(0x30A030); | |
5973 } | |
5974 ························ | |
5975 if (G.f & G_PICKSEL) { | |
5976 ml->selcol2 = code; | |
5977 glLoadName(code++); | |
5978 } | |
5979 drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad * atanf(ml-
>s) / (float)M_PI_2, imat); | |
5980 } | |
5981 ················ | |
5982 ml = ml->next; | |
5983 } | |
5984 return false; | |
5985 } | |
5986 | |
5987 static void draw_forcefield(Object *ob, RegionView3D *rv3d, | |
5988 const short dflag, const unsigned char ob_wire_col[4
]) | |
5989 { | |
5990 PartDeflect *pd = ob->pd; | |
5991 float imat[4][4], tmat[4][4]; | |
5992 float vec[3] = {0.0, 0.0, 0.0}; | |
5993 float size; | |
5994 ········ | |
5995 /* scale size of circle etc with the empty drawsize */ | |
5996 if (ob->type == OB_EMPTY) size = ob->empty_drawsize; | |
5997 else size = 1.0; | |
5998 ········ | |
5999 /* calculus here, is reused in PFIELD_FORCE */ | |
6000 invert_m4_m4(imat, rv3d->viewmatob); | |
6001 // normalize_v3(imat[0]); /* we don't do this because field doesnt scale e
ither... apart from wind! */ | |
6002 // normalize_v3(imat[1]); | |
6003 ········ | |
6004 if (pd->forcefield == PFIELD_WIND) { | |
6005 float force_val; | |
6006 | |
6007 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6008 ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f)
; | |
6009 } | |
6010 | |
6011 //if (has_ipo_code(ob->ipo, OB_PD_FSTR)) | |
6012 // force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, scene
->r.cfra); | |
6013 //else | |
6014 { | |
6015 force_val = pd->f_strength; | |
6016 } | |
6017 | |
6018 unit_m4(tmat); | |
6019 force_val *= 0.1f; | |
6020 drawcircball(GL_LINE_LOOP, vec, size, tmat); | |
6021 vec[2] = 0.5f * force_val; | |
6022 drawcircball(GL_LINE_LOOP, vec, size, tmat); | |
6023 vec[2] = 1.0f * force_val; | |
6024 drawcircball(GL_LINE_LOOP, vec, size, tmat); | |
6025 vec[2] = 1.5f * force_val; | |
6026 drawcircball(GL_LINE_LOOP, vec, size, tmat); | |
6027 vec[2] = 0.0f; /* reset vec for max dist circle */ | |
6028 ················ | |
6029 } | |
6030 else if (pd->forcefield == PFIELD_FORCE) { | |
6031 float ffall_val; | |
6032 | |
6033 //if (has_ipo_code(ob->ipo, OB_PD_FFALL)) | |
6034 // ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, scen
e->r.cfra); | |
6035 //else | |
6036 { | |
6037 ffall_val = pd->f_power; | |
6038 } | |
6039 | |
6040 if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id
(ob_wire_col, TH_BACK, 0.5f); | |
6041 drawcircball(GL_LINE_LOOP, vec, size, imat); | |
6042 if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id
(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val)); | |
6043 drawcircball(GL_LINE_LOOP, vec, size * 1.5f, imat); | |
6044 if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id
(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val)); | |
6045 drawcircball(GL_LINE_LOOP, vec, size * 2.0f, imat); | |
6046 } | |
6047 else if (pd->forcefield == PFIELD_VORTEX) { | |
6048 float /*ffall_val,*/ force_val; | |
6049 | |
6050 unit_m4(tmat); | |
6051 //if (has_ipo_code(ob->ipo, OB_PD_FFALL)) | |
6052 // ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, scen
e->r.cfra); | |
6053 //else | |
6054 // ffall_val = pd->f_power; | |
6055 | |
6056 //if (has_ipo_code(ob->ipo, OB_PD_FSTR)) | |
6057 // force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, scene
->r.cfra); | |
6058 //else | |
6059 { | |
6060 force_val = pd->f_strength; | |
6061 } | |
6062 | |
6063 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6064 ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f)
; | |
6065 } | |
6066 | |
6067 if (force_val < 0) { | |
6068 drawspiral(vec, size, tmat, 1); | |
6069 drawspiral(vec, size, tmat, 16); | |
6070 } | |
6071 else { | |
6072 drawspiral(vec, size, tmat, -1); | |
6073 drawspiral(vec, size, tmat, -16); | |
6074 } | |
6075 } | |
6076 else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) { | |
6077 Curve *cu = ob->data; | |
6078 if ((cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_c
ache->path->data) { | |
6079 float mindist, guidevec1[4], guidevec2[3]; | |
6080 | |
6081 //if (has_ipo_code(ob->ipo, OB_PD_FSTR)) | |
6082 // mindist = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR,
scene->r.cfra); | |
6083 //else | |
6084 { | |
6085 mindist = pd->f_strength; | |
6086 } | |
6087 | |
6088 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6089 ob_wire_color_blend_theme_id(ob_wire_col, TH_BAC
K, 0.5f); | |
6090 } | |
6091 | |
6092 /*path end*/ | |
6093 setlinestyle(3); | |
6094 where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL
, NULL); | |
6095 drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); | |
6096 | |
6097 /*path beginning*/ | |
6098 setlinestyle(0); | |
6099 where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL
, NULL); | |
6100 drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); | |
6101 ························ | |
6102 copy_v3_v3(vec, guidevec1); /* max center */ | |
6103 } | |
6104 } | |
6105 | |
6106 setlinestyle(3); | |
6107 | |
6108 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6109 ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f); | |
6110 } | |
6111 | |
6112 if (pd->falloff == PFIELD_FALL_SPHERE) { | |
6113 /* as last, guide curve alters it */ | |
6114 if (pd->flag & PFIELD_USEMAX) | |
6115 drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat); | |
6116 | |
6117 if (pd->flag & PFIELD_USEMIN) | |
6118 drawcircball(GL_LINE_LOOP, vec, pd->mindist, imat); | |
6119 } | |
6120 else if (pd->falloff == PFIELD_FALL_TUBE) { | |
6121 float radius, distance; | |
6122 | |
6123 unit_m4(tmat); | |
6124 | |
6125 vec[0] = vec[1] = 0.0f; | |
6126 radius = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f; | |
6127 distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; | |
6128 vec[2] = distance; | |
6129 distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distan
ce; | |
6130 | |
6131 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) | |
6132 drawtube(vec, radius, distance, tmat); | |
6133 | |
6134 radius = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f; | |
6135 distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; | |
6136 vec[2] = distance; | |
6137 distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distan
ce; | |
6138 | |
6139 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) | |
6140 drawtube(vec, radius, distance, tmat); | |
6141 } | |
6142 else if (pd->falloff == PFIELD_FALL_CONE) { | |
6143 float radius, distance; | |
6144 | |
6145 unit_m4(tmat); | |
6146 | |
6147 radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0
f); | |
6148 distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; | |
6149 | |
6150 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { | |
6151 drawcone(vec, distance * sinf(radius), distance * cosf(r
adius), tmat); | |
6152 if ((pd->flag & PFIELD_POSZ) == 0) | |
6153 drawcone(vec, distance * sinf(radius), -distance
* cosf(radius), tmat); | |
6154 } | |
6155 | |
6156 radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0
f); | |
6157 distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; | |
6158 | |
6159 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { | |
6160 drawcone(vec, distance * sinf(radius), distance * cosf(r
adius), tmat); | |
6161 if ((pd->flag & PFIELD_POSZ) == 0) | |
6162 drawcone(vec, distance * sinf(radius), -distance
* cosf(radius), tmat); | |
6163 } | |
6164 } | |
6165 setlinestyle(0); | |
6166 } | |
6167 | |
6168 static void draw_box(float vec[8][3]) | |
6169 { | |
6170 glBegin(GL_LINE_STRIP); | |
6171 glVertex3fv(vec[0]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); glVertex3
fv(vec[3]); | |
6172 glVertex3fv(vec[0]); glVertex3fv(vec[4]); glVertex3fv(vec[5]); glVertex3
fv(vec[6]); | |
6173 glVertex3fv(vec[7]); glVertex3fv(vec[4]); | |
6174 glEnd(); | |
6175 | |
6176 glBegin(GL_LINES); | |
6177 glVertex3fv(vec[1]); glVertex3fv(vec[5]); | |
6178 glVertex3fv(vec[2]); glVertex3fv(vec[6]); | |
6179 glVertex3fv(vec[3]); glVertex3fv(vec[7]); | |
6180 glEnd(); | |
6181 } | |
6182 | |
6183 /* uses boundbox, function used by Ketsji */ | |
6184 #if 0 | |
6185 static void get_local_bounds(Object *ob, float center[3], float size[3]) | |
6186 { | |
6187 BoundBox *bb = BKE_object_boundbox_get(ob); | |
6188 ········ | |
6189 if (bb == NULL) { | |
6190 zero_v3(center); | |
6191 copy_v3_v3(size, ob->size); | |
6192 } | |
6193 else { | |
6194 size[0] = 0.5 * fabsf(bb->vec[0][0] - bb->vec[4][0]); | |
6195 size[1] = 0.5 * fabsf(bb->vec[0][1] - bb->vec[2][1]); | |
6196 size[2] = 0.5 * fabsf(bb->vec[0][2] - bb->vec[1][2]); | |
6197 | |
6198 center[0] = (bb->vec[0][0] + bb->vec[4][0]) / 2.0; | |
6199 center[1] = (bb->vec[0][1] + bb->vec[2][1]) / 2.0; | |
6200 center[2] = (bb->vec[0][2] + bb->vec[1][2]) / 2.0; | |
6201 } | |
6202 } | |
6203 #endif | |
6204 | |
6205 static void draw_bb_quadric(BoundBox *bb, char type) | |
6206 { | |
6207 float size[3], cent[3]; | |
6208 GLUquadricObj *qobj = gluNewQuadric(); | |
6209 ········ | |
6210 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); | |
6211 ········ | |
6212 size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]); | |
6213 size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]); | |
6214 size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); | |
6215 | |
6216 cent[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]); | |
6217 cent[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]); | |
6218 cent[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]); | |
6219 ········ | |
6220 glPushMatrix(); | |
6221 if (type == OB_BOUND_SPHERE) { | |
6222 float scale = MAX3(size[0], size[1], size[2]); | |
6223 glTranslatef(cent[0], cent[1], cent[2]); | |
6224 glScalef(scale, scale, scale); | |
6225 gluSphere(qobj, 1.0, 8, 5); | |
6226 } | |
6227 else if (type == OB_BOUND_CYLINDER) { | |
6228 float radius = size[0] > size[1] ? size[0] : size[1]; | |
6229 glTranslatef(cent[0], cent[1], cent[2] - size[2]); | |
6230 glScalef(radius, radius, 2.0f * size[2]); | |
6231 gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1); | |
6232 } | |
6233 else if (type == OB_BOUND_CONE) { | |
6234 float radius = size[0] > size[1] ? size[0] : size[1]; | |
6235 glTranslatef(cent[0], cent[1], cent[2] - size[2]); | |
6236 glScalef(radius, radius, 2.0f * size[2]); | |
6237 gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1); | |
6238 } | |
6239 else if (type == OB_BOUND_CAPSULE) { | |
6240 float radius = size[0] > size[1] ? size[0] : size[1]; | |
6241 float length = size[2] > radius ? 2.0f * (size[2] - radius) : 0.
0f; | |
6242 glTranslatef(cent[0], cent[1], cent[2] - length * 0.5f); | |
6243 gluCylinder(qobj, radius, radius, length, 8, 1); | |
6244 gluSphere(qobj, radius, 8, 4); | |
6245 glTranslatef(0.0, 0.0, length); | |
6246 gluSphere(qobj, radius, 8, 4); | |
6247 } | |
6248 glPopMatrix(); | |
6249 ········ | |
6250 gluDeleteQuadric(qobj); | |
6251 } | |
6252 | |
6253 static void draw_bounding_volume(Scene *scene, Object *ob, char type) | |
6254 { | |
6255 BoundBox bb_local; | |
6256 BoundBox *bb = NULL; | |
6257 ········ | |
6258 if (ob->type == OB_MESH) { | |
6259 bb = BKE_mesh_boundbox_get(ob); | |
6260 } | |
6261 else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { | |
6262 bb = BKE_curve_boundbox_get(ob); | |
6263 } | |
6264 else if (ob->type == OB_MBALL) { | |
6265 if (BKE_mball_is_basis(ob)) { | |
6266 bb = ob->bb; | |
6267 if (bb == NULL) { | |
6268 BKE_displist_make_mball(scene, ob); | |
6269 bb = ob->bb; | |
6270 } | |
6271 } | |
6272 } | |
6273 else if (ob->type == OB_ARMATURE) { | |
6274 bb = BKE_armature_boundbox_get(ob); | |
6275 } | |
6276 else { | |
6277 const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f
, 1.0f}; | |
6278 bb = &bb_local; | |
6279 BKE_boundbox_init_from_minmax(bb, min, max); | |
6280 } | |
6281 ········ | |
6282 if (bb == NULL) return; | |
6283 ········ | |
6284 if (type == OB_BOUND_BOX) draw_box(bb->vec); | |
6285 else draw_bb_quadric(bb, type); | |
6286 ········ | |
6287 } | |
6288 | |
6289 static void drawtexspace(Object *ob) | |
6290 { | |
6291 float vec[8][3], loc[3], size[3]; | |
6292 ········ | |
6293 if (ob->type == OB_MESH) { | |
6294 BKE_mesh_texspace_get(ob->data, loc, NULL, size); | |
6295 } | |
6296 else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { | |
6297 BKE_curve_texspace_get(ob->data, loc, NULL, size); | |
6298 } | |
6299 else if (ob->type == OB_MBALL) { | |
6300 MetaBall *mb = ob->data; | |
6301 copy_v3_v3(size, mb->size); | |
6302 copy_v3_v3(loc, mb->loc); | |
6303 } | |
6304 else { | |
6305 return; | |
6306 } | |
6307 | |
6308 vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0]; | |
6309 vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0]; | |
6310 ········ | |
6311 vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = loc[1] - size[1]; | |
6312 vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = loc[1] + size[1]; | |
6313 | |
6314 vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = loc[2] - size[2]; | |
6315 vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = loc[2] + size[2]; | |
6316 ········ | |
6317 setlinestyle(2); | |
6318 | |
6319 draw_box(vec); | |
6320 | |
6321 setlinestyle(0); | |
6322 } | |
6323 | |
6324 /* draws wire outline */ | |
6325 static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, | |
6326 const unsigned char ob_wire_col[4]) | |
6327 { | |
6328 RegionView3D *rv3d = ar->regiondata; | |
6329 Object *ob = base->object; | |
6330 ········ | |
6331 glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); | |
6332 glDepthMask(0); | |
6333 ········ | |
6334 if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { | |
6335 DerivedMesh *dm = ob->derivedFinal; | |
6336 bool has_faces = false; | |
6337 | |
6338 if (dm) { | |
6339 has_faces = dm->getNumTessFaces(dm); | |
6340 } | |
6341 else { | |
6342 has_faces = BKE_displist_has_faces(&ob->curve_cache->dis
p); | |
6343 } | |
6344 | |
6345 if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb
)) { | |
6346 draw_index_wire = false; | |
6347 if (dm) { | |
6348 draw_mesh_object_outline(v3d, ob, dm); | |
6349 } | |
6350 else { | |
6351 drawDispListwire(&ob->curve_cache->disp); | |
6352 } | |
6353 draw_index_wire = true; | |
6354 } | |
6355 } | |
6356 else if (ob->type == OB_MBALL) { | |
6357 if (BKE_mball_is_basis(ob)) { | |
6358 if ((base->flag & OB_FROMDUPLI) == 0) | |
6359 drawDispListwire(&ob->curve_cache->disp); | |
6360 } | |
6361 } | |
6362 else if (ob->type == OB_ARMATURE) { | |
6363 if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) | |
6364 draw_armature(scene, v3d, ar, base, OB_WIRE, 0, ob_wire_
col, true); | |
6365 } | |
6366 | |
6367 glLineWidth(1.0); | |
6368 glDepthMask(1); | |
6369 } | |
6370 | |
6371 static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign
ed char ob_wire_col[4]) | |
6372 { | |
6373 if (ELEM4(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) { | |
6374 | |
6375 if (scene->obedit == ob) { | |
6376 UI_ThemeColor(TH_WIRE_EDIT); | |
6377 } | |
6378 else { | |
6379 glColor3ubv(ob_wire_col); | |
6380 } | |
6381 | |
6382 bglPolygonOffset(rv3d->dist, 1.0); | |
6383 glDepthMask(0); /* disable write in zbuffer, selected edge wire
s show better */ | |
6384 | |
6385 if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { | |
6386 if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { | |
6387 if (ob->type == OB_CURVE) | |
6388 draw_index_wire = false; | |
6389 | |
6390 if (ob->derivedFinal) { | |
6391 drawCurveDMWired(ob); | |
6392 } | |
6393 else { | |
6394 drawDispListwire(&ob->curve_cache->disp)
; | |
6395 } | |
6396 | |
6397 if (ob->type == OB_CURVE) | |
6398 draw_index_wire = true; | |
6399 } | |
6400 } | |
6401 else if (ob->type == OB_MBALL) { | |
6402 if (BKE_mball_is_basis(ob)) { | |
6403 drawDispListwire(&ob->curve_cache->disp); | |
6404 } | |
6405 } | |
6406 | |
6407 glDepthMask(1); | |
6408 bglPolygonOffset(rv3d->dist, 0.0); | |
6409 } | |
6410 } | |
6411 | |
6412 /* should be called in view space */ | |
6413 static void draw_hooks(Object *ob) | |
6414 { | |
6415 ModifierData *md; | |
6416 float vec[3]; | |
6417 ········ | |
6418 for (md = ob->modifiers.first; md; md = md->next) { | |
6419 if (md->type == eModifierType_Hook) { | |
6420 HookModifierData *hmd = (HookModifierData *) md; | |
6421 | |
6422 mul_v3_m4v3(vec, ob->obmat, hmd->cent); | |
6423 | |
6424 if (hmd->object) { | |
6425 setlinestyle(3); | |
6426 glBegin(GL_LINES); | |
6427 glVertex3fv(hmd->object->obmat[3]); | |
6428 glVertex3fv(vec); | |
6429 glEnd(); | |
6430 setlinestyle(0); | |
6431 } | |
6432 | |
6433 glPointSize(3.0); | |
6434 bglBegin(GL_POINTS); | |
6435 bglVertex3fv(vec); | |
6436 bglEnd(); | |
6437 glPointSize(1.0); | |
6438 } | |
6439 } | |
6440 } | |
6441 | |
6442 static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data, const short d
flag, unsigned char ob_wire_col[4]) | |
6443 { | |
6444 const char *axis_str[3] = {"px", "py", "pz"}; | |
6445 int axis; | |
6446 float mat[4][4]; | |
6447 | |
6448 eul_to_mat4(mat, &data->axX); | |
6449 glLineWidth(4.0f); | |
6450 setlinestyle(2); | |
6451 for (axis = 0; axis < 3; axis++) { | |
6452 float dir[3] = {0, 0, 0}; | |
6453 float v[3]; | |
6454 | |
6455 copy_v3_v3(v, &data->pivX); | |
6456 | |
6457 dir[axis] = 1.0f; | |
6458 glBegin(GL_LINES); | |
6459 mul_m4_v3(mat, dir); | |
6460 add_v3_v3(v, dir); | |
6461 glVertex3fv(&data->pivX); | |
6462 glVertex3fv(v); | |
6463 glEnd(); | |
6464 | |
6465 /* when const color is set wirecolor is NULL - we could get the
current color but | |
6466 * with selection and group instancing its not needed to draw th
e text */ | |
6467 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6468 view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CA
CHE_TEXT_ASCII, ob_wire_col); | |
6469 } | |
6470 } | |
6471 glLineWidth(1.0f); | |
6472 setlinestyle(0); | |
6473 } | |
6474 | |
6475 static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
wire_col[4]) | |
6476 { | |
6477 Object *ob = base->object; | |
6478 int colindex = 0; | |
6479 const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0; | |
6480 /* confusing logic here, there are 2 methods of setting the color | |
6481 * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. | |
6482 * | |
6483 * note: no theme yet for 'colindex' */ | |
6484 int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE; | |
6485 int theme_shade = 0; | |
6486 | |
6487 if ((scene->obedit == NULL) && | |
6488 (G.moving & G_TRANSFORM_OBJ) && | |
6489 (base->flag & (SELECT + BA_WAS_SEL))) | |
6490 { | |
6491 theme_id = TH_TRANSFORM; | |
6492 } | |
6493 else { | |
6494 /* Sets the 'colindex' */ | |
6495 if (ob->id.lib) { | |
6496 colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 2 : 1; | |
6497 } | |
6498 /* Sets the 'theme_id' or fallback to wire */ | |
6499 else { | |
6500 if (ob->flag & OB_FROMGROUP) { | |
6501 if (base->flag & (SELECT + BA_WAS_SEL)) { | |
6502 /* uses darker active color for non-acti
ve + selected*/ | |
6503 theme_id = TH_GROUP_ACTIVE; | |
6504 | |
6505 if (scene->basact != base) { | |
6506 theme_shade = -16; | |
6507 } | |
6508 } | |
6509 else { | |
6510 theme_id = TH_GROUP; | |
6511 } | |
6512 } | |
6513 else { | |
6514 if (base->flag & (SELECT + BA_WAS_SEL)) { | |
6515 theme_id = scene->basact == base ? TH_AC
TIVE : TH_SELECT; | |
6516 } | |
6517 else { | |
6518 if (ob->type == OB_LAMP) theme_id = TH_L
AMP; | |
6519 else if (ob->type == OB_SPEAKER) theme_i
d = TH_SPEAKER; | |
6520 else if (ob->type == OB_CAMERA) theme_id
= TH_CAMERA; | |
6521 else if (ob->type == OB_EMPTY) theme_id
= TH_EMPTY; | |
6522 /* fallback to TH_WIRE */ | |
6523 } | |
6524 } | |
6525 } | |
6526 } | |
6527 | |
6528 /* finally set the color */ | |
6529 if (colindex == 0) { | |
6530 if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_c
ol); | |
6531 else UI_GetThemeColorShade3ubv(theme_id, theme_
shade, r_ob_wire_col); | |
6532 } | |
6533 else { | |
6534 cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]); | |
6535 } | |
6536 | |
6537 /* no reason to use this but some functions take col[4] */ | |
6538 r_ob_wire_col[3] = 255; | |
6539 } | |
6540 | |
6541 static void draw_object_matcap_check(Scene *scene, View3D *v3d, Object *ob) | |
6542 { | |
6543 /* fixed rule, active object draws as matcap */ | |
6544 if (ob == OBACT) { | |
6545 if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB
_MODE_TEXTURE_PAINT)) | |
6546 return; | |
6547 ························ | |
6548 if (v3d->defmaterial == NULL) { | |
6549 extern Material defmaterial; | |
6550 ························ | |
6551 v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap
material"); | |
6552 *(v3d->defmaterial) = defmaterial; | |
6553 v3d->defmaterial->gpumaterial.first = v3d->defmaterial->
gpumaterial.last = NULL; | |
6554 v3d->defmaterial->preview = NULL; | |
6555 } | |
6556 /* first time users */ | |
6557 if (v3d->matcap_icon == 0) | |
6558 v3d->matcap_icon = ICON_MATCAP_01; | |
6559 ················ | |
6560 if (v3d->defmaterial->preview == NULL) | |
6561 v3d->defmaterial->preview = UI_icon_to_preview(v3d->matc
ap_icon); | |
6562 ················ | |
6563 /* signal to all material checks, gets cleared below */ | |
6564 v3d->flag2 |= V3D_SHOW_SOLID_MATCAP; | |
6565 } | |
6566 | |
6567 } | |
6568 | |
6569 /** | |
6570 * main object drawing function, draws in selection | |
6571 * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCE
NESET | |
6572 */ | |
6573 void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
dflag) | |
6574 { | |
6575 ModifierData *md = NULL; | |
6576 Object *ob = base->object; | |
6577 Curve *cu; | |
6578 RegionView3D *rv3d = ar->regiondata; | |
6579 float vec1[3], vec2[3]; | |
6580 unsigned int col = 0; | |
6581 unsigned char _ob_wire_col[4]; /* dont initialize this */ | |
6582 unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL cr
ashes as a way to find invalid use */ | |
6583 int i, selstart, selend, empty_object = 0; | |
6584 short dtx; | |
6585 char dt; | |
6586 short zbufoff = 0; | |
6587 const bool is_obact = (ob == OBACT); | |
6588 const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; | |
6589 bool particle_skip_object = false; /* Draw particles but not their emit
ter object. */ | |
6590 | |
6591 /* only once set now, will be removed too, should become a global standa
rd */ | |
6592 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
6593 | |
6594 if (ob != scene->obedit) { | |
6595 if (ob->restrictflag & OB_RESTRICT_VIEW) { | |
6596 return; | |
6597 } | |
6598 else if ((ob->restrictflag & OB_RESTRICT_RENDER) && render_overr
ide) { | |
6599 return; | |
6600 } | |
6601 } | |
6602 | |
6603 if (ob->particlesystem.first) { | |
6604 /* XXX particles are not safe for simultaneous threaded render *
/ | |
6605 if (G.is_rendering) { | |
6606 return; | |
6607 } | |
6608 | |
6609 if (ob->mode == OB_MODE_OBJECT) { | |
6610 ParticleSystem *psys; | |
6611 | |
6612 particle_skip_object = render_override; | |
6613 for (psys = ob->particlesystem.first; psys; psys = psys-
>next) { | |
6614 /* Once we have found a psys which renders its e
mitter object, we are done. */ | |
6615 if (psys->part->draw & PART_DRAW_EMITTER) { | |
6616 particle_skip_object = false; | |
6617 break; | |
6618 } | |
6619 } | |
6620 } | |
6621 } | |
6622 | |
6623 /* xray delay? */ | |
6624 if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (
v3d->flag2 & V3D_RENDER_SHADOW) == 0) { | |
6625 /* don't do xray in particle mode, need the z-buffer */ | |
6626 if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { | |
6627 /* xray and transp are set when it is drawing the 2nd/3r
d pass */ | |
6628 if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY
) && !(ob->dtx & OB_DRAWTRANSP)) { | |
6629 ED_view3d_after_add(&v3d->afterdraw_xray, base,
dflag); | |
6630 return; | |
6631 } | |
6632 | |
6633 /* allow transp option for empty images */ | |
6634 if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMP
TY_IMAGE) { | |
6635 if (!v3d->xray && !v3d->transp && !(ob->dtx & OB
_DRAWXRAY) && (ob->dtx & OB_DRAWTRANSP)) { | |
6636 ED_view3d_after_add(&v3d->afterdraw_tran
sp, base, dflag); | |
6637 return; | |
6638 } | |
6639 } | |
6640 } | |
6641 } | |
6642 | |
6643 /* no return after this point, otherwise leaks */ | |
6644 view3d_cached_text_draw_begin(); | |
6645 ········ | |
6646 /* draw motion paths (in view space) */ | |
6647 if (ob->mpath && !render_override) { | |
6648 bAnimVizSettings *avs = &ob->avs; | |
6649 ················ | |
6650 /* setup drawing environment for paths */ | |
6651 draw_motion_paths_init(v3d, ar); | |
6652 ················ | |
6653 /* draw motion path for object */ | |
6654 draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath); | |
6655 ················ | |
6656 /* cleanup after drawing */ | |
6657 draw_motion_paths_cleanup(v3d); | |
6658 } | |
6659 | |
6660 /* multiply view with object matrix. | |
6661 * local viewmat and persmat, to calculate projections */ | |
6662 ED_view3d_init_mats_rv3d_gl(ob, rv3d); | |
6663 | |
6664 /* which wire color */ | |
6665 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
6666 | |
6667 ED_view3d_project_base(ar, base); | |
6668 | |
6669 draw_object_wire_color(scene, base, _ob_wire_col); | |
6670 ob_wire_col = _ob_wire_col; | |
6671 | |
6672 glColor3ubv(ob_wire_col); | |
6673 } | |
6674 | |
6675 /* maximum drawtype */ | |
6676 dt = v3d->drawtype; | |
6677 if (dt == OB_RENDER) dt = OB_SOLID; | |
6678 dt = MIN2(dt, ob->dt); | |
6679 if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE; | |
6680 dtx = 0; | |
6681 ········ | |
6682 /* matcap check */ | |
6683 if (dt == OB_SOLID && (v3d->flag2 & V3D_SOLID_MATCAP)) | |
6684 draw_object_matcap_check(scene, v3d, ob); | |
6685 | |
6686 /* faceselect exception: also draw solid when (dt == wire), except in ed
itmode */ | |
6687 if (is_obact && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT
| OB_MODE_TEXTURE_PAINT))) { | |
6688 if (ob->type == OB_MESH) { | |
6689 if (dt < OB_SOLID) { | |
6690 zbufoff = 1; | |
6691 dt = OB_SOLID; | |
6692 } | |
6693 | |
6694 if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PA
INT)) { | |
6695 dt = OB_PAINT; | |
6696 } | |
6697 | |
6698 glEnable(GL_DEPTH_TEST); | |
6699 } | |
6700 else { | |
6701 if (dt < OB_SOLID) { | |
6702 dt = OB_SOLID; | |
6703 glEnable(GL_DEPTH_TEST); | |
6704 zbufoff = 1; | |
6705 } | |
6706 } | |
6707 } | |
6708 ········ | |
6709 /* draw-extra supported for boundbox drawmode too */ | |
6710 if (dt >= OB_BOUNDBOX) { | |
6711 dtx = ob->dtx; | |
6712 if (ob->mode & OB_MODE_EDIT) { | |
6713 // the only 2 extra drawtypes alowed in editmode | |
6714 dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE); | |
6715 } | |
6716 | |
6717 } | |
6718 | |
6719 if (!particle_skip_object) { | |
6720 /* bad exception, solve this! otherwise outline shows too late *
/ | |
6721 if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { | |
6722 /* still needed for curves hidden in other layers. depgr
aph doesnt handle that yet */ | |
6723 if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.fi
rst)) { | |
6724 BKE_displist_make_curveTypes(scene, ob, 0); | |
6725 } | |
6726 } | |
6727 ················ | |
6728 /* draw outline for selected objects, mesh does itself */ | |
6729 if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->
type != OB_MESH) { | |
6730 if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (d
flag & DRAW_SCENESET) == 0) { | |
6731 if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELE
CT) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { | |
6732 drawObjectSelect(scene, v3d, ar, base, o
b_wire_col); | |
6733 } | |
6734 } | |
6735 } | |
6736 | |
6737 switch (ob->type) { | |
6738 case OB_MESH: | |
6739 empty_object = draw_mesh_object(scene, ar, v3d,
rv3d, base, dt, ob_wire_col, dflag); | |
6740 if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIR
E; // mesh draws wire itself | |
6741 | |
6742 break; | |
6743 case OB_FONT: | |
6744 cu = ob->data; | |
6745 if (cu->editfont) { | |
6746 draw_textcurs(rv3d, cu->editfont->textcu
rs); | |
6747 | |
6748 if (cu->flag & CU_FAST) { | |
6749 cpack(0xFFFFFF); | |
6750 set_inverted_drawing(1); | |
6751 drawDispList(scene, v3d, rv3d, b
ase, OB_WIRE, dflag, ob_wire_col); | |
6752 set_inverted_drawing(0); | |
6753 } | |
6754 else { | |
6755 drawDispList(scene, v3d, rv3d, b
ase, dt, dflag, ob_wire_col); | |
6756 } | |
6757 | |
6758 if (cu->linewidth != 0.0f) { | |
6759 UI_ThemeColor(TH_WIRE_EDIT); | |
6760 copy_v3_v3(vec1, ob->orig); | |
6761 copy_v3_v3(vec2, ob->orig); | |
6762 vec1[0] += cu->linewidth; | |
6763 vec2[0] += cu->linewidth; | |
6764 vec1[1] += cu->linedist * cu->fs
ize; | |
6765 vec2[1] -= cu->lines * cu->lined
ist * cu->fsize; | |
6766 setlinestyle(3); | |
6767 glBegin(GL_LINE_STRIP); | |
6768 glVertex2fv(vec1); | |
6769 glVertex2fv(vec2); | |
6770 glEnd(); | |
6771 setlinestyle(0); | |
6772 } | |
6773 | |
6774 setlinestyle(3); | |
6775 for (i = 0; i < cu->totbox; i++) { | |
6776 if (cu->tb[i].w != 0.0f) { | |
6777 UI_ThemeColor(i == (cu->
actbox - 1) ? TH_ACTIVE : TH_WIRE); | |
6778 vec1[0] = (cu->xof * cu-
>fsize) + cu->tb[i].x; | |
6779 vec1[1] = (cu->yof * cu-
>fsize) + cu->tb[i].y + cu->fsize; | |
6780 vec1[2] = 0.001; | |
6781 glBegin(GL_LINE_STRIP); | |
6782 glVertex3fv(vec1); | |
6783 vec1[0] += cu->tb[i].w; | |
6784 glVertex3fv(vec1); | |
6785 vec1[1] -= cu->tb[i].h; | |
6786 glVertex3fv(vec1); | |
6787 vec1[0] -= cu->tb[i].w; | |
6788 glVertex3fv(vec1); | |
6789 vec1[1] += cu->tb[i].h; | |
6790 glVertex3fv(vec1); | |
6791 glEnd(); | |
6792 } | |
6793 } | |
6794 setlinestyle(0); | |
6795 | |
6796 | |
6797 if (BKE_vfont_select_get(ob, &selstart,
&selend) && cu->selboxes) { | |
6798 float selboxw; | |
6799 | |
6800 cpack(0xffffff); | |
6801 set_inverted_drawing(1); | |
6802 for (i = 0; i <= (selend - selst
art); i++) { | |
6803 SelBox *sb = &(cu->selbo
xes[i]); | |
6804 | |
6805 if (i < (selend - selsta
rt)) { | |
6806 if (cu->selboxes
[i + 1].y == sb->y) | |
6807 selboxw
= cu->selboxes[i + 1].x - sb->x; | |
6808 else | |
6809 selboxw
= sb->w; | |
6810 } | |
6811 else { | |
6812 selboxw = sb->w; | |
6813 } | |
6814 glBegin(GL_QUADS); | |
6815 glVertex3f(sb->x, sb->y,
0.001); | |
6816 glVertex3f(sb->x + selbo
xw, sb->y, 0.001); | |
6817 glVertex3f(sb->x + selbo
xw, sb->y + sb->h, 0.001); | |
6818 glVertex3f(sb->x, sb->y
+ sb->h, 0.001); | |
6819 glEnd(); | |
6820 } | |
6821 set_inverted_drawing(0); | |
6822 } | |
6823 } | |
6824 else if (dt == OB_BOUNDBOX) { | |
6825 if ((render_override && v3d->drawtype >=
OB_WIRE) == 0) { | |
6826 draw_bounding_volume(scene, ob,
ob->boundtype); | |
6827 } | |
6828 } | |
6829 else if (ED_view3d_boundbox_clip(rv3d, ob->obmat
, ob->bb)) { | |
6830 empty_object = drawDispList(scene, v3d,
rv3d, base, dt, dflag, ob_wire_col); | |
6831 } | |
6832 | |
6833 break; | |
6834 case OB_CURVE: | |
6835 case OB_SURF: | |
6836 cu = ob->data; | |
6837 | |
6838 if (cu->editnurb) { | |
6839 ListBase *nurbs = BKE_curve_editNurbs_ge
t(cu); | |
6840 drawnurb(scene, v3d, rv3d, base, nurbs->
first, dt, dflag, ob_wire_col); | |
6841 } | |
6842 else if (dt == OB_BOUNDBOX) { | |
6843 if ((render_override && (v3d->drawtype >
= OB_WIRE)) == 0) { | |
6844 draw_bounding_volume(scene, ob,
ob->boundtype); | |
6845 } | |
6846 } | |
6847 else if (ED_view3d_boundbox_clip(rv3d, ob->obmat
, ob->bb)) { | |
6848 empty_object = drawDispList(scene, v3d,
rv3d, base, dt, dflag, ob_wire_col); | |
6849 | |
6850 //XXX old animsys if (cu->path) | |
6851 // curve_draw_speed(scene, ob); | |
6852 } | |
6853 break; | |
6854 case OB_MBALL: | |
6855 { | |
6856 MetaBall *mb = ob->data; | |
6857 ································ | |
6858 if (mb->editelems) | |
6859 drawmball(scene, v3d, rv3d, base, dt, df
lag, ob_wire_col); | |
6860 else if (dt == OB_BOUNDBOX) { | |
6861 if ((render_override && (v3d->drawtype >
= OB_WIRE)) == 0) { | |
6862 draw_bounding_volume(scene, ob,
ob->boundtype); | |
6863 } | |
6864 } | |
6865 else | |
6866 empty_object = drawmball(scene, v3d, rv3
d, base, dt, dflag, ob_wire_col); | |
6867 break; | |
6868 } | |
6869 case OB_EMPTY: | |
6870 if (!render_override) { | |
6871 if (ob->empty_drawtype == OB_EMPTY_IMAGE
) { | |
6872 draw_empty_image(ob, dflag, ob_w
ire_col); | |
6873 } | |
6874 else { | |
6875 drawaxes(ob->empty_drawsize, ob-
>empty_drawtype); | |
6876 } | |
6877 } | |
6878 break; | |
6879 case OB_LAMP: | |
6880 if (!render_override) { | |
6881 drawlamp(scene, v3d, rv3d, base, dt, dfl
ag, ob_wire_col); | |
6882 } | |
6883 break; | |
6884 case OB_CAMERA: | |
6885 if (!render_override || | |
6886 (rv3d->persp == RV3D_CAMOB && v3d->camera ==
ob)) /* special exception for active camera */ | |
6887 { | |
6888 drawcamera(scene, v3d, rv3d, base, dflag
, ob_wire_col); | |
6889 } | |
6890 break; | |
6891 case OB_SPEAKER: | |
6892 if (!render_override) | |
6893 drawspeaker(scene, v3d, rv3d, ob, dflag)
; | |
6894 break; | |
6895 case OB_LATTICE: | |
6896 if (!render_override) { | |
6897 /* Do not allow boundbox in edit nor pos
e mode! */ | |
6898 if ((dt == OB_BOUNDBOX) && (ob->mode & O
B_MODE_EDIT)) | |
6899 dt = OB_WIRE; | |
6900 if (dt == OB_BOUNDBOX) { | |
6901 draw_bounding_volume(scene, ob,
ob->boundtype); | |
6902 } | |
6903 else { | |
6904 drawlattice(scene, v3d, ob); | |
6905 } | |
6906 } | |
6907 break; | |
6908 case OB_ARMATURE: | |
6909 if (!render_override) { | |
6910 /* Do not allow boundbox in edit nor pos
e mode! */ | |
6911 if ((dt == OB_BOUNDBOX) && (ob->mode & (
OB_MODE_EDIT | OB_MODE_POSE))) | |
6912 dt = OB_WIRE; | |
6913 if (dt == OB_BOUNDBOX) { | |
6914 draw_bounding_volume(scene, ob,
ob->boundtype); | |
6915 } | |
6916 else { | |
6917 if (dt > OB_WIRE) | |
6918 GPU_enable_material(0, N
ULL); /* we use default material */ | |
6919 empty_object = draw_armature(sce
ne, v3d, ar, base, dt, dflag, ob_wire_col, false); | |
6920 if (dt > OB_WIRE) | |
6921 GPU_disable_material(); | |
6922 } | |
6923 } | |
6924 break; | |
6925 default: | |
6926 if (!render_override) { | |
6927 drawaxes(1.0, OB_ARROWS); | |
6928 } | |
6929 break; | |
6930 } | |
6931 | |
6932 if (!render_override) { | |
6933 if (ob->soft /*&& dflag & OB_SBMOTION*/) { | |
6934 float mrt[3][3], msc[3][3], mtr[3][3]; | |
6935 SoftBody *sb = NULL; | |
6936 float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f; | |
6937 if ((sb = ob->soft)) { | |
6938 if (sb->solverflags & SBSO_ESTIMATEIPO)
{ | |
6939 | |
6940 glLoadMatrixf(rv3d->viewmat); | |
6941 copy_m3_m3(msc, sb->lscale); | |
6942 copy_m3_m3(mrt, sb->lrot); | |
6943 mul_m3_m3m3(mtr, mrt, msc); | |
6944 ob_draw_RE_motion(sb->lcom, mtr,
tipw, tiph, drawsize); | |
6945 glMultMatrixf(ob->obmat); | |
6946 } | |
6947 } | |
6948 } | |
6949 | |
6950 if (ob->pd && ob->pd->forcefield) { | |
6951 draw_forcefield(ob, rv3d, dflag, ob_wire_col); | |
6952 } | |
6953 } | |
6954 } | |
6955 | |
6956 /* code for new particle system */ | |
6957 if ((ob->particlesystem.first) && | |
6958 (ob != scene->obedit)) | |
6959 { | |
6960 ParticleSystem *psys; | |
6961 | |
6962 if (col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visib
ility, also while wpaint */ | |
6963 //glDepthMask(GL_FALSE); | |
6964 | |
6965 glLoadMatrixf(rv3d->viewmat); | |
6966 ················ | |
6967 view3d_cached_text_draw_begin(); | |
6968 | |
6969 for (psys = ob->particlesystem.first; psys; psys = psys->next) { | |
6970 /* run this so that possible child particles get cached
*/ | |
6971 if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { | |
6972 PTCacheEdit *edit = PE_create_current(scene, ob)
; | |
6973 if (edit && edit->psys == psys) | |
6974 draw_update_ptcache_edit(scene, ob, edit
); | |
6975 } | |
6976 | |
6977 draw_new_particle_system(scene, v3d, rv3d, base, psys, d
t); | |
6978 } | |
6979 invert_m4_m4(ob->imat, ob->obmat); | |
6980 view3d_cached_text_draw_end(v3d, ar, 0, NULL); | |
6981 | |
6982 glMultMatrixf(ob->obmat); | |
6983 ················ | |
6984 //glDepthMask(GL_TRUE); | |
6985 if (col) cpack(col); | |
6986 } | |
6987 | |
6988 /* draw edit particles last so that they can draw over child particles *
/ | |
6989 if ((dflag & DRAW_PICKING) == 0 && | |
6990 (!scene->obedit)) | |
6991 { | |
6992 | |
6993 if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { | |
6994 PTCacheEdit *edit = PE_create_current(scene, ob); | |
6995 if (edit) { | |
6996 glLoadMatrixf(rv3d->viewmat); | |
6997 draw_update_ptcache_edit(scene, ob, edit); | |
6998 draw_ptcache_edit(scene, v3d, edit); | |
6999 glMultMatrixf(ob->obmat); | |
7000 } | |
7001 } | |
7002 } | |
7003 | |
7004 /* draw code for smoke */ | |
7005 if ((md = modifiers_findByType(ob, eModifierType_Smoke))) { | |
7006 SmokeModifierData *smd = (SmokeModifierData *)md; | |
7007 | |
7008 // draw collision objects | |
7009 if ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) { | |
7010 #if 0 | |
7011 SmokeCollSettings *scs = smd->coll; | |
7012 if (scs->points) { | |
7013 size_t i; | |
7014 | |
7015 glLoadMatrixf(rv3d->viewmat); | |
7016 | |
7017 if (col || (ob->flag & SELECT)) cpack(0xFFFFFF); | |
7018 glDepthMask(GL_FALSE); | |
7019 glEnable(GL_BLEND); | |
7020 ································ | |
7021 | |
7022 // glPointSize(3.0); | |
7023 bglBegin(GL_POINTS); | |
7024 | |
7025 for (i = 0; i < scs->numpoints; i++) | |
7026 { | |
7027 bglVertex3fv(&scs->points[3 * i]); | |
7028 } | |
7029 | |
7030 bglEnd(); | |
7031 glPointSize(1.0); | |
7032 | |
7033 glMultMatrixf(ob->obmat); | |
7034 glDisable(GL_BLEND); | |
7035 glDepthMask(GL_TRUE); | |
7036 if (col) cpack(col); | |
7037 ································ | |
7038 } | |
7039 #endif | |
7040 } | |
7041 | |
7042 /* only draw domains */ | |
7043 if (smd->domain) { | |
7044 SmokeDomainSettings *sds = smd->domain; | |
7045 float p0[3], p1[3], viewnormal[3]; | |
7046 BoundBox bb; | |
7047 | |
7048 glLoadMatrixf(rv3d->viewmat); | |
7049 glMultMatrixf(ob->obmat); | |
7050 | |
7051 /* draw adaptive domain bounds */ | |
7052 if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { | |
7053 /* draw domain max bounds */ | |
7054 VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adap
t_res); | |
7055 VECADDFAC(p1, sds->p1, sds->cell_size, sds->adap
t_res); | |
7056 BKE_boundbox_init_from_minmax(&bb, p0, p1); | |
7057 draw_box(bb.vec); | |
7058 | |
7059 /* draw base resolution bounds */ | |
7060 #if 0 | |
7061 BKE_boundbox_init_from_minmax(&bb, sds->p0, sds-
>p1); | |
7062 draw_box(bb.vec); | |
7063 #endif | |
7064 } | |
7065 | |
7066 /* don't show smoke before simulation starts, this could
be made an option in the future */ | |
7067 if (smd->domain->fluid && CFRA >= smd->domain->point_cac
he[0]->startframe) { | |
7068 | |
7069 // get view vector | |
7070 copy_v3_v3(viewnormal, rv3d->viewinv[2]); | |
7071 invert_m4_m4(ob->imat, ob->obmat); | |
7072 mul_mat3_m4_v3(ob->imat, viewnormal); | |
7073 normalize_v3(viewnormal); | |
7074 | |
7075 /* set dynamic boundaries to draw the volume | |
7076 * also scale cube to global space to equalize v
olume slicing on all axises | |
7077 * (its scaled back before drawing) */ | |
7078 p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->r
es_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); | |
7079 p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->r
es_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); | |
7080 p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->r
es_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); | |
7081 p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->r
es_max[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); | |
7082 p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->r
es_max[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); | |
7083 p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->r
es_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); | |
7084 | |
7085 if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_
VIEW_SHOWBIG)) { | |
7086 smd->domain->tex = NULL; | |
7087 GPU_create_smoke(smd, 0); | |
7088 draw_smoke_volume(sds, ob, sds->tex, | |
7089 p0, p1, | |
7090 sds->res, sds->dx, sds
->scale * sds->maxres, | |
7091 viewnormal, sds->tex_s
hadow, sds->tex_flame); | |
7092 GPU_free_smoke(smd); | |
7093 } | |
7094 else if (sds->wt && (sds->viewsettings & MOD_SMO
KE_VIEW_SHOWBIG)) { | |
7095 sds->tex = NULL; | |
7096 GPU_create_smoke(smd, 1); | |
7097 draw_smoke_volume(sds, ob, sds->tex, | |
7098 p0, p1, | |
7099 sds->res_wt, sds->dx,
sds->scale * sds->maxres, | |
7100 viewnormal, sds->tex_s
hadow, sds->tex_flame); | |
7101 GPU_free_smoke(smd); | |
7102 } | |
7103 | |
7104 /* smoke debug render */ | |
7105 #ifdef SMOKE_DEBUG_VELOCITY | |
7106 draw_smoke_velocity(smd->domain, ob); | |
7107 #endif | |
7108 #ifdef SMOKE_DEBUG_HEAT | |
7109 draw_smoke_heat(smd->domain, ob); | |
7110 #endif | |
7111 } | |
7112 } | |
7113 } | |
7114 | |
7115 if (!render_override) { | |
7116 bConstraint *con; | |
7117 | |
7118 for (con = ob->constraints.first; con; con = con->next) { | |
7119 if (con->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) { | |
7120 bRigidBodyJointConstraint *data = (bRigidBodyJoi
ntConstraint *)con->data; | |
7121 if (data->flag & CONSTRAINT_DRAW_PIVOT) | |
7122 draw_rigid_body_pivot(data, dflag, ob_wi
re_col); | |
7123 } | |
7124 } | |
7125 | |
7126 if ((ob->gameflag & OB_BOUNDS) && (ob->mode == OB_MODE_OBJECT))
{ | |
7127 if (ob->boundtype != ob->collision_boundtype || (dtx & O
B_DRAWBOUNDOX) == 0) { | |
7128 setlinestyle(2); | |
7129 draw_bounding_volume(scene, ob, ob->collision_bo
undtype); | |
7130 setlinestyle(0); | |
7131 } | |
7132 } | |
7133 | |
7134 /* draw extra: after normal draw because of makeDispList */ | |
7135 if (dtx && (G.f & G_RENDER_OGL) == 0) { | |
7136 | |
7137 if (dtx & OB_AXIS) { | |
7138 drawaxes(1.0f, OB_ARROWS); | |
7139 } | |
7140 if (dtx & OB_DRAWBOUNDOX) { | |
7141 draw_bounding_volume(scene, ob, ob->boundtype); | |
7142 } | |
7143 if (dtx & OB_TEXSPACE) { | |
7144 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
7145 /* prevent random colors being used */ | |
7146 glColor3ubv(ob_wire_col); | |
7147 } | |
7148 drawtexspace(ob); | |
7149 } | |
7150 if (dtx & OB_DRAWNAME) { | |
7151 /* patch for several 3d cards (IBM mostly) that
crash on GL_SELECT with text drawing */ | |
7152 /* but, we also don't draw names for sets or dup
licators */ | |
7153 if (dflag == 0) { | |
7154 const float zero[3] = {0, 0, 0}; | |
7155 view3d_cached_text_draw_add(zero, ob->id
.name + 2, 10, 0, ob_wire_col); | |
7156 } | |
7157 } | |
7158 /*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ | |
7159 if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) { | |
7160 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
7161 draw_wire_extra(scene, rv3d, ob, ob_wire
_col); | |
7162 } | |
7163 } | |
7164 } | |
7165 } | |
7166 | |
7167 if ((dt <= OB_SOLID) && !render_override) { | |
7168 if (((ob->gameflag & OB_DYNAMIC) && | |
7169 !ELEM(ob->collision_boundtype, OB_BOUND_TRIANGLE_MESH, OB_B
OUND_CONVEX_HULL)) || | |
7170 | |
7171 ((ob->gameflag & OB_BOUNDS) && | |
7172 (ob->boundtype == OB_BOUND_SPHERE))) | |
7173 { | |
7174 float imat[4][4], vec[3] = {0.0f, 0.0f, 0.0f}; | |
7175 | |
7176 invert_m4_m4(imat, rv3d->viewmatob); | |
7177 | |
7178 if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
7179 /* prevent random colors being used */ | |
7180 glColor3ubv(ob_wire_col); | |
7181 } | |
7182 | |
7183 setlinestyle(2); | |
7184 drawcircball(GL_LINE_LOOP, vec, ob->inertia, imat); | |
7185 setlinestyle(0); | |
7186 } | |
7187 } | |
7188 ········ | |
7189 /* return warning, this is cached text draw */ | |
7190 invert_m4_m4(ob->imat, ob->obmat); | |
7191 view3d_cached_text_draw_end(v3d, ar, 1, NULL); | |
7192 /* return warning, clear temp flag */ | |
7193 v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP; | |
7194 ········ | |
7195 glLoadMatrixf(rv3d->viewmat); | |
7196 | |
7197 if (zbufoff) { | |
7198 glDisable(GL_DEPTH_TEST); | |
7199 } | |
7200 | |
7201 if ((base->flag & OB_FROMDUPLI) || render_override) { | |
7202 ED_view3d_clear_mats_rv3d(rv3d); | |
7203 return; | |
7204 } | |
7205 | |
7206 /* object centers, need to be drawn in viewmat space for speed, but OK f
or picking select */ | |
7207 if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { | |
7208 int do_draw_center = -1; /* defines below are zero or positive..
. */ | |
7209 | |
7210 if (render_override) { | |
7211 /* don't draw */ | |
7212 } | |
7213 else if ((scene->basact) == base) | |
7214 do_draw_center = ACTIVE; | |
7215 else if (base->flag & SELECT) | |
7216 do_draw_center = SELECT; | |
7217 else if (empty_object || (v3d->flag & V3D_DRAW_CENTERS)) | |
7218 do_draw_center = DESELECT; | |
7219 | |
7220 if (do_draw_center != -1) { | |
7221 if (dflag & DRAW_PICKING) { | |
7222 /* draw a single point for opengl selection */ | |
7223 glBegin(GL_POINTS); | |
7224 glVertex3fv(ob->obmat[3]); | |
7225 glEnd(); | |
7226 } | |
7227 else if ((dflag & DRAW_CONSTCOLOR) == 0) { | |
7228 /* we don't draw centers for duplicators and set
s */ | |
7229 if (U.obcenter_dia > 0) { | |
7230 /* check > 0 otherwise grease pencil can
draw into the circle select which is annoying. */ | |
7231 drawcentercircle(v3d, rv3d, ob->obmat[3]
, do_draw_center, ob->id.lib || ob->id.us > 1); | |
7232 } | |
7233 } | |
7234 } | |
7235 } | |
7236 | |
7237 /* not for sets, duplicators or picking */ | |
7238 if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && !render_overr
ide) { | |
7239 ListBase *list; | |
7240 RigidBodyCon *rbc = ob->rigidbody_constraint; | |
7241 ················ | |
7242 /* draw hook center and offset line */ | |
7243 if (ob != scene->obedit) | |
7244 draw_hooks(ob); | |
7245 | |
7246 /* help lines and so */ | |
7247 if (ob != scene->obedit && ob->parent && (ob->parent->lay & v3d-
>lay)) { | |
7248 setlinestyle(3); | |
7249 glBegin(GL_LINES); | |
7250 glVertex3fv(ob->obmat[3]); | |
7251 glVertex3fv(ob->orig); | |
7252 glEnd(); | |
7253 setlinestyle(0); | |
7254 } | |
7255 | |
7256 /* Drawing the constraint lines */ | |
7257 if (ob->constraints.first) { | |
7258 bConstraint *curcon; | |
7259 bConstraintOb *cob; | |
7260 unsigned char col1[4], col2[4]; | |
7261 ························ | |
7262 list = &ob->constraints; | |
7263 ························ | |
7264 UI_GetThemeColor3ubv(TH_GRID, col1); | |
7265 UI_make_axis_color(col1, col2, 'Z'); | |
7266 glColor3ubv(col2); | |
7267 ························ | |
7268 cob = BKE_constraints_make_evalob(scene, ob, NULL, CONST
RAINT_OBTYPE_OBJECT); | |
7269 ························ | |
7270 for (curcon = list->first; curcon; curcon = curcon->next
) { | |
7271 if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRA
CK, CONSTRAINT_TYPE_OBJECTSOLVER)) { | |
7272 /* special case for object solver and fo
llow track constraints because they don't fill | |
7273 * constraint targets properly (design l
imitation -- scene is needed for their target | |
7274 * but it can't be accessed from get_tar
gets callvack) */ | |
7275 | |
7276 Object *camob = NULL; | |
7277 | |
7278 if (curcon->type == CONSTRAINT_TYPE_FOLL
OWTRACK) { | |
7279 bFollowTrackConstraint *data = (
bFollowTrackConstraint *)curcon->data; | |
7280 | |
7281 camob = data->camera ? data->cam
era : scene->camera; | |
7282 } | |
7283 else if (curcon->type == CONSTRAINT_TYPE
_OBJECTSOLVER) { | |
7284 bObjectSolverConstraint *data =
(bObjectSolverConstraint *)curcon->data; | |
7285 | |
7286 camob = data->camera ? data->cam
era : scene->camera; | |
7287 } | |
7288 | |
7289 if (camob) { | |
7290 setlinestyle(3); | |
7291 glBegin(GL_LINES); | |
7292 glVertex3fv(camob->obmat[3]); | |
7293 glVertex3fv(ob->obmat[3]); | |
7294 glEnd(); | |
7295 setlinestyle(0); | |
7296 } | |
7297 } | |
7298 else { | |
7299 bConstraintTypeInfo *cti = BKE_constrain
t_get_typeinfo(curcon); | |
7300 | |
7301 if ((cti && cti->get_constraint_targets)
&& (curcon->flag & CONSTRAINT_EXPAND)) { | |
7302 ListBase targets = {NULL, NULL}; | |
7303 bConstraintTarget *ct; | |
7304 | |
7305 cti->get_constraint_targets(curc
on, &targets); | |
7306 | |
7307 for (ct = targets.first; ct; ct
= ct->next) { | |
7308 /* calculate target's ma
trix */ | |
7309 if (cti->get_target_matr
ix) | |
7310 cti->get_target_
matrix(curcon, cob, ct, BKE_scene_frame_get(scene)); | |
7311 else | |
7312 unit_m4(ct->matr
ix); | |
7313 | |
7314 setlinestyle(3); | |
7315 glBegin(GL_LINES); | |
7316 glVertex3fv(ct->matrix[3
]); | |
7317 glVertex3fv(ob->obmat[3]
); | |
7318 glEnd(); | |
7319 setlinestyle(0); | |
7320 } | |
7321 | |
7322 if (cti->flush_constraint_target
s) | |
7323 cti->flush_constraint_ta
rgets(curcon, &targets, 1); | |
7324 } | |
7325 } | |
7326 } | |
7327 ························ | |
7328 BKE_constraints_clear_evalob(cob); | |
7329 } | |
7330 /* draw rigid body constraint lines */ | |
7331 if (rbc) { | |
7332 UI_ThemeColor(TH_WIRE); | |
7333 setlinestyle(3); | |
7334 glBegin(GL_LINES); | |
7335 if (rbc->ob1) { | |
7336 glVertex3fv(ob->obmat[3]); | |
7337 glVertex3fv(rbc->ob1->obmat[3]); | |
7338 } | |
7339 if (rbc->ob2) { | |
7340 glVertex3fv(ob->obmat[3]); | |
7341 glVertex3fv(rbc->ob2->obmat[3]); | |
7342 } | |
7343 glEnd(); | |
7344 setlinestyle(0); | |
7345 } | |
7346 } | |
7347 | |
7348 free_old_images(); | |
7349 | |
7350 ED_view3d_clear_mats_rv3d(rv3d); | |
7351 } | |
7352 | |
7353 /* ***************** BACKBUF SEL (BBS) ********* */ | |
7354 | |
7355 static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const floa
t co[3], | |
7356 const float UNUSED(no_f[3]), const sh
ort UNUSED(no_s[3])) | |
7357 { | |
7358 bbsObmodeMeshVerts_userData *data = userData; | |
7359 MVert *mv = &data->mvert[index]; | |
7360 int offset = (intptr_t) data->offset; | |
7361 | |
7362 if (!(mv->flag & ME_HIDE)) { | |
7363 WM_framebuffer_index_set(offset + index); | |
7364 bglVertex3fv(co); | |
7365 } | |
7366 } | |
7367 | |
7368 static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) | |
7369 { | |
7370 bbsObmodeMeshVerts_userData data; | |
7371 Mesh *me = ob->data; | |
7372 MVert *mvert = me->mvert; | |
7373 data.mvert = mvert; | |
7374 data.offset = (void *)(intptr_t) offset; | |
7375 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); | |
7376 bglBegin(GL_POINTS); | |
7377 dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FORE
ACH_NOP); | |
7378 bglEnd(); | |
7379 glPointSize(1.0); | |
7380 } | |
7381 | |
7382 static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3]
, | |
7383 const float UNUSED(no_f[3]), const short UNU
SED(no_s[3])) | |
7384 { | |
7385 void **ptrs = userData; | |
7386 int offset = (intptr_t) ptrs[0]; | |
7387 BMVert *eve = BM_vert_at_index(ptrs[1], index); | |
7388 | |
7389 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { | |
7390 WM_framebuffer_index_set(offset + index); | |
7391 bglVertex3fv(co); | |
7392 } | |
7393 } | |
7394 static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) | |
7395 { | |
7396 void *ptrs[2] = {(void *)(intptr_t) offset, em->bm}; | |
7397 | |
7398 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); | |
7399 bglBegin(GL_POINTS); | |
7400 dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs, DM_FOREACH_NOP)
; | |
7401 bglEnd(); | |
7402 glPointSize(1.0); | |
7403 } | |
7404 | |
7405 static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) | |
7406 { | |
7407 void **ptrs = userData; | |
7408 int offset = (intptr_t) ptrs[0]; | |
7409 BMEdge *eed = BM_edge_at_index(ptrs[1], index); | |
7410 | |
7411 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | |
7412 WM_framebuffer_index_set(offset + index); | |
7413 return DM_DRAW_OPTION_NORMAL; | |
7414 } | |
7415 else { | |
7416 return DM_DRAW_OPTION_SKIP; | |
7417 } | |
7418 } | |
7419 static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) | |
7420 { | |
7421 void *ptrs[2] = {(void *)(intptr_t) offset, em->bm}; | |
7422 dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); | |
7423 } | |
7424 | |
7425 static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int inde
x) | |
7426 { | |
7427 BMFace *efa = BM_face_at_index(((void **)userData)[0], index); | |
7428 ········ | |
7429 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
7430 if (((void **)userData)[1]) { | |
7431 WM_framebuffer_index_set(index + 1); | |
7432 } | |
7433 return DM_DRAW_OPTION_NORMAL; | |
7434 } | |
7435 else { | |
7436 return DM_DRAW_OPTION_SKIP; | |
7437 } | |
7438 } | |
7439 | |
7440 static void bbs_mesh_solid__drawCenter(void *userData, int index, const float ce
nt[3], const float UNUSED(no[3])) | |
7441 { | |
7442 BMFace *efa = BM_face_at_index(((void **)userData)[0], index); | |
7443 | |
7444 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { | |
7445 WM_framebuffer_index_set(index + 1); | |
7446 | |
7447 bglVertex3fv(cent); | |
7448 } | |
7449 } | |
7450 | |
7451 /* two options, facecolors or black */ | |
7452 static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, | |
7453 Object *ob, DerivedMesh *dm, int facecol) | |
7454 { | |
7455 void *ptrs[2] = {em->bm, NULL}; //second one being null means to draw bl
ack | |
7456 cpack(0); | |
7457 | |
7458 if (facecol) { | |
7459 ptrs[1] = (void *)(intptr_t) 1; | |
7460 dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU
_enable_material, NULL, ptrs, 0); | |
7461 | |
7462 if (check_ob_drawface_dot(scene, v3d, ob->dt)) { | |
7463 glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); | |
7464 | |
7465 bglBegin(GL_POINTS); | |
7466 dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCent
er, ptrs, DM_FOREACH_NOP); | |
7467 bglEnd(); | |
7468 } | |
7469 | |
7470 } | |
7471 else { | |
7472 dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU
_enable_material, NULL, ptrs, 0); | |
7473 } | |
7474 } | |
7475 | |
7476 static DMDrawOption bbs_mesh_solid__setDrawOpts(void *UNUSED(userData), int inde
x) | |
7477 { | |
7478 WM_framebuffer_index_set(index + 1); | |
7479 return DM_DRAW_OPTION_NORMAL; | |
7480 } | |
7481 | |
7482 static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index) | |
7483 { | |
7484 Mesh *me = userData; | |
7485 | |
7486 if (!(me->mpoly[index].flag & ME_HIDE)) { | |
7487 WM_framebuffer_index_set(index + 1); | |
7488 return DM_DRAW_OPTION_NORMAL; | |
7489 } | |
7490 else { | |
7491 return DM_DRAW_OPTION_SKIP; | |
7492 } | |
7493 } | |
7494 | |
7495 /* must have called WM_framebuffer_index_set beforehand */ | |
7496 static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index) | |
7497 { | |
7498 Mesh *me = userData; | |
7499 | |
7500 if (!(me->mpoly[index].flag & ME_HIDE)) { | |
7501 return DM_DRAW_OPTION_NORMAL; | |
7502 } | |
7503 else { | |
7504 return DM_DRAW_OPTION_SKIP; | |
7505 } | |
7506 } | |
7507 | |
7508 static void bbs_mesh_solid_verts(Scene *scene, Object *ob) | |
7509 { | |
7510 Mesh *me = ob->data; | |
7511 DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_ma
sk); | |
7512 glColor3ub(0, 0, 0); | |
7513 | |
7514 dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_ma
terial, NULL, me, 0); | |
7515 | |
7516 bbs_obmode_mesh_verts(ob, dm, 1); | |
7517 bm_vertoffs = me->totvert + 1; | |
7518 dm->release(dm); | |
7519 } | |
7520 | |
7521 static void bbs_mesh_solid_faces(Scene *scene, Object *ob) | |
7522 { | |
7523 DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_ma
sk); | |
7524 Mesh *me = (Mesh *)ob->data; | |
7525 ········ | |
7526 glColor3ub(0, 0, 0); | |
7527 | |
7528 if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) | |
7529 dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, GPU_en
able_material, NULL, me, 0); | |
7530 else | |
7531 dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, GPU_enable_
material, NULL, me, 0); | |
7532 | |
7533 dm->release(dm); | |
7534 } | |
7535 | |
7536 void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
t *ob) | |
7537 { | |
7538 ToolSettings *ts = scene->toolsettings; | |
7539 | |
7540 glMultMatrixf(ob->obmat); | |
7541 | |
7542 glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); | |
7543 glEnable(GL_DEPTH_TEST); | |
7544 | |
7545 switch (ob->type) { | |
7546 case OB_MESH: | |
7547 if (ob->mode & OB_MODE_EDIT) { | |
7548 Mesh *me = ob->data; | |
7549 BMEditMesh *em = me->edit_btmesh; | |
7550 | |
7551 DerivedMesh *dm = editbmesh_get_derived_cage(sce
ne, ob, em, CD_MASK_BAREMESH); | |
7552 | |
7553 BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_E
DGE | BM_FACE); | |
7554 | |
7555 bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->se
lectmode & SCE_SELECT_FACE); | |
7556 if (ts->selectmode & SCE_SELECT_FACE) | |
7557 bm_solidoffs = 1 + em->bm->totface; | |
7558 else | |
7559 bm_solidoffs = 1; | |
7560 | |
7561 bglPolygonOffset(rv3d->dist, 1.0); | |
7562 | |
7563 /* we draw edges always, for loop (select) tools
*/ | |
7564 bbs_mesh_wire(em, dm, bm_solidoffs); | |
7565 bm_wireoffs = bm_solidoffs + em->bm->totedge; | |
7566 | |
7567 /* we draw verts if vert select mode or if in tr
ansform (for snap). */ | |
7568 if ((ts->selectmode & SCE_SELECT_VERTEX) || (G.m
oving & G_TRANSFORM_EDIT)) { | |
7569 bbs_mesh_verts(em, dm, bm_wireoffs); | |
7570 bm_vertoffs = bm_wireoffs + em->bm->totv
ert; | |
7571 } | |
7572 else { | |
7573 bm_vertoffs = bm_wireoffs; | |
7574 } | |
7575 | |
7576 bglPolygonOffset(rv3d->dist, 0.0); | |
7577 | |
7578 dm->release(dm); | |
7579 } | |
7580 else { | |
7581 Mesh *me = ob->data; | |
7582 if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && | |
7583 /* currently vertex select only supports wei
ght paint */ | |
7584 (ob->mode & OB_MODE_WEIGHT_PAINT)) | |
7585 { | |
7586 bbs_mesh_solid_verts(scene, ob); | |
7587 } | |
7588 else { | |
7589 bbs_mesh_solid_faces(scene, ob); | |
7590 } | |
7591 } | |
7592 break; | |
7593 case OB_CURVE: | |
7594 case OB_SURF: | |
7595 break; | |
7596 } | |
7597 | |
7598 glLoadMatrixf(rv3d->viewmat); | |
7599 } | |
7600 | |
7601 | |
7602 /* ************* draw object instances for bones, for example ******************
*/ | |
7603 /* assumes all matrices/etc set OK */ | |
7604 | |
7605 /* helper function for drawing object instances - meshes */ | |
7606 static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
v3d, | |
7607 Object *ob, const short dt, int outline) | |
7608 { | |
7609 Mesh *me = ob->data; | |
7610 DerivedMesh *dm = NULL, *edm = NULL; | |
7611 int glsl; | |
7612 ········ | |
7613 if (ob->mode & OB_MODE_EDIT) | |
7614 edm = editbmesh_get_derived_base(ob, me->edit_btmesh); | |
7615 else | |
7616 dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); | |
7617 | |
7618 if (dt <= OB_WIRE) { | |
7619 if (dm) | |
7620 dm->drawEdges(dm, 1, 0); | |
7621 else if (edm) | |
7622 edm->drawEdges(edm, 1, 0); | |
7623 } | |
7624 else { | |
7625 if (outline) | |
7626 draw_mesh_object_outline(v3d, ob, dm ? dm : edm); | |
7627 | |
7628 if (dm) { | |
7629 glsl = draw_glsl_material(scene, ob, v3d, dt); | |
7630 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, N
ULL); | |
7631 } | |
7632 else { | |
7633 glEnable(GL_COLOR_MATERIAL); | |
7634 UI_ThemeColor(TH_BONE_SOLID); | |
7635 glDisable(GL_COLOR_MATERIAL); | |
7636 } | |
7637 ················ | |
7638 glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); | |
7639 glEnable(GL_LIGHTING); | |
7640 ················ | |
7641 if (dm) { | |
7642 dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); | |
7643 GPU_end_object_materials(); | |
7644 } | |
7645 else if (edm) | |
7646 edm->drawMappedFaces(edm, NULL, GPU_enable_material, NUL
L, NULL, 0); | |
7647 ················ | |
7648 glDisable(GL_LIGHTING); | |
7649 } | |
7650 | |
7651 if (edm) edm->release(edm); | |
7652 if (dm) dm->release(dm); | |
7653 } | |
7654 | |
7655 void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
*ob, const char dt, int outline) | |
7656 { | |
7657 if (ob == NULL) | |
7658 return; | |
7659 | |
7660 switch (ob->type) { | |
7661 case OB_MESH: | |
7662 draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outl
ine); | |
7663 break; | |
7664 case OB_EMPTY: | |
7665 if (ob->empty_drawtype == OB_EMPTY_IMAGE) { | |
7666 /* CONSTCOLOR == no wire outline */ | |
7667 draw_empty_image(ob, DRAW_CONSTCOLOR, NULL); | |
7668 } | |
7669 else { | |
7670 drawaxes(ob->empty_drawsize, ob->empty_drawtype)
; | |
7671 } | |
7672 break; | |
7673 } | |
7674 } | |
LEFT | RIGHT |