| 1 | 
– | 
/* Copyright (c) 1987 Regents of the University of California */ | 
| 2 | 
– | 
 | 
| 1 | 
  | 
#ifndef lint | 
| 2 | 
< | 
static char SCCSid[] = "$SunId$ LBL"; | 
| 2 | 
> | 
static const char       RCSid[] = "$Id$"; | 
| 3 | 
  | 
#endif | 
| 6 | 
– | 
 | 
| 4 | 
  | 
/* | 
| 5 | 
  | 
 *  rview.c - routines and variables for interactive view generation. | 
| 6 | 
  | 
 * | 
| 7 | 
< | 
 *     3/24/87 | 
| 7 | 
> | 
 *  External symbols declared in rpaint.h | 
| 8 | 
  | 
 */ | 
| 9 | 
  | 
 | 
| 10 | 
+ | 
#include "copyright.h" | 
| 11 | 
+ | 
 | 
| 12 | 
  | 
#include  "ray.h" | 
| 13 | 
  | 
 | 
| 14 | 
  | 
#include  "rpaint.h" | 
| 17 | 
  | 
 | 
| 18 | 
  | 
#include  <ctype.h> | 
| 19 | 
  | 
 | 
| 20 | 
< | 
VIEW  ourview = STDVIEW;                /* viewing parameters */ | 
| 21 | 
< | 
int  hresolu, vresolu;                  /* image resolution */ | 
| 20 | 
> | 
CUBE  thescene;                         /* our scene */ | 
| 21 | 
> | 
OBJECT  nsceneobjs;                     /* number of objects in our scene */ | 
| 22 | 
  | 
 | 
| 23 | 
  | 
int  dimlist[MAXDIM];                   /* sampling dimensions */ | 
| 24 | 
  | 
int  ndims = 0;                         /* number of sampling dimensions */ | 
| 25 | 
  | 
int  samplendx = 0;                     /* index for this sample */ | 
| 26 | 
  | 
 | 
| 27 | 
+ | 
extern void  ambnotify(); | 
| 28 | 
+ | 
void  (*addobjnotify[])() = {ambnotify, NULL}; | 
| 29 | 
+ | 
 | 
| 30 | 
+ | 
VIEW  ourview = STDVIEW;                /* viewing parameters */ | 
| 31 | 
+ | 
int  hresolu, vresolu;                  /* image resolution */ | 
| 32 | 
+ | 
 | 
| 33 | 
+ | 
void  (*trace)() = NULL;                /* trace call */ | 
| 34 | 
+ | 
 | 
| 35 | 
+ | 
int  do_irrad = 0;                      /* compute irradiance? */ | 
| 36 | 
+ | 
 | 
| 37 | 
  | 
int  psample = 8;                       /* pixel sample size */ | 
| 38 | 
< | 
double  maxdiff = .15;                  /* max. sample difference */ | 
| 38 | 
> | 
double  maxdiff = .15;                  /* max. sample difference */ | 
| 39 | 
  | 
 | 
| 40 | 
< | 
double  exposure = 1.0;                 /* exposure for scene */ | 
| 40 | 
> | 
double  exposure = 1.0;                 /* exposure for scene */ | 
| 41 | 
  | 
 | 
| 42 | 
< | 
double  dstrsrc = 0.0;                  /* square source distribution */ | 
| 43 | 
< | 
double  shadthresh = .1;                /* shadow threshold */ | 
| 44 | 
< | 
double  shadcert = .25;                 /* shadow certainty */ | 
| 42 | 
> | 
double  dstrsrc = 0.0;                  /* square source distribution */ | 
| 43 | 
> | 
double  shadthresh = .1;                /* shadow threshold */ | 
| 44 | 
> | 
double  shadcert = .25;                 /* shadow certainty */ | 
| 45 | 
  | 
int  directrelay = 0;                   /* number of source relays */ | 
| 46 | 
  | 
int  vspretest = 128;                   /* virtual source pretest density */ | 
| 47 | 
< | 
int  directinvis = 0;                   /* sources invisible? */ | 
| 48 | 
< | 
double  srcsizerat = 0.;                /* maximum ratio source size/dist. */ | 
| 47 | 
> | 
int  directvis = 1;                     /* sources visible? */ | 
| 48 | 
> | 
double  srcsizerat = 0.;                /* maximum ratio source size/dist. */ | 
| 49 | 
  | 
 | 
| 50 | 
+ | 
COLOR  cextinction = BLKCOLOR;          /* global extinction coefficient */ | 
| 51 | 
+ | 
COLOR  salbedo = BLKCOLOR;              /* global scattering albedo */ | 
| 52 | 
+ | 
double  seccg = 0.;                     /* global scattering eccentricity */ | 
| 53 | 
+ | 
double  ssampdist = 0.;                 /* scatter sampling distance */ | 
| 54 | 
+ | 
 | 
| 55 | 
+ | 
double  specthresh = .3;                /* specular sampling threshold */ | 
| 56 | 
+ | 
double  specjitter = 1.;                /* specular sampling jitter */ | 
| 57 | 
+ | 
 | 
| 58 | 
+ | 
int  backvis = 1;                       /* back face visibility */ | 
| 59 | 
+ | 
 | 
| 60 | 
  | 
int  maxdepth = 4;                      /* maximum recursion depth */ | 
| 61 | 
< | 
double  minweight = 1e-2;               /* minimum ray weight */ | 
| 61 | 
> | 
double  minweight = 1e-2;               /* minimum ray weight */ | 
| 62 | 
  | 
 | 
| 63 | 
+ | 
char  *ambfile = NULL;                  /* ambient file name */ | 
| 64 | 
  | 
COLOR  ambval = BLKCOLOR;               /* ambient value */ | 
| 65 | 
< | 
double  ambacc = 0.2;                   /* ambient accuracy */ | 
| 65 | 
> | 
int  ambvwt = 0;                        /* initial weight for ambient value */ | 
| 66 | 
> | 
double  ambacc = 0.2;                   /* ambient accuracy */ | 
| 67 | 
  | 
int  ambres = 8;                        /* ambient resolution */ | 
| 68 | 
  | 
int  ambdiv = 32;                       /* ambient divisions */ | 
| 69 | 
  | 
int  ambssamp = 0;                      /* ambient super-samples */ | 
| 72 | 
  | 
int  ambincl = -1;                      /* include == 1, exclude == 0 */ | 
| 73 | 
  | 
 | 
| 74 | 
  | 
int  greyscale = 0;                     /* map colors to brightness? */ | 
| 75 | 
< | 
char  *devname = dev_default;           /* output device name */ | 
| 75 | 
> | 
char  *dvcname = dev_default;           /* output device name */ | 
| 76 | 
  | 
 | 
| 77 | 
  | 
struct driver  *dev = NULL;             /* driver functions */ | 
| 78 | 
  | 
 | 
| 79 | 
+ | 
char  rifname[128];                     /* rad input file name */ | 
| 80 | 
+ | 
 | 
| 81 | 
  | 
VIEW  oldview;                          /* previous view parameters */ | 
| 82 | 
  | 
 | 
| 83 | 
  | 
PNODE  ptrunk;                          /* the base of our image */ | 
| 88 | 
  | 
 | 
| 89 | 
  | 
#define RESERVE_AMT     32768           /* amount of memory to reserve */ | 
| 90 | 
  | 
 | 
| 91 | 
< | 
#define  CTRL(c)        ('c'-'@') | 
| 91 | 
> | 
#define  CTRL(c)        ((c)-'@') | 
| 92 | 
  | 
 | 
| 93 | 
  | 
 | 
| 94 | 
+ | 
void | 
| 95 | 
  | 
quit(code)                      /* quit program */ | 
| 96 | 
  | 
int  code; | 
| 97 | 
  | 
{ | 
| 98 | 
+ | 
#ifdef MSTATS | 
| 99 | 
+ | 
        if (code == 2 && errno == ENOMEM) | 
| 100 | 
+ | 
                printmemstats(stderr); | 
| 101 | 
+ | 
#endif | 
| 102 | 
  | 
        devclose(); | 
| 103 | 
  | 
        exit(code); | 
| 104 | 
  | 
} | 
| 105 | 
  | 
 | 
| 106 | 
  | 
 | 
| 107 | 
+ | 
void | 
| 108 | 
  | 
devopen(dname)                          /* open device driver */ | 
| 109 | 
  | 
char  *dname; | 
| 110 | 
  | 
{ | 
| 121 | 
  | 
                                error(USER, errmsg); | 
| 122 | 
  | 
                        } else | 
| 123 | 
  | 
                                return; | 
| 124 | 
+ | 
#ifndef NIX                                                 | 
| 125 | 
  | 
                                                /* not there, try exec */ | 
| 126 | 
  | 
        if ((dev = comm_init(dname, id)) == NULL) { | 
| 127 | 
  | 
                sprintf(errmsg, "cannot start device \"%s\"", dname); | 
| 128 | 
  | 
                error(USER, errmsg); | 
| 129 | 
  | 
        } | 
| 130 | 
+ | 
#endif | 
| 131 | 
  | 
} | 
| 132 | 
  | 
 | 
| 133 | 
  | 
 | 
| 134 | 
+ | 
void | 
| 135 | 
  | 
devclose()                              /* close our device */ | 
| 136 | 
  | 
{ | 
| 137 | 
  | 
        if (dev != NULL) | 
| 140 | 
  | 
} | 
| 141 | 
  | 
 | 
| 142 | 
  | 
 | 
| 143 | 
+ | 
void | 
| 144 | 
  | 
printdevices()                          /* print list of output devices */ | 
| 145 | 
  | 
{ | 
| 146 | 
  | 
        register int  i; | 
| 150 | 
  | 
} | 
| 151 | 
  | 
 | 
| 152 | 
  | 
 | 
| 153 | 
+ | 
void | 
| 154 | 
  | 
rview()                         /* do a view */ | 
| 155 | 
  | 
{ | 
| 156 | 
  | 
        char  buf[32]; | 
| 157 | 
  | 
 | 
| 158 | 
< | 
        devopen(devname);               /* open device */ | 
| 158 | 
> | 
        devopen(dvcname);               /* open device */ | 
| 159 | 
  | 
        newimage();                     /* start image (calls fillreserves) */ | 
| 160 | 
  | 
 | 
| 161 | 
  | 
        for ( ; ; ) {                   /* quit in command() */ | 
| 183 | 
  | 
} | 
| 184 | 
  | 
 | 
| 185 | 
  | 
 | 
| 186 | 
+ | 
void | 
| 187 | 
  | 
fillreserves()                  /* fill memory reserves */ | 
| 188 | 
  | 
{ | 
| 189 | 
  | 
        if (reserve_mem != NULL) | 
| 190 | 
  | 
                return; | 
| 191 | 
< | 
        reserve_mem = malloc(RESERVE_AMT); | 
| 191 | 
> | 
        reserve_mem = (char *)malloc(RESERVE_AMT); | 
| 192 | 
  | 
} | 
| 193 | 
  | 
 | 
| 194 | 
  | 
 | 
| 195 | 
+ | 
void | 
| 196 | 
  | 
freereserves()                  /* free memory reserves */ | 
| 197 | 
  | 
{ | 
| 198 | 
  | 
        if (reserve_mem == NULL) | 
| 202 | 
  | 
} | 
| 203 | 
  | 
 | 
| 204 | 
  | 
 | 
| 205 | 
+ | 
void | 
| 206 | 
  | 
command(prompt)                 /* get/execute command */ | 
| 207 | 
  | 
char  *prompt; | 
| 208 | 
  | 
{ | 
| 209 | 
< | 
#define  badcom(s)      strncmp(s, inpbuf, args-inpbuf-1) | 
| 173 | 
< | 
        double  atof(); | 
| 209 | 
> | 
#define  badcom(s)      strncmp(s, inpbuf, args-inpbuf-1) | 
| 210 | 
  | 
        char  inpbuf[256]; | 
| 211 | 
  | 
        char  *args; | 
| 212 | 
  | 
again: | 
| 217 | 
  | 
        else *++args = '\0'; | 
| 218 | 
  | 
         | 
| 219 | 
  | 
        switch (inpbuf[0]) { | 
| 220 | 
< | 
        case 'f':                               /* new frame */ | 
| 221 | 
< | 
                if (badcom("frame")) | 
| 222 | 
< | 
                        goto commerr; | 
| 220 | 
> | 
        case 'f':                               /* new frame (or free mem.) */ | 
| 221 | 
> | 
                if (badcom("frame")) { | 
| 222 | 
> | 
                        if (badcom("free")) | 
| 223 | 
> | 
                                goto commerr; | 
| 224 | 
> | 
                        free_objmem(); | 
| 225 | 
> | 
                        break; | 
| 226 | 
> | 
                } | 
| 227 | 
  | 
                getframe(args); | 
| 228 | 
  | 
                break; | 
| 229 | 
  | 
        case 'v':                               /* view */ | 
| 236 | 
  | 
                        goto commerr; | 
| 237 | 
  | 
                lastview(args); | 
| 238 | 
  | 
                break; | 
| 239 | 
+ | 
        case 'V':                               /* save view */ | 
| 240 | 
+ | 
                if (badcom("V")) | 
| 241 | 
+ | 
                        goto commerr; | 
| 242 | 
+ | 
                saveview(args); | 
| 243 | 
+ | 
                break; | 
| 244 | 
+ | 
        case 'L':                               /* load view */ | 
| 245 | 
+ | 
                if (badcom("L")) | 
| 246 | 
+ | 
                        goto commerr; | 
| 247 | 
+ | 
                loadview(args); | 
| 248 | 
+ | 
                break; | 
| 249 | 
  | 
        case 'e':                               /* exposure */ | 
| 250 | 
  | 
                if (badcom("exposure")) | 
| 251 | 
  | 
                        goto commerr; | 
| 252 | 
  | 
                getexposure(args); | 
| 253 | 
  | 
                break; | 
| 254 | 
  | 
        case 's':                               /* set a parameter */ | 
| 255 | 
< | 
                if (badcom("set")) | 
| 255 | 
> | 
                if (badcom("set")) { | 
| 256 | 
> | 
#ifdef  SIGTSTP | 
| 257 | 
> | 
                        if (!badcom("stop")) | 
| 258 | 
> | 
                                goto dostop; | 
| 259 | 
> | 
#endif | 
| 260 | 
  | 
                        goto commerr; | 
| 261 | 
+ | 
                } | 
| 262 | 
  | 
                setparam(args); | 
| 263 | 
  | 
                break; | 
| 264 | 
  | 
        case 'n':                               /* new picture */ | 
| 276 | 
  | 
                        goto commerr; | 
| 277 | 
  | 
                getaim(args); | 
| 278 | 
  | 
                break; | 
| 279 | 
< | 
        case 'm':                               /* move camera */ | 
| 279 | 
> | 
        case 'm':                               /* move camera (or memstats) */ | 
| 280 | 
  | 
                if (badcom("move")) | 
| 281 | 
+ | 
#ifdef  MSTATS | 
| 282 | 
+ | 
                { | 
| 283 | 
+ | 
                        if (badcom("memory")) | 
| 284 | 
+ | 
                                goto commerr; | 
| 285 | 
+ | 
                        printmemstats(stderr); | 
| 286 | 
+ | 
                        break; | 
| 287 | 
+ | 
                } | 
| 288 | 
+ | 
#else | 
| 289 | 
  | 
                        goto commerr; | 
| 290 | 
+ | 
#endif | 
| 291 | 
  | 
                getmove(args); | 
| 292 | 
  | 
                break; | 
| 293 | 
  | 
        case 'r':                               /* rotate/repaint */ | 
| 294 | 
  | 
                if (badcom("rotate")) { | 
| 295 | 
< | 
                        if (badcom("repaint")) | 
| 296 | 
< | 
                                goto commerr; | 
| 295 | 
> | 
                        if (badcom("repaint")) { | 
| 296 | 
> | 
                                if (badcom("redraw")) | 
| 297 | 
> | 
                                        goto commerr; | 
| 298 | 
> | 
                                redraw(); | 
| 299 | 
> | 
                                break; | 
| 300 | 
> | 
                        } | 
| 301 | 
  | 
                        getrepaint(args); | 
| 302 | 
  | 
                        break; | 
| 303 | 
  | 
                } | 
| 304 | 
  | 
                getrotate(args); | 
| 305 | 
  | 
                break; | 
| 306 | 
  | 
        case 'p':                               /* pivot view */ | 
| 307 | 
< | 
                if (badcom("pivot")) | 
| 308 | 
< | 
                        goto commerr; | 
| 307 | 
> | 
                if (badcom("pivot")) { | 
| 308 | 
> | 
                        if (badcom("pause")) | 
| 309 | 
> | 
                                goto commerr; | 
| 310 | 
> | 
                        goto again; | 
| 311 | 
> | 
                } | 
| 312 | 
  | 
                getpivot(args); | 
| 313 | 
  | 
                break; | 
| 314 | 
< | 
        case CTRL(R):                           /* redraw */ | 
| 314 | 
> | 
        case CTRL('R'):                         /* redraw */ | 
| 315 | 
  | 
                redraw(); | 
| 316 | 
  | 
                break; | 
| 317 | 
  | 
        case 'w':                               /* write */ | 
| 323 | 
  | 
                if (badcom("quit")) | 
| 324 | 
  | 
                        goto commerr; | 
| 325 | 
  | 
                quit(0); | 
| 326 | 
< | 
        case CTRL(C):                           /* interrupt */ | 
| 326 | 
> | 
        case CTRL('C'):                         /* interrupt */ | 
| 327 | 
  | 
                goto again; | 
| 328 | 
< | 
#ifdef  SIGTSTP | 
| 329 | 
< | 
        case CTRL(Z):                           /* stop */ | 
| 328 | 
> | 
#ifdef  SIGTSTP | 
| 329 | 
> | 
        case CTRL('Z'):;                        /* stop */ | 
| 330 | 
> | 
dostop: | 
| 331 | 
  | 
                devclose(); | 
| 332 | 
  | 
                kill(0, SIGTSTP); | 
| 333 | 
  | 
                /* pc stops here */ | 
| 334 | 
< | 
                devopen(devname); | 
| 334 | 
> | 
                devopen(dvcname); | 
| 335 | 
  | 
                redraw(); | 
| 336 | 
  | 
                break; | 
| 337 | 
  | 
#endif | 
| 347 | 
  | 
                error(COMMAND, errmsg); | 
| 348 | 
  | 
                break; | 
| 349 | 
  | 
        } | 
| 350 | 
< | 
#undef  badcom | 
| 350 | 
> | 
#undef  badcom | 
| 351 | 
  | 
} | 
| 352 | 
  | 
 | 
| 353 | 
  | 
 | 
| 354 | 
+ | 
void | 
| 355 | 
  | 
rsample()                       /* sample the image */ | 
| 356 | 
  | 
{ | 
| 357 | 
  | 
        int  xsiz, ysiz, y; | 
| 358 | 
  | 
        RECT  r; | 
| 359 | 
  | 
        PNODE  *p; | 
| 360 | 
  | 
        register RECT  *rl; | 
| 361 | 
< | 
        register PNODE  **pl; | 
| 361 | 
> | 
        register PNODE  **pl; | 
| 362 | 
  | 
        register int  x; | 
| 363 | 
  | 
        /* | 
| 364 | 
  | 
         *     We initialize the bottom row in the image at our current | 
| 365 | 
< | 
         * resolution.  During sampling, we check super-pixels to the | 
| 365 | 
> | 
         * resolution.  During sampling, we check super-pixels to the | 
| 366 | 
  | 
         * right and above by calling bigdiff().  If there is a significant | 
| 367 | 
  | 
         * difference, we subsample the super-pixels.  The testing process | 
| 368 | 
  | 
         * includes initialization of the next row. | 
| 369 | 
  | 
         */ | 
| 370 | 
< | 
        xsiz = (((pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu; | 
| 371 | 
< | 
        ysiz = (((pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu; | 
| 370 | 
> | 
        xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu; | 
| 371 | 
> | 
        ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu; | 
| 372 | 
  | 
        rl = (RECT *)malloc(xsiz*sizeof(RECT)); | 
| 373 | 
  | 
        if (rl == NULL) | 
| 374 | 
  | 
                return; | 
| 375 | 
  | 
        pl = (PNODE **)malloc(xsiz*sizeof(PNODE *)); | 
| 376 | 
< | 
        if (pl == NULL) | 
| 376 | 
> | 
        if (pl == NULL) { | 
| 377 | 
> | 
                free((void *)rl); | 
| 378 | 
  | 
                return; | 
| 379 | 
+ | 
        } | 
| 380 | 
  | 
        /* | 
| 381 | 
  | 
         * Initialize the bottom row. | 
| 382 | 
  | 
         */ | 
| 435 | 
  | 
                } | 
| 436 | 
  | 
        } | 
| 437 | 
  | 
escape: | 
| 438 | 
< | 
        free((char *)rl); | 
| 439 | 
< | 
        free((char *)pl); | 
| 438 | 
> | 
        free((void *)rl); | 
| 439 | 
> | 
        free((void *)pl); | 
| 440 | 
  | 
} | 
| 441 | 
  | 
 | 
| 442 | 
  | 
 | 
| 443 | 
  | 
int | 
| 444 | 
  | 
refine(p, xmin, ymin, xmax, ymax, pd)           /* refine a node */ | 
| 445 | 
< | 
register PNODE  *p; | 
| 445 | 
> | 
register PNODE  *p; | 
| 446 | 
  | 
int  xmin, ymin, xmax, ymax; | 
| 447 | 
  | 
int  pd; | 
| 448 | 
  | 
{ | 
| 466 | 
  | 
                        return(0); | 
| 467 | 
  | 
                /* | 
| 468 | 
  | 
                 *  The following paint order can leave a black pixel | 
| 469 | 
< | 
                 *  when redraw() is called in (*dev->paintr)(). | 
| 469 | 
> | 
                 *  if redraw() is called in (*dev->paintr)(). | 
| 470 | 
  | 
                 */ | 
| 471 | 
  | 
                if (p->x >= mx && p->y >= my) | 
| 472 | 
  | 
                        pcopy(p, p->kid+UR); |