| 1 | 
– | 
/* Copyright (c) 1998 Silicon Graphics, Inc. */ | 
| 2 | 
– | 
 | 
| 1 | 
  | 
#ifndef lint | 
| 2 | 
< | 
static char SCCSid[] = "$SunId$ SGI"; | 
| 2 | 
> | 
static const char       RCSid[] = "$Id$"; | 
| 3 | 
  | 
#endif | 
| 6 | 
– | 
 | 
| 4 | 
  | 
/* | 
| 5 | 
  | 
 * Routines for loading and displaying Radiance objects in rholo with GLX. | 
| 6 | 
  | 
 */ | 
| 19 | 
  | 
 | 
| 20 | 
  | 
#define AVGREFL         0.5             /* assumed average reflectance */ | 
| 21 | 
  | 
 | 
| 22 | 
< | 
#define MAXAC           64              /* maximum number of args */ | 
| 22 | 
> | 
#define MAXAC           512             /* maximum number of args */ | 
| 23 | 
  | 
 | 
| 24 | 
  | 
#ifndef MINTHRESH | 
| 25 | 
  | 
#define MINTHRESH       5.0             /* source threshold w.r.t. mean */ | 
| 52 | 
  | 
        FVECT   center;                 /* orig. object center */ | 
| 53 | 
  | 
        FLOAT   radius;                 /* orig. object radius */ | 
| 54 | 
  | 
        int     listid;                 /* GL display list identifier */ | 
| 55 | 
+ | 
        int     nlists;                 /* number of lists allocated */ | 
| 56 | 
  | 
        int     rtp[3];                 /* associated rtrace process */ | 
| 57 | 
  | 
        DLIGHTS *ol;                    /* object lights */ | 
| 58 | 
  | 
        FULLXF  xfb;                    /* coordinate transform */ | 
| 117 | 
  | 
        } | 
| 118 | 
  | 
        dobjects = ohead.next; | 
| 119 | 
  | 
        if (!foundlink) { | 
| 120 | 
< | 
                glDeleteLists(op->listid, 1); | 
| 120 | 
> | 
                glDeleteLists(op->listid, op->nlists); | 
| 121 | 
  | 
                close_process(op->rtp); | 
| 122 | 
  | 
        } | 
| 123 | 
  | 
        while (op->xfac) | 
| 124 | 
  | 
                freestr(op->xfav[--op->xfac]); | 
| 125 | 
< | 
        free((char *)op); | 
| 125 | 
> | 
        free((void *)op); | 
| 126 | 
  | 
        return(1); | 
| 127 | 
  | 
} | 
| 128 | 
  | 
 | 
| 297 | 
  | 
                                                /* avg. reflected brightness */ | 
| 298 | 
  | 
        d = AVGREFL / (double)ncells;    | 
| 299 | 
  | 
        scalecolor(csum, d); | 
| 300 | 
< | 
        if (tmCvColors(&dlightsets->larb, TM_NOCHROM, csum, 1) != TM_E_OK) | 
| 300 | 
> | 
        if (tmCvColors(&dlightsets->larb, TM_NOCHROM, &csum, 1) != TM_E_OK) | 
| 301 | 
  | 
                error(CONSISTENCY, "tone mapping problem in ssph_compute"); | 
| 302 | 
  | 
                                        /* greedy light source clustering */ | 
| 303 | 
  | 
        while (dlightsets->nl < MAXLIGHTS) { | 
| 318 | 
  | 
                                continue;               /* too dim */ | 
| 319 | 
  | 
                        ssph_direc(v, alt, azi);        /* else add it in */ | 
| 320 | 
  | 
                        VSUM(ls->direc, ls->direc, v, d); | 
| 321 | 
< | 
                        ls->omega++; | 
| 321 | 
> | 
                        ls->omega += 1.; | 
| 322 | 
  | 
                        addcolor(ls->val, ssamp[alt][azi].val); | 
| 323 | 
+ | 
                                                        /* remove from list */ | 
| 324 | 
  | 
                        setcolor(ssamp[alt][azi].val, 0., 0., 0.); | 
| 325 | 
+ | 
                        ssamp[alt][azi].nsamp = 0; | 
| 326 | 
  | 
                } | 
| 327 | 
  | 
                d = 1./ls->omega;                       /* avg. brightness */ | 
| 328 | 
  | 
                scalecolor(ls->val, d); | 
| 404 | 
  | 
                        quit(0); | 
| 405 | 
  | 
        if (!ssph_compute()) {          /* compute light sources from sphere */ | 
| 406 | 
  | 
                dlightsets = dl->next; | 
| 407 | 
< | 
                free((char *)dl); | 
| 407 | 
> | 
                free((void *)dl); | 
| 408 | 
  | 
                return(0); | 
| 409 | 
  | 
        } | 
| 410 | 
  | 
        op->ol = dl; | 
| 414 | 
  | 
} | 
| 415 | 
  | 
 | 
| 416 | 
  | 
 | 
| 417 | 
< | 
static int | 
| 417 | 
> | 
static | 
| 418 | 
  | 
cmderror(cn, err)               /* report command error */ | 
| 419 | 
  | 
int     cn; | 
| 420 | 
  | 
char    *err; | 
| 421 | 
  | 
{ | 
| 422 | 
  | 
        sprintf(errmsg, "%s: %s", rhdcmd[cn], err); | 
| 423 | 
  | 
        error(COMMAND, errmsg); | 
| 424 | 
– | 
        return(cn); | 
| 424 | 
  | 
} | 
| 425 | 
  | 
 | 
| 426 | 
  | 
 | 
| 429 | 
  | 
char    *cmd; | 
| 430 | 
  | 
register char   *args; | 
| 431 | 
  | 
{ | 
| 432 | 
+ | 
        int     somechange = 0; | 
| 433 | 
  | 
        int     cn, na, doxfm; | 
| 434 | 
  | 
        register int    nn; | 
| 435 | 
  | 
        char    *alist[MAXAC+1], *nm; | 
| 457 | 
  | 
                        dobj_load(alist[0], alist[0]); | 
| 458 | 
  | 
                else if (na == 2) | 
| 459 | 
  | 
                        dobj_load(alist[0], alist[1]); | 
| 460 | 
< | 
                else | 
| 461 | 
< | 
                        return(cmderror(cn, "need octree [name]")); | 
| 460 | 
> | 
                else { | 
| 461 | 
> | 
                        cmderror(cn, "need octree [name]"); | 
| 462 | 
> | 
                        return(0); | 
| 463 | 
> | 
                } | 
| 464 | 
  | 
                break; | 
| 465 | 
  | 
        case DO_UNLOAD:                         /* clear an object */ | 
| 466 | 
  | 
                if (na > 1) goto toomany; | 
| 467 | 
  | 
                if (na && alist[0][0] == '*') | 
| 468 | 
< | 
                        dobj_cleanup(); | 
| 468 | 
> | 
                        somechange += dobj_cleanup(); | 
| 469 | 
  | 
                else | 
| 470 | 
< | 
                        dobj_unload(na ? alist[0] : curname); | 
| 470 | 
> | 
                        somechange += dobj_unload(na ? alist[0] : curname); | 
| 471 | 
  | 
                break; | 
| 472 | 
  | 
        case DO_XFORM:                          /* transform object */ | 
| 473 | 
  | 
        case DO_MOVE: | 
| 476 | 
  | 
                } else { | 
| 477 | 
  | 
                        nm = curname; nn = 0; | 
| 478 | 
  | 
                } | 
| 479 | 
< | 
                if (cn == DO_MOVE && nn >= na) | 
| 480 | 
< | 
                        return(cmderror(cn, "missing transform")); | 
| 481 | 
< | 
                dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); | 
| 479 | 
> | 
                if (cn == DO_MOVE && nn >= na) { | 
| 480 | 
> | 
                        cmderror(cn, "missing transform"); | 
| 481 | 
> | 
                        return(0); | 
| 482 | 
> | 
                } | 
| 483 | 
> | 
                somechange += dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); | 
| 484 | 
  | 
                break; | 
| 485 | 
  | 
        case DO_UNMOVE:                         /* undo last transform */ | 
| 486 | 
< | 
                dobj_unmove(); | 
| 486 | 
> | 
                somechange += dobj_unmove(); | 
| 487 | 
  | 
                break; | 
| 488 | 
  | 
        case DO_OBJECT:                         /* print object statistics */ | 
| 489 | 
  | 
                if (dobj_putstats(na ? alist[0] : curname, sstdout)) | 
| 497 | 
  | 
                                break; | 
| 498 | 
  | 
                switch (nn) { | 
| 499 | 
  | 
                case 0: | 
| 500 | 
< | 
                        return(cmderror(cn, "need new object name")); | 
| 500 | 
> | 
                        cmderror(cn, "need new object name"); | 
| 501 | 
> | 
                        return(0); | 
| 502 | 
  | 
                case 1: | 
| 503 | 
  | 
                        nm = curname; | 
| 504 | 
  | 
                        break; | 
| 511 | 
  | 
                if (!dobj_dup(nm, alist[nn-1])) | 
| 512 | 
  | 
                        break; | 
| 513 | 
  | 
                if (na > nn) | 
| 514 | 
< | 
                        dobj_xform(curname, 1, na-nn, alist+nn); | 
| 514 | 
> | 
                        somechange += dobj_xform(curname, 1, na-nn, alist+nn); | 
| 515 | 
  | 
                else | 
| 516 | 
  | 
                        curobj->drawcode = DO_HIDE; | 
| 517 | 
  | 
                savedxf(curobj); | 
| 521 | 
  | 
        case DO_HIDE: | 
| 522 | 
  | 
                if (na > 1) goto toomany; | 
| 523 | 
  | 
                dobj_lighting(na ? alist[0] : curname, cn); | 
| 524 | 
+ | 
                somechange++; | 
| 525 | 
  | 
                break; | 
| 526 | 
  | 
        default: | 
| 527 | 
  | 
                error(CONSISTENCY, "bad command id in dobj_command"); | 
| 528 | 
  | 
        } | 
| 529 | 
< | 
        dev_view(&odev.v);                      /* redraw */ | 
| 524 | 
< | 
        return(cn); | 
| 529 | 
> | 
        return(somechange); | 
| 530 | 
  | 
toomany: | 
| 531 | 
  | 
        return(cmderror(cn, "too many arguments")); | 
| 532 | 
  | 
} | 
| 574 | 
  | 
        op->xfav[op->xfac=0] = NULL; | 
| 575 | 
  | 
                                        /* load octree into display list */ | 
| 576 | 
  | 
        dolights = 0; | 
| 577 | 
< | 
        op->listid = rgl_octlist(fpath, op->center, &op->radius); | 
| 577 | 
> | 
        domats = 1; | 
| 578 | 
> | 
        op->listid = rgl_octlist(fpath, op->center, &op->radius, &op->nlists); | 
| 579 | 
  | 
                                        /* start rtrace */ | 
| 580 | 
  | 
        rtargv[RTARGC-1] = fpath; | 
| 581 | 
  | 
        rtargv[RTARGC] = NULL; | 
| 612 | 
  | 
        savedxf(curobj = NULL); | 
| 613 | 
  | 
        while ((lp = dlightsets) != NULL) { | 
| 614 | 
  | 
                dlightsets = lp->next; | 
| 615 | 
< | 
                free((char *)lp); | 
| 615 | 
> | 
                free((void *)lp); | 
| 616 | 
  | 
        } | 
| 617 | 
  | 
        return(1); | 
| 618 | 
  | 
} | 
| 619 | 
  | 
 | 
| 620 | 
  | 
 | 
| 621 | 
< | 
dobj_xform(nam, add, ac, av)            /* set/add transform for nam */ | 
| 621 | 
> | 
dobj_xform(nam, rel, ac, av)            /* set/add transform for nam */ | 
| 622 | 
  | 
char    *nam; | 
| 623 | 
< | 
int     add, ac; | 
| 623 | 
> | 
int     rel, ac; | 
| 624 | 
  | 
char    **av; | 
| 625 | 
  | 
{ | 
| 626 | 
  | 
        register DOBJECT        *op; | 
| 627 | 
+ | 
        FVECT   cent; | 
| 628 | 
+ | 
        double  rad; | 
| 629 | 
+ | 
        char    scoord[16]; | 
| 630 | 
+ | 
        int     i; | 
| 631 | 
  | 
 | 
| 632 | 
  | 
        if ((op = getdobj(nam)) == NULL) { | 
| 633 | 
  | 
                error(COMMAND, "no object"); | 
| 634 | 
  | 
                return(0); | 
| 635 | 
  | 
        } | 
| 636 | 
< | 
        if (add) add = op->xfac; | 
| 637 | 
< | 
        if (ac + add > MAXAC) { | 
| 636 | 
> | 
        if (rel) | 
| 637 | 
> | 
                rel = op->xfac + 8; | 
| 638 | 
> | 
        if (ac + rel > MAXAC) { | 
| 639 | 
  | 
                error(COMMAND, "too many transform arguments"); | 
| 640 | 
  | 
                return(0); | 
| 641 | 
  | 
        } | 
| 642 | 
< | 
        savedxf(curobj = op); | 
| 643 | 
< | 
        if (!add) | 
| 642 | 
> | 
        savedxf(curobj = op);           /* remember current transform */ | 
| 643 | 
> | 
        if (rel && ac == 4 && !strcmp(av[0], "-t")) | 
| 644 | 
> | 
                rel = -1;                       /* don't move for translate */ | 
| 645 | 
> | 
        else { | 
| 646 | 
> | 
                getdcent(cent, op);             /* don't move if near orig. */ | 
| 647 | 
> | 
                rad = getdrad(op); | 
| 648 | 
> | 
                if (DOT(cent,cent) < rad*rad) | 
| 649 | 
> | 
                        rel = -1; | 
| 650 | 
> | 
        } | 
| 651 | 
> | 
        if (!rel) {                             /* remove old transform */ | 
| 652 | 
  | 
                while (op->xfac) | 
| 653 | 
  | 
                        freestr(op->xfav[--op->xfac]); | 
| 654 | 
+ | 
        } else if (rel > 0) {                   /* relative move */ | 
| 655 | 
+ | 
                op->xfav[op->xfac++] = savestr("-t"); | 
| 656 | 
+ | 
                for (i = 0; i < 3; i++) { | 
| 657 | 
+ | 
                        sprintf(scoord, "%.4e", -cent[i]); | 
| 658 | 
+ | 
                        op->xfav[op->xfac++] = savestr(scoord); | 
| 659 | 
+ | 
                } | 
| 660 | 
+ | 
        } | 
| 661 | 
  | 
        while (ac--) | 
| 662 | 
  | 
                op->xfav[op->xfac++] = savestr(*av++); | 
| 663 | 
+ | 
        if (rel > 0) {                          /* move back */ | 
| 664 | 
+ | 
                op->xfav[op->xfac++] = savestr("-t"); | 
| 665 | 
+ | 
                for (i = 0; i < 3; i++) { | 
| 666 | 
+ | 
                        sprintf(scoord, "%.4e", cent[i]); | 
| 667 | 
+ | 
                        op->xfav[op->xfac++] = savestr(scoord); | 
| 668 | 
+ | 
                } | 
| 669 | 
+ | 
        } | 
| 670 | 
  | 
        op->xfav[op->xfac] = NULL; | 
| 671 | 
  | 
        if (fullxf(&op->xfb, op->xfac, op->xfav) != op->xfac) { | 
| 672 | 
  | 
                error(COMMAND, "bad transform arguments"); | 
| 703 | 
  | 
                return(0); | 
| 704 | 
  | 
        } | 
| 705 | 
  | 
        getdcent(ocent, op); | 
| 706 | 
< | 
        fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name, | 
| 706 | 
> | 
        fprintf(fp, "%s: %s, center [%g %g %g], radius %g", op->name, | 
| 707 | 
  | 
                        op->drawcode==DO_HIDE ? "hidden" : | 
| 708 | 
  | 
                        op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" : | 
| 709 | 
  | 
                        "shown", | 
| 860 | 
  | 
                VCOPY(darr, rorg); VCOPY(darr+3, rdir); | 
| 861 | 
  | 
        } | 
| 862 | 
  | 
                                /* trace it */ | 
| 863 | 
< | 
        if (process(op->rtp, darr, darr, sizeof(double), | 
| 863 | 
> | 
        if (process(op->rtp, (char *)darr, (char *)darr, sizeof(double), | 
| 864 | 
  | 
                        6*sizeof(double)) != sizeof(double)) | 
| 865 | 
  | 
                error(SYSTEM, "rtrace communication error"); | 
| 866 | 
  | 
                                /* return distance */ | 
| 870 | 
  | 
} | 
| 871 | 
  | 
 | 
| 872 | 
  | 
 | 
| 873 | 
+ | 
int | 
| 874 | 
  | 
dobj_render()                   /* render our objects in OpenGL */ | 
| 875 | 
  | 
{ | 
| 876 | 
+ | 
        int     nrendered = 0; | 
| 877 | 
  | 
        GLboolean       normalizing; | 
| 878 | 
  | 
        GLfloat vec[4]; | 
| 879 | 
  | 
        FVECT   v1; | 
| 884 | 
  | 
                if (op->drawcode != DO_HIDE) | 
| 885 | 
  | 
                        break; | 
| 886 | 
  | 
        if (op == NULL) | 
| 887 | 
< | 
                return(1); | 
| 887 | 
> | 
                return(0); | 
| 888 | 
  | 
                                        /* set up general rendering params */ | 
| 889 | 
  | 
        glGetBooleanv(GL_NORMALIZE, &normalizing); | 
| 890 | 
  | 
        glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT| | 
| 970 | 
  | 
                } | 
| 971 | 
  | 
                                        /* render the display list */ | 
| 972 | 
  | 
                glCallList(op->listid); | 
| 973 | 
+ | 
                nrendered++; | 
| 974 | 
  | 
                                        /* restore matrix */ | 
| 975 | 
  | 
                if (op->xfac) { | 
| 976 | 
  | 
                        glMatrixMode(GL_MODELVIEW); | 
| 988 | 
  | 
        } | 
| 989 | 
  | 
        glPopAttrib();                  /* restore rendering params */ | 
| 990 | 
  | 
        rgl_checkerr("rendering objects in dobj_render"); | 
| 991 | 
< | 
        return(1); | 
| 991 | 
> | 
        return(nrendered); | 
| 992 | 
  | 
} |