| 5 |  | #endif | 
| 6 |  |  | 
| 7 |  | /* | 
| 8 | < | * Routines for loading and displaying Radiance objects under OpenGL in rholo. | 
| 8 | > | * Routines for loading and displaying Radiance objects in rholo with GLX. | 
| 9 |  | */ | 
| 10 |  |  | 
| 11 |  | #include "radogl.h" | 
| 22 |  |  | 
| 23 |  | #define AVGREFL         0.5             /* assumed average reflectance */ | 
| 24 |  |  | 
| 25 | < | #define MAXAC           64              /* maximum number of args */ | 
| 25 | > | #define MAXAC           512             /* maximum number of args */ | 
| 26 |  |  | 
| 27 |  | #ifndef MINTHRESH | 
| 28 |  | #define MINTHRESH       5.0             /* source threshold w.r.t. mean */ | 
| 320 |  | continue;               /* too dim */ | 
| 321 |  | ssph_direc(v, alt, azi);        /* else add it in */ | 
| 322 |  | VSUM(ls->direc, ls->direc, v, d); | 
| 323 | < | ls->omega++; | 
| 323 | > | ls->omega += 1.; | 
| 324 |  | addcolor(ls->val, ssamp[alt][azi].val); | 
| 325 | + | /* remove from list */ | 
| 326 |  | setcolor(ssamp[alt][azi].val, 0., 0., 0.); | 
| 327 | + | ssamp[alt][azi].nsamp = 0; | 
| 328 |  | } | 
| 329 |  | d = 1./ls->omega;                       /* avg. brightness */ | 
| 330 |  | scalecolor(ls->val, d); | 
| 416 |  | } | 
| 417 |  |  | 
| 418 |  |  | 
| 419 | < | static int | 
| 419 | > | static | 
| 420 |  | cmderror(cn, err)               /* report command error */ | 
| 421 |  | int     cn; | 
| 422 |  | char    *err; | 
| 423 |  | { | 
| 424 |  | sprintf(errmsg, "%s: %s", rhdcmd[cn], err); | 
| 425 |  | error(COMMAND, errmsg); | 
| 424 | – | return(cn); | 
| 426 |  | } | 
| 427 |  |  | 
| 428 |  |  | 
| 431 |  | char    *cmd; | 
| 432 |  | register char   *args; | 
| 433 |  | { | 
| 434 | + | int     somechange = 0; | 
| 435 |  | int     cn, na, doxfm; | 
| 436 |  | register int    nn; | 
| 437 |  | char    *alist[MAXAC+1], *nm; | 
| 459 |  | dobj_load(alist[0], alist[0]); | 
| 460 |  | else if (na == 2) | 
| 461 |  | dobj_load(alist[0], alist[1]); | 
| 462 | < | else | 
| 463 | < | return(cmderror(cn, "need octree [name]")); | 
| 462 | > | else { | 
| 463 | > | cmderror(cn, "need octree [name]"); | 
| 464 | > | return(0); | 
| 465 | > | } | 
| 466 |  | break; | 
| 467 | < | case DO_UNLOAD:                         /* unload an object */ | 
| 467 | > | case DO_UNLOAD:                         /* clear an object */ | 
| 468 |  | if (na > 1) goto toomany; | 
| 469 |  | if (na && alist[0][0] == '*') | 
| 470 | < | dobj_cleanup(); | 
| 470 | > | somechange += dobj_cleanup(); | 
| 471 |  | else | 
| 472 | < | dobj_unload(na ? alist[0] : curname); | 
| 472 | > | somechange += dobj_unload(na ? alist[0] : curname); | 
| 473 |  | break; | 
| 474 |  | case DO_XFORM:                          /* transform object */ | 
| 475 |  | case DO_MOVE: | 
| 478 |  | } else { | 
| 479 |  | nm = curname; nn = 0; | 
| 480 |  | } | 
| 481 | < | if (cn == DO_MOVE && nn >= na) | 
| 482 | < | return(cmderror(cn, "missing transform")); | 
| 483 | < | dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); | 
| 481 | > | if (cn == DO_MOVE && nn >= na) { | 
| 482 | > | cmderror(cn, "missing transform"); | 
| 483 | > | return(0); | 
| 484 | > | } | 
| 485 | > | somechange += dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); | 
| 486 |  | break; | 
| 487 |  | case DO_UNMOVE:                         /* undo last transform */ | 
| 488 | < | dobj_unmove(); | 
| 488 | > | somechange += dobj_unmove(); | 
| 489 |  | break; | 
| 490 |  | case DO_OBJECT:                         /* print object statistics */ | 
| 491 |  | if (dobj_putstats(na ? alist[0] : curname, sstdout)) | 
| 492 | < | if (na && alist[0][0] != '*' && | 
| 493 | < | strcmp(alist[0], curname)) | 
| 492 | > | if (na && alist[0][0] != '*' && (curobj == NULL || | 
| 493 | > | strcmp(alist[0], curobj->name))) | 
| 494 |  | savedxf(curobj = getdobj(alist[0])); | 
| 495 |  | break; | 
| 496 |  | case DO_DUP:                            /* duplicate object */ | 
| 499 |  | break; | 
| 500 |  | switch (nn) { | 
| 501 |  | case 0: | 
| 502 | < | return(cmderror(cn, "need new object name")); | 
| 502 | > | cmderror(cn, "need new object name"); | 
| 503 | > | return(0); | 
| 504 |  | case 1: | 
| 505 |  | nm = curname; | 
| 506 |  | break; | 
| 513 |  | if (!dobj_dup(nm, alist[nn-1])) | 
| 514 |  | break; | 
| 515 |  | if (na > nn) | 
| 516 | < | dobj_xform(curname, 1, na-nn, alist+nn); | 
| 516 | > | somechange += dobj_xform(curname, 1, na-nn, alist+nn); | 
| 517 |  | else | 
| 518 |  | curobj->drawcode = DO_HIDE; | 
| 519 |  | savedxf(curobj); | 
| 523 |  | case DO_HIDE: | 
| 524 |  | if (na > 1) goto toomany; | 
| 525 |  | dobj_lighting(na ? alist[0] : curname, cn); | 
| 526 | + | somechange++; | 
| 527 |  | break; | 
| 528 |  | default: | 
| 529 |  | error(CONSISTENCY, "bad command id in dobj_command"); | 
| 530 |  | } | 
| 531 | < | dev_view(&odev.v);                      /* redraw */ | 
| 524 | < | return(cn); | 
| 531 | > | return(somechange); | 
| 532 |  | toomany: | 
| 533 |  | return(cmderror(cn, "too many arguments")); | 
| 534 |  | } | 
| 554 |  | return(0); | 
| 555 |  | } | 
| 556 |  | if (getdobj(nam) != NULL) { | 
| 557 | < | error(COMMAND, "name already taken (unload first)"); | 
| 557 | > | error(COMMAND, "name already taken (clear first)"); | 
| 558 |  | return(0); | 
| 559 |  | } | 
| 560 |  | /* get octree path */ | 
| 576 |  | op->xfav[op->xfac=0] = NULL; | 
| 577 |  | /* load octree into display list */ | 
| 578 |  | dolights = 0; | 
| 579 | + | domats = 1; | 
| 580 |  | op->listid = rgl_octlist(fpath, op->center, &op->radius); | 
| 581 |  | /* start rtrace */ | 
| 582 |  | rtargv[RTARGC-1] = fpath; | 
| 620 |  | } | 
| 621 |  |  | 
| 622 |  |  | 
| 623 | < | dobj_xform(nam, add, ac, av)            /* set/add transform for nam */ | 
| 623 | > | dobj_xform(nam, rel, ac, av)            /* set/add transform for nam */ | 
| 624 |  | char    *nam; | 
| 625 | < | int     add, ac; | 
| 625 | > | int     rel, ac; | 
| 626 |  | char    **av; | 
| 627 |  | { | 
| 628 |  | register DOBJECT        *op; | 
| 629 | + | FVECT   cent; | 
| 630 | + | double  rad; | 
| 631 | + | char    scoord[16]; | 
| 632 | + | int     i; | 
| 633 |  |  | 
| 634 |  | if ((op = getdobj(nam)) == NULL) { | 
| 635 |  | error(COMMAND, "no object"); | 
| 636 |  | return(0); | 
| 637 |  | } | 
| 638 | < | if (add) add = op->xfac; | 
| 639 | < | if (ac + add > MAXAC) { | 
| 638 | > | if (rel) | 
| 639 | > | rel = op->xfac + 8; | 
| 640 | > | if (ac + rel > MAXAC) { | 
| 641 |  | error(COMMAND, "too many transform arguments"); | 
| 642 |  | return(0); | 
| 643 |  | } | 
| 644 | < | savedxf(curobj = op); | 
| 645 | < | if (!add) | 
| 644 | > | savedxf(curobj = op);           /* remember current transform */ | 
| 645 | > | if (rel && ac == 4 && !strcmp(av[0], "-t")) | 
| 646 | > | rel = -1;                       /* don't move for translate */ | 
| 647 | > | else { | 
| 648 | > | getdcent(cent, op);             /* don't move if near orig. */ | 
| 649 | > | rad = getdrad(op); | 
| 650 | > | if (DOT(cent,cent) < rad*rad) | 
| 651 | > | rel = -1; | 
| 652 | > | } | 
| 653 | > | if (!rel) {                             /* remove old transform */ | 
| 654 |  | while (op->xfac) | 
| 655 |  | freestr(op->xfav[--op->xfac]); | 
| 656 | + | } else if (rel > 0) {                   /* relative move */ | 
| 657 | + | op->xfav[op->xfac++] = savestr("-t"); | 
| 658 | + | for (i = 0; i < 3; i++) { | 
| 659 | + | sprintf(scoord, "%.4e", -cent[i]); | 
| 660 | + | op->xfav[op->xfac++] = savestr(scoord); | 
| 661 | + | } | 
| 662 | + | } | 
| 663 |  | while (ac--) | 
| 664 |  | op->xfav[op->xfac++] = savestr(*av++); | 
| 665 | + | if (rel > 0) {                          /* move back */ | 
| 666 | + | op->xfav[op->xfac++] = savestr("-t"); | 
| 667 | + | for (i = 0; i < 3; i++) { | 
| 668 | + | sprintf(scoord, "%.4e", cent[i]); | 
| 669 | + | op->xfav[op->xfac++] = savestr(scoord); | 
| 670 | + | } | 
| 671 | + | } | 
| 672 |  | op->xfav[op->xfac] = NULL; | 
| 673 |  | if (fullxf(&op->xfb, op->xfac, op->xfav) != op->xfac) { | 
| 674 |  | error(COMMAND, "bad transform arguments"); | 
| 705 |  | return(0); | 
| 706 |  | } | 
| 707 |  | getdcent(ocent, op); | 
| 708 | < | fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name, | 
| 708 | > | fprintf(fp, "%s: %s, center [%g %g %g], radius %g", op->name, | 
| 709 |  | op->drawcode==DO_HIDE ? "hidden" : | 
| 710 |  | op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" : | 
| 711 |  | "shown", | 
| 767 |  | return(0); | 
| 768 |  | } | 
| 769 |  | if (getdobj(nam) != NULL) { | 
| 770 | < | error(COMMAND, "name already taken (unload first)"); | 
| 770 | > | error(COMMAND, "name already taken (clear first)"); | 
| 771 |  | return(0); | 
| 772 |  | } | 
| 773 |  | /* allocate and copy struct */ | 
| 872 |  | } | 
| 873 |  |  | 
| 874 |  |  | 
| 875 | + | int | 
| 876 |  | dobj_render()                   /* render our objects in OpenGL */ | 
| 877 |  | { | 
| 878 | + | int     nrendered = 0; | 
| 879 |  | GLboolean       normalizing; | 
| 880 |  | GLfloat vec[4]; | 
| 881 |  | FVECT   v1; | 
| 886 |  | if (op->drawcode != DO_HIDE) | 
| 887 |  | break; | 
| 888 |  | if (op == NULL) | 
| 889 | < | return(1); | 
| 889 | > | return(0); | 
| 890 |  | /* set up general rendering params */ | 
| 891 |  | glGetBooleanv(GL_NORMALIZE, &normalizing); | 
| 892 |  | glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT| | 
| 972 |  | } | 
| 973 |  | /* render the display list */ | 
| 974 |  | glCallList(op->listid); | 
| 975 | + | nrendered++; | 
| 976 |  | /* restore matrix */ | 
| 977 |  | if (op->xfac) { | 
| 978 |  | glMatrixMode(GL_MODELVIEW); | 
| 990 |  | } | 
| 991 |  | glPopAttrib();                  /* restore rendering params */ | 
| 992 |  | rgl_checkerr("rendering objects in dobj_render"); | 
| 993 | < | return(1); | 
| 993 | > | return(nrendered); | 
| 994 |  | } |