ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/ambient.c
(Generate patch)

Comparing ray/src/rt/ambient.c (file contents):
Revision 1.7 by greg, Tue Sep 5 09:46:17 1989 UTC vs.
Revision 1.13 by greg, Thu Jun 6 10:48:50 1991 UTC

# Line 17 | Line 17 | static char SCCSid[] = "$SunId$ LBL";
17  
18   #include  "octree.h"
19  
20 + #include  "otypes.h"
21 +
22   #include  "random.h"
23  
24   #define  OCTSCALE       0.5     /* ceil((valid rad.)/(cube size)) */
# Line 32 | Line 34 | extern int  ambounce;          /* number of ambient bounces */
34   extern char  *amblist[];        /* ambient include/exclude list */
35   extern int  ambincl;            /* include == 1, exclude == 0 */
36  
37 < OBJECT  ambset[128];            /* ambient include/exclude set */
37 > #define  MAXASET        511     /* maximum number of elements in ambient set */
38 > OBJECT  ambset[MAXASET+1]={0};  /* ambient include/exclude set */
39  
40   double  maxarad;                /* maximum ambient radius */
41   double  minarad;                /* minimum ambient radius */
42  
43 + /*
44 + * Since we've defined our vectors as float below to save space,
45 + * watch out for changes in the definitions of VCOPY() and DOT().
46 + */
47   typedef struct ambval {
48 <        FVECT  pos;             /* position in space */
49 <        FVECT  dir;             /* normal direction */
48 >        float  pos[3];          /* position in space */
49 >        float  dir[3];          /* normal direction */
50          int  lvl;               /* recursion level of parent ray */
51          float  weight;          /* weight of parent ray */
52          COLOR  val;             /* computed ambient value */
# Line 74 | Line 81 | setambient(afile)                      /* initialize calculation */
81   char  *afile;
82   {
83          long  ftell();
77        char  **amblp;
78        OBJECT  obj;
84          AMBVAL  amb;
85 <                                        /* set up ambient set */
81 <        ambset[0] = 0;
82 <        for (amblp = amblist; *amblp != NULL; amblp++) {
83 <                if ((obj = modifier(*amblp)) == OVOID) {
84 <                        sprintf(errmsg, "unknown %s modifier \"%s\"",
85 <                                ambincl ? "include" : "exclude", *amblp);
86 <                        error(WARNING, errmsg);
87 <                        continue;
88 <                }
89 <                if (!inset(ambset, obj))
90 <                        insertelem(ambset, obj);
91 <        }
85 >
86          maxarad = thescene.cusize / 2.0;                /* maximum radius */
87                                                          /* minimum radius */
88          minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
# Line 96 | Line 90 | char  *afile;
90                                          /* open ambient file */
91          if (afile != NULL)
92                  if ((ambfp = fopen(afile, "r+")) != NULL) {
93 <                        while (fread(&amb, sizeof(AMBVAL), 1, ambfp) == 1)
93 >                        while (fread((char *)&amb,sizeof(AMBVAL),1,ambfp) == 1)
94                                  avinsert(&amb, &atrunk, thescene.cuorg,
95                                                  thescene.cusize);
96                                                          /* align */
# Line 109 | Line 103 | char  *afile;
103   }
104  
105  
106 + ambnotify(obj)                  /* record new modifier */
107 + OBJECT  obj;
108 + {
109 +        static int  hitlimit = 0;
110 +        register OBJREC  *o = objptr(obj);
111 +        register char  **amblp;
112 +
113 +        if (hitlimit || !ismodifier(o->otype))
114 +                return;
115 +        for (amblp = amblist; *amblp != NULL; amblp++)
116 +                if (!strcmp(o->oname, *amblp)) {
117 +                        if (ambset[0] >= MAXASET) {
118 +                                error(WARNING, "too many modifiers in ambient list");
119 +                                hitlimit++;
120 +                                return;         /* should this be fatal? */
121 +                        }
122 +                        insertelem(ambset, obj);
123 +                        return;
124 +                }
125 + }
126 +
127 +
128   ambient(acol, r)                /* compute ambient component for ray */
129   COLOR  acol;
130   register RAY  *r;
# Line 197 | Line 213 | double  s;
213                  for (j = 0; j < 3; j++)
214                          d += (r->rop[j] - av->pos[j]) *
215                                          (av->dir[j] + r->ron[j]);
216 <                if (d < -minarad)
216 >                if (d*0.5 < -minarad*ambacc)
217                          continue;
218                  /*
219                   *  Jittering final test reduces image artifacts.
# Line 266 | Line 282 | register RAY  *r;
282   {
283          extern int  ambcmp();
284          extern double  sin(), cos(), sqrt();
285 +        int  hlist[4];
286          double  phi, xd, yd, zd;
287          double  b, b2;
288          register AMBSAMP  *div;
# Line 290 | Line 307 | register RAY  *r;
307                  div = (AMBSAMP *)malloc(ndivs*sizeof(AMBSAMP));
308                  if (div == NULL)
309                          error(SYSTEM, "out of memory in doambient");
310 <        }
310 >        } else
311 >                div = NULL;
312                                          /* make axes */
313          uy[0] = uy[1] = uy[2] = 0.0;
314          for (k = 0; k < 3; k++)
# Line 300 | Line 318 | register RAY  *r;
318          fcross(ux, r->ron, uy);
319          normalize(ux);
320          fcross(uy, ux, r->ron);
321 +                                        /* set up urand */
322 +        hlist[0] = r->rno;
323                                                  /* sample divisions */
324          arad = 0.0;
325          ne = 0;
326 <        for (i = 0; i < nt; i++)
326 >        for (i = 0; i < nt; i++) {
327 >                hlist[1] = i;
328                  for (j = 0; j < np; j++) {
329                          rayorigin(&ar, r, AMBIENT, 0.5);        /* pretested */
330 <                        zd = sqrt((i+frandom())/nt);
331 <                        phi = 2.0*PI * (j+frandom())/np;
330 >                        hlist[2] = j;
331 >                        hlist[3] = 0;
332 >                        zd = sqrt((i+urand(ilhash(hlist,4)))/nt);
333 >                        hlist[3] = 1;
334 >                        phi = 2.0*PI * (j+urand(ilhash(hlist,4)))/np;
335                          xd = cos(phi) * zd;
336                          yd = sin(phi) * zd;
337                          zd = sqrt(1.0 - zd*zd);
338                          for (k = 0; k < 3; k++)
339                                  ar.rdir[k] = xd*ux[k]+yd*uy[k]+zd*r->ron[k];
340 +                        dimlist[ndims++] = i*np + j + 38813;
341                          rayvalue(&ar);
342 +                        ndims--;
343                          if (ar.rot < FHUGE)
344                                  arad += 1.0 / ar.rot;
345 <                        if (ns > 0) {                   /* save division */
345 >                        if (div != NULL) {              /* save division */
346                                  div[ne].k = 0.0;
347                                  copycolor(div[ne].v, ar.rcol);
348                                  div[ne].n = 0;
# Line 351 | Line 377 | register RAY  *r;
377                          } else
378                                  addcolor(acol, ar.rcol);
379                  }
380 +        }
381          for (k = 0; k < ne; k++) {              /* compute errors */
382                  if (div[k].n > 1)
383                          div[k].k /= div[k].n;
# Line 366 | Line 393 | register RAY  *r;
393                                                  /* super-sample */
394          for (i = ns; i > 0; i--) {
395                  rayorigin(&ar, r, AMBIENT, 0.5);        /* pretested */
396 <                zd = sqrt((div[0].t+frandom())/nt);
397 <                phi = 2.0*PI * (div[0].p+frandom())/np;
396 >                hlist[1] = div[0].t;
397 >                hlist[2] = div[0].p;
398 >                hlist[3] = 0;
399 >                zd = sqrt((div[0].t+urand(ilhash(hlist,4)+div[0].n))/nt);
400 >                hlist[3] = 1;
401 >                phi = 2.0*PI * (div[0].p+urand(ilhash(hlist,4)+div[0].n))/np;
402                  xd = cos(phi) * zd;
403                  yd = sin(phi) * zd;
404                  zd = sqrt(1.0 - zd*zd);
405                  for (k = 0; k < 3; k++)
406                          ar.rdir[k] = xd*ux[k]+yd*uy[k]+zd*r->ron[k];
407 +                dimlist[ndims++] = div[0].t*np + div[0].p + 38813;
408                  rayvalue(&ar);
409 +                ndims--;
410 +                rayvalue(&ar);
411                  if (ar.rot < FHUGE)
412                          arad += 1.0 / ar.rot;
413                                                  /* recompute error */
# Line 386 | Line 420 | register RAY  *r;
420                  dnew.k = b2/(dnew.n*dnew.n);
421                                                  /* reinsert */
422                  for (k = 0; k < ne-1 && dnew.k < div[k+1].k; k++)
423 <                        bcopy(&div[k+1], &div[k], sizeof(AMBSAMP));
424 <                bcopy(&dnew, &div[k], sizeof(AMBSAMP));
423 >                        copystruct(&div[k], &div[k+1]);
424 >                copystruct(&div[k], &dnew);
425  
426                  if (ne >= i) {          /* extract darkest division */
427                          ne--;
428 <                        if (div[ne].n > 1)
429 <                                scalecolor(div[ne].v, 1.0/div[ne].n);
428 >                        if (div[ne].n > 1) {
429 >                                b = 1.0/div[ne].n;
430 >                                scalecolor(div[ne].v, b);
431 >                                div[ne].n = 1;
432 >                        }
433                          addcolor(acol, div[ne].v);
434                  }
435          }
# Line 405 | Line 442 | register RAY  *r;
442                  arad = maxarad;
443          else if (arad < minarad)
444                  arad = minarad;
445 <        if (ns > 0)
445 >        if (div != NULL)
446                  free((char *)div);
447          return(arad);
448   }
# Line 432 | Line 469 | AMBVAL  *av;
469   #endif
470          if (ambfp == NULL)
471                  return;
472 <        if (fwrite(av, sizeof(AMBVAL), 1, ambfp) != 1)
472 >        if (fwrite((char *)av, sizeof(AMBVAL), 1, ambfp) != 1)
473                  goto writerr;
474   #ifdef  AMBFLUSH
475          if (++nunflshed >= AMBFLUSH) {
# Line 461 | Line 498 | double  s;
498  
499          if ((av = newambval()) == NULL)
500                  goto memerr;
501 <        bcopy(aval, av, sizeof(AMBVAL));
501 >        copystruct(av, aval);
502          VCOPY(ck0, c0);
503          while (s*(OCTSCALE/2) > av->rad*ambacc) {
504                  if (at->kid == NULL)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines