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

Comparing ray/src/rt/ambcomp.c (file contents):
Revision 2.46 by greg, Fri May 2 21:58:50 2014 UTC vs.
Revision 2.47 by greg, Sat May 3 05:46:19 2014 UTC

# Line 23 | Line 23 | static const char      RCSid[] = "$Id$";
23  
24   #ifdef NEWAMB
25  
26 + /* #define HEM_MULT     4.0     /* hem multiplier (bigger => sparser cache) */
27 +
28   extern void             SDsquare2disk(double ds[2], double seedx, double seedy);
29  
30                                  /* vertex direction bit positions */
# Line 50 | Line 52 | static const int  adjacent_trifl[8] = {
52  
53   typedef struct {
54          COLOR   v;              /* hemisphere sample value */
55 +        float   d;              /* reciprocal distance (1/rt) */
56          FVECT   p;              /* intersection point */
57   } AMBSAMP;              /* sample value */
58  
# Line 207 | Line 210 | ambsample(                             /* initial ambient division sample */
210          AMBSAMP *ap = &ambsam(hp,i,j);
211          RAY     ar;
212                                          /* generate hemispherical sample */
213 <        if (!getambsamp(&ar, hp, i, j, 0))
214 <                goto badsample;
215 <                                        /* limit vertex distance */
213 >        if (!getambsamp(&ar, hp, i, j, 0) || ar.rt <= FTINY) {
214 >                memset(ap, 0, sizeof(AMBSAMP));
215 >                return(NULL);
216 >        }
217 >        ap->d = 1.0/ar.rt;              /* limit vertex distance */
218          if (ar.rt > 10.0*thescene.cusize)
219                  ar.rt = 10.0*thescene.cusize;
215        else if (ar.rt <= FTINY)        /* should never happen! */
216                goto badsample;
220          VSUM(ap->p, ar.rorg, ar.rdir, ar.rt);
221          copycolor(ap->v, ar.rcol);
222          return(ap);
220 badsample:
221        setcolor(ap->v, 0., 0., 0.);
222        VCOPY(ap->p, hp->rp->rop);
223        return(NULL);
223   }
224  
225  
# Line 317 | Line 316 | static uby8 *
316   vertex_flags(AMBHEMI *hp)
317   {
318          uby8    *vflags = (uby8 *)calloc(hp->ns*hp->ns, sizeof(uby8));
320        double  *dist2a = (double *)malloc(sizeof(double)*hp->ns);
319          uby8    *vf;
320 +        AMBSAMP *ap;
321          int     i, j;
322  
323 <        if ((vflags == NULL) | (dist2a == NULL))
323 >        if (vflags == NULL)
324                  error(SYSTEM, "out of memory in vertex_flags()");
325 <        vf = vflags;            /* compute distances along first row */
326 <        for (j = 0; j < hp->ns; j++) {
327 <                dist2a[j] = dist2(ambsam(hp,0,j).p, hp->rp->rop);
328 <                ++vf;
329 <                if (!j) continue;
331 <                if (dist2a[j] >= dist2a[j-1])
332 <                        vf[0] |= 1<<VDB_x;
325 >        vf = vflags;
326 >        ap = hp->sa;            /* compute farthest along first row */
327 >        for (j = 0; j < hp->ns-1; j++, vf++, ap++)
328 >                if (ap[0].d <= ap[1].d)
329 >                        vf[0] |= 1<<VDB_X;
330                  else
331 <                        vf[-1] |= 1<<VDB_X;
332 <        }
331 >                        vf[1] |= 1<<VDB_x;
332 >        ++vf; ++ap;
333                                  /* flag subsequent rows */
334          for (i = 1; i < hp->ns; i++) {
335 <            double      d2n = dist2(ambsam(hp,i,0).p, hp->rp->rop);
336 <            for (j = 0; j < hp->ns-1; j++) {
340 <                double  d2 = d2n;
341 <                if (d2 >= dist2a[j])    /* row before */
335 >            for (j = 0; j < hp->ns-1; j++, vf++, ap++) {
336 >                if (ap[0].d <= ap[-hp->ns].d)   /* row before */
337                          vf[0] |= 1<<VDB_y;
338                  else
339                          vf[-hp->ns] |= 1<<VDB_Y;
340 <                dist2a[j] = d2n;
346 <                if (d2 >= dist2a[j+1])  /* diagonal we care about */
340 >                if (ap[0].d <= ap[1-hp->ns].d)  /* diagonal we care about */
341                          vf[0] |= 1<<VDB_Xy;
342                  else
343                          vf[1-hp->ns] |= 1<<VDB_xY;
344 <                d2n = dist2(ambsam(hp,i,j+1).p, hp->rp->rop);
351 <                if (d2 >= d2n)          /* column after */
344 >                if (ap[0].d <= ap[1].d)         /* column after */
345                          vf[0] |= 1<<VDB_X;
346                  else
347                          vf[1] |= 1<<VDB_x;
355                ++vf;
348              }
349 <            if (d2n >= dist2a[j])       /* final column edge */
349 >            if (ap[0].d <= ap[-hp->ns].d)       /* final column edge */
350                  vf[0] |= 1<<VDB_y;
351              else
352                  vf[-hp->ns] |= 1<<VDB_Y;
353 <            dist2a[j] = d2n;
362 <            ++vf;
353 >            ++vf; ++ap;
354          }
364        free(dist2a);
355          return(vflags);
356   }
357  
# Line 730 | Line 720 | ambdirgrad(AMBHEMI *hp, FVECT uv[2], float dg[2])
720   }
721  
722  
723 + /* Make sure radii don't extend beyond what we see in our periphery */
724 + static void
725 + hem_radii(AMBHEMI *hp, FVECT uv[2], float ra[2])
726 + {
727 + #ifdef HEM_MULT
728 +        double          udsum = 0, vdsum = 0;
729 +        double          uwsum = 0, vwsum = 0;
730 +        int             i, j;
731 +                                        /* circle around perimeter */
732 +        for (i = 0; i < hp->ns; i++)
733 +            for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) {
734 +                AMBSAMP *ap = &ambsam(hp,i,j);
735 +                FVECT   vec;
736 +                double  us2, vs2;
737 +                VSUB(vec, ap->p, hp->rp->rop);
738 +                us2 = DOT(vec, uv[0]) * ap->d;
739 +                us2 *= us2;
740 +                vs2 = DOT(vec, uv[1]) * ap->d;
741 +                vs2 *= vs2;
742 +                udsum += us2 * ap->d;
743 +                uwsum += us2;
744 +                vdsum += vs2 * ap->d;
745 +                vwsum += vs2;
746 +            }
747 +        uwsum *= HEM_MULT;              /* adjust effective hem size */
748 +        vwsum *= HEM_MULT;
749 +                                        /* cap radii (recall d=1/rt) */
750 +        if (ra[0]*udsum > uwsum)
751 +                ra[0] = uwsum/udsum;
752 +        if (ra[1]*vdsum > vwsum)
753 +                ra[1] = vwsum/vdsum;
754 + #endif
755 + }
756 +
757 +
758   int
759   doambient(                              /* compute ambient component */
760          COLOR   rcol,                   /* input/output color */
# Line 811 | Line 836 | doambient(                             /* compute ambient component */
836                                  ra[0] = 1.0/d;
837                          if (ra[1]*(d = fabs(pg[1])) > 1.0)
838                                  ra[1] = 1.0/d;
814                        if (ra[0] > ra[1])
815                                ra[0] = ra[1];
839                  }
840 +                hem_radii(hp, uv, ra);
841 +                if (ra[0] > ra[1])
842 +                        ra[0] = ra[1];
843                  if (ra[0] < minarad) {
844                          ra[0] = minarad;
845                          if (ra[1] < minarad)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines