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.6 by greg, Tue Aug 8 17:31:23 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)) */
25  
24 #define  WDONE          4       /* stop if wsum/wmin is at or above */
25
26   extern CUBE  thescene;          /* contains space boundaries */
27  
28   extern COLOR  ambval;           /* global ambient component */
# Line 34 | 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 76 | Line 81 | setambient(afile)                      /* initialize calculation */
81   char  *afile;
82   {
83          long  ftell();
79        char  **amblp;
80        OBJECT  obj;
84          AMBVAL  amb;
85 <                                        /* set up ambient set */
83 <        ambset[0] = 0;
84 <        for (amblp = amblist; *amblp != NULL; amblp++) {
85 <                if ((obj = modifier(*amblp)) == OVOID) {
86 <                        sprintf(errmsg, "unknown %s modifier \"%s\"",
87 <                                ambincl ? "include" : "exclude", *amblp);
88 <                        error(WARNING, errmsg);
89 <                        continue;
90 <                }
91 <                if (!inset(ambset, obj))
92 <                        insertelem(ambset, obj);
93 <        }
85 >
86          maxarad = thescene.cusize / 2.0;                /* maximum radius */
87                                                          /* minimum radius */
88          minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
# Line 98 | 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 111 | 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 166 | Line 180 | double  s;
180          int  i;
181          register int  j;
182          register AMBVAL  *av;
183 <
183 >                                        /* do this node */
184          wsum = 0.0;
171                                        /* check children first */
172        if (at->kid != NULL) {
173                s *= 0.5;
174                for (i = 0; i < 8; i++) {
175                        for (j = 0; j < 3; j++) {
176                                ck0[j] = c0[j];
177                                if (1<<j & i)
178                                        ck0[j] += s;
179                                if (r->rop[j] < ck0[j] - OCTSCALE*s)
180                                        break;
181                                if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
182                                        break;
183                        }
184                        if (j == 3)
185                                wsum += sumambient(acol, r, at->kid+i, ck0, s);
186                }
187                if (wsum*ambacc >= WDONE)
188                        return(wsum);           /* close enough */
189        }
190                                        /* check this node */
185          for (av = at->alist; av != NULL; av = av->next) {
186                  /*
187                   *  Ray strength test.
# Line 219 | 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.
220                   */
221                  wt = sqrt(e1) + sqrt(e2);
222 <                wt *= 0.9 + 0.2*frandom();
222 >                wt *= .9 + .2*frandom();
223                  if (wt > ambacc)
224                          continue;
225                  if (wt <= 1e-3)
# Line 237 | Line 231 | double  s;
231                  scalecolor(ct, wt);
232                  addcolor(acol, ct);
233          }
234 +        if (at->kid == NULL)
235 +                return(wsum);
236 +                                        /* do children */
237 +        s *= 0.5;
238 +        for (i = 0; i < 8; i++) {
239 +                for (j = 0; j < 3; j++) {
240 +                        ck0[j] = c0[j];
241 +                        if (1<<j & i)
242 +                                ck0[j] += s;
243 +                        if (r->rop[j] < ck0[j] - OCTSCALE*s)
244 +                                break;
245 +                        if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
246 +                                break;
247 +                }
248 +                if (j == 3)
249 +                        wsum += sumambient(acol, r, at->kid+i, ck0, s);
250 +        }
251          return(wsum);
252   }
253  
# Line 271 | 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 295 | 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 305 | 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 356 | 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 371 | 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 391 | 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 410 | 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 437 | 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 466 | 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