--- ray/src/hd/rhdobj.c 1998/08/27 19:32:43 3.5 +++ ray/src/hd/rhdobj.c 2003/06/26 00:58:10 3.13 @@ -1,9 +1,6 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhdobj.c,v 3.13 2003/06/26 00:58:10 schorsch Exp $"; #endif - /* * Routines for loading and displaying Radiance objects in rholo with GLX. */ @@ -13,6 +10,7 @@ static char SCCSid[] = "$SunId$ SGI"; #include "rhdisp.h" #include "rhdriver.h" #include "rhdobj.h" +#include "rtprocess.h" extern FILE *sstdout; /* user standard output */ @@ -22,7 +20,7 @@ int (*dobj_lightsamp)() = NULL; /* pointer to function #define AVGREFL 0.5 /* assumed average reflectance */ -#define MAXAC 64 /* maximum number of args */ +#define MAXAC 512 /* maximum number of args */ #ifndef MINTHRESH #define MINTHRESH 5.0 /* source threshold w.r.t. mean */ @@ -53,9 +51,10 @@ typedef struct dobject { struct dobject *next; /* next object in list */ char name[64]; /* object name */ FVECT center; /* orig. object center */ - FLOAT radius; /* orig. object radius */ + RREAL radius; /* orig. object radius */ int listid; /* GL display list identifier */ - int rtp[3]; /* associated rtrace process */ + int nlists; /* number of lists allocated */ + SUBPROC rtp; /* associated rtrace process */ DLIGHTS *ol; /* object lights */ FULLXF xfb; /* coordinate transform */ short drawcode; /* drawing code */ @@ -119,12 +118,12 @@ register DOBJECT *op; } dobjects = ohead.next; if (!foundlink) { - glDeleteLists(op->listid, 1); - close_process(op->rtp); + glDeleteLists(op->listid, op->nlists); + close_process(&(op->rtp)); } while (op->xfac) freestr(op->xfav[--op->xfac]); - free((char *)op); + free((void *)op); return(1); } @@ -299,7 +298,7 @@ ssph_compute() /* compute source set from sphere sam /* avg. reflected brightness */ d = AVGREFL / (double)ncells; scalecolor(csum, d); - if (tmCvColors(&dlightsets->larb, TM_NOCHROM, csum, 1) != TM_E_OK) + if (tmCvColors(&dlightsets->larb, TM_NOCHROM, &csum, 1) != TM_E_OK) error(CONSISTENCY, "tone mapping problem in ssph_compute"); /* greedy light source clustering */ while (dlightsets->nl < MAXLIGHTS) { @@ -320,9 +319,11 @@ ssph_compute() /* compute source set from sphere sam continue; /* too dim */ ssph_direc(v, alt, azi); /* else add it in */ VSUM(ls->direc, ls->direc, v, d); - ls->omega++; + ls->omega += 1.; addcolor(ls->val, ssamp[alt][azi].val); + /* remove from list */ setcolor(ssamp[alt][azi].val, 0., 0., 0.); + ssamp[alt][azi].nsamp = 0; } d = 1./ls->omega; /* avg. brightness */ scalecolor(ls->val, d); @@ -337,7 +338,7 @@ ssph_compute() /* compute source set from sphere sam d = 1.0/ncells; scalecolor(dlightsets->lamb, d); done: /* clear sphere sample array */ - bzero((char *)ssamp, sizeof(ssamp)); + bzero((void *)ssamp, sizeof(ssamp)); return(ncells); } @@ -404,7 +405,7 @@ int force; quit(0); if (!ssph_compute()) { /* compute light sources from sphere */ dlightsets = dl->next; - free((char *)dl); + free((void *)dl); return(0); } op->ol = dl; @@ -414,14 +415,13 @@ memerr: } -static int +static cmderror(cn, err) /* report command error */ int cn; char *err; { sprintf(errmsg, "%s: %s", rhdcmd[cn], err); error(COMMAND, errmsg); - return(cn); } @@ -430,6 +430,7 @@ dobj_command(cmd, args) /* run object display command char *cmd; register char *args; { + int somechange = 0; int cn, na, doxfm; register int nn; char *alist[MAXAC+1], *nm; @@ -457,15 +458,17 @@ register char *args; dobj_load(alist[0], alist[0]); else if (na == 2) dobj_load(alist[0], alist[1]); - else - return(cmderror(cn, "need octree [name]")); + else { + cmderror(cn, "need octree [name]"); + return(0); + } break; case DO_UNLOAD: /* clear an object */ if (na > 1) goto toomany; if (na && alist[0][0] == '*') - dobj_cleanup(); + somechange += dobj_cleanup(); else - dobj_unload(na ? alist[0] : curname); + somechange += dobj_unload(na ? alist[0] : curname); break; case DO_XFORM: /* transform object */ case DO_MOVE: @@ -474,12 +477,14 @@ register char *args; } else { nm = curname; nn = 0; } - if (cn == DO_MOVE && nn >= na) - return(cmderror(cn, "missing transform")); - dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); + if (cn == DO_MOVE && nn >= na) { + cmderror(cn, "missing transform"); + return(0); + } + somechange += dobj_xform(nm, cn==DO_MOVE, na-nn, alist+nn); break; case DO_UNMOVE: /* undo last transform */ - dobj_unmove(); + somechange += dobj_unmove(); break; case DO_OBJECT: /* print object statistics */ if (dobj_putstats(na ? alist[0] : curname, sstdout)) @@ -493,7 +498,8 @@ register char *args; break; switch (nn) { case 0: - return(cmderror(cn, "need new object name")); + cmderror(cn, "need new object name"); + return(0); case 1: nm = curname; break; @@ -506,7 +512,7 @@ register char *args; if (!dobj_dup(nm, alist[nn-1])) break; if (na > nn) - dobj_xform(curname, 1, na-nn, alist+nn); + somechange += dobj_xform(curname, 1, na-nn, alist+nn); else curobj->drawcode = DO_HIDE; savedxf(curobj); @@ -516,12 +522,12 @@ register char *args; case DO_HIDE: if (na > 1) goto toomany; dobj_lighting(na ? alist[0] : curname, cn); + somechange++; break; default: error(CONSISTENCY, "bad command id in dobj_command"); } - dev_view(&odev.v); /* redraw */ - return(cn); + return(somechange); toomany: return(cmderror(cn, "too many arguments")); } @@ -530,7 +536,6 @@ toomany: dobj_load(oct, nam) /* create/load an octree object */ char *oct, *nam; { - extern char *getlibpath(), *getpath(); char *fpp, fpath[128]; register DOBJECT *op; /* check arguments */ @@ -551,7 +556,7 @@ char *oct, *nam; return(0); } /* get octree path */ - if ((fpp = getpath(oct, getlibpath(), R_OK)) == NULL) { + if ((fpp = getpath(oct, getrlibpath(), R_OK)) == NULL) { sprintf(errmsg, "cannot find octree \"%s\"", oct); error(COMMAND, errmsg); return(0); @@ -569,11 +574,12 @@ char *oct, *nam; op->xfav[op->xfac=0] = NULL; /* load octree into display list */ dolights = 0; - op->listid = rgl_octlist(fpath, op->center, &op->radius); + domats = 1; + op->listid = rgl_octlist(fpath, op->center, &op->radius, &op->nlists); /* start rtrace */ rtargv[RTARGC-1] = fpath; rtargv[RTARGC] = NULL; - open_process(op->rtp, rtargv); + open_process(&(op->rtp), rtargv); /* insert into main list */ op->next = dobjects; curobj = dobjects = op; @@ -606,34 +612,61 @@ dobj_cleanup() /* free all resources */ savedxf(curobj = NULL); while ((lp = dlightsets) != NULL) { dlightsets = lp->next; - free((char *)lp); + free((void *)lp); } return(1); } -dobj_xform(nam, add, ac, av) /* set/add transform for nam */ +dobj_xform(nam, rel, ac, av) /* set/add transform for nam */ char *nam; -int add, ac; +int rel, ac; char **av; { register DOBJECT *op; + FVECT cent; + double rad; + char scoord[16]; + int i; if ((op = getdobj(nam)) == NULL) { error(COMMAND, "no object"); return(0); } - if (add) add = op->xfac; - if (ac + add > MAXAC) { + if (rel) + rel = op->xfac + 8; + if (ac + rel > MAXAC) { error(COMMAND, "too many transform arguments"); return(0); } - savedxf(curobj = op); - if (!add) + savedxf(curobj = op); /* remember current transform */ + if (rel && ac == 4 && !strcmp(av[0], "-t")) + rel = -1; /* don't move for translate */ + else { + getdcent(cent, op); /* don't move if near orig. */ + rad = getdrad(op); + if (DOT(cent,cent) < rad*rad) + rel = -1; + } + if (!rel) { /* remove old transform */ while (op->xfac) freestr(op->xfav[--op->xfac]); + } else if (rel > 0) { /* relative move */ + op->xfav[op->xfac++] = savestr("-t"); + for (i = 0; i < 3; i++) { + sprintf(scoord, "%.4e", -cent[i]); + op->xfav[op->xfac++] = savestr(scoord); + } + } while (ac--) op->xfav[op->xfac++] = savestr(*av++); + if (rel > 0) { /* move back */ + op->xfav[op->xfac++] = savestr("-t"); + for (i = 0; i < 3; i++) { + sprintf(scoord, "%.4e", cent[i]); + op->xfav[op->xfac++] = savestr(scoord); + } + } op->xfav[op->xfac] = NULL; if (fullxf(&op->xfb, op->xfac, op->xfav) != op->xfac) { error(COMMAND, "bad transform arguments"); @@ -670,7 +703,7 @@ FILE *fp; return(0); } getdcent(ocent, op); - fprintf(fp, "%s: %s, center [%f %f %f], radius %f", op->name, + fprintf(fp, "%s: %s, center [%g %g %g], radius %g", op->name, op->drawcode==DO_HIDE ? "hidden" : op->drawcode==DO_LIGHT && op->ol!=NULL ? "lighted" : "shown", @@ -698,13 +731,13 @@ dobj_unmove() /* undo last transform change */ return(0); } /* hold last transform */ - bcopy((char *)lastxfav, (char *)txfav, + bcopy((void *)lastxfav, (void *)txfav, (txfac=lastxfac)*sizeof(char *)); /* save this transform */ - bcopy((char *)curobj->xfav, (char *)lastxfav, + bcopy((void *)curobj->xfav, (void *)lastxfav, (lastxfac=curobj->xfac)*sizeof(char *)); /* copy back last transform */ - bcopy((char *)txfav, (char *)curobj->xfav, + bcopy((void *)txfav, (void *)curobj->xfav, (curobj->xfac=txfac)*sizeof(char *)); /* set matrices */ fullxf(&curobj->xfb, curobj->xfac, curobj->xfav); @@ -827,7 +860,7 @@ FVECT rorg, rdir; VCOPY(darr, rorg); VCOPY(darr+3, rdir); } /* trace it */ - if (process(op->rtp, darr, darr, sizeof(double), + if (process(&(op->rtp), (char *)darr, (char *)darr, sizeof(double), 6*sizeof(double)) != sizeof(double)) error(SYSTEM, "rtrace communication error"); /* return distance */ @@ -837,8 +870,10 @@ FVECT rorg, rdir; } +int dobj_render() /* render our objects in OpenGL */ { + int nrendered = 0; GLboolean normalizing; GLfloat vec[4]; FVECT v1; @@ -849,7 +884,7 @@ dobj_render() /* render our objects in OpenGL */ if (op->drawcode != DO_HIDE) break; if (op == NULL) - return(1); + return(0); /* set up general rendering params */ glGetBooleanv(GL_NORMALIZE, &normalizing); glPushAttrib(GL_LIGHTING_BIT|GL_TRANSFORM_BIT|GL_ENABLE_BIT| @@ -935,6 +970,7 @@ dobj_render() /* render our objects in OpenGL */ } /* render the display list */ glCallList(op->listid); + nrendered++; /* restore matrix */ if (op->xfac) { glMatrixMode(GL_MODELVIEW); @@ -952,5 +988,5 @@ dobj_render() /* render our objects in OpenGL */ } glPopAttrib(); /* restore rendering params */ rgl_checkerr("rendering objects in dobj_render"); - return(1); + return(nrendered); }