23 |
|
|
24 |
|
#ifdef NEWAMB |
25 |
|
|
26 |
– |
/* #define HEM_MULT 4.0 /* hem multiplier (bigger => sparser cache) */ |
27 |
– |
|
26 |
|
extern void SDsquare2disk(double ds[2], double seedx, double seedy); |
27 |
|
|
28 |
|
/* vertex direction bit positions */ |
718 |
|
} |
719 |
|
|
720 |
|
|
721 |
< |
/* Make sure radii don't extend beyond what we see in our periphery */ |
722 |
< |
static void |
723 |
< |
hem_radii(AMBHEMI *hp, FVECT uv[2], float ra[2]) |
721 |
> |
/* Compute potential light leak direction flags for cache value */ |
722 |
> |
static uint32 |
723 |
> |
ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, const double r1) |
724 |
|
{ |
725 |
< |
#ifdef HEM_MULT |
726 |
< |
double udsum = 0, vdsum = 0; |
729 |
< |
double uwsum = 0, vwsum = 0; |
730 |
< |
int i, j; |
725 |
> |
uint32 flgs = 0; |
726 |
> |
int i, j; |
727 |
|
/* circle around perimeter */ |
728 |
|
for (i = 0; i < hp->ns; i++) |
729 |
|
for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) { |
730 |
|
AMBSAMP *ap = &ambsam(hp,i,j); |
731 |
|
FVECT vec; |
732 |
< |
double us2, vs2; |
732 |
> |
double u, v; |
733 |
> |
double ang; |
734 |
> |
int abp; |
735 |
> |
if (ap->d <= FTINY) |
736 |
> |
continue; |
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; |
738 |
> |
u = DOT(vec, uv[0]) * ap->d; |
739 |
> |
v = DOT(vec, uv[1]) * ap->d; |
740 |
> |
if ((r0*r0*u*u + r1*r1*v*v) * ap->d*ap->d <= 1.0) |
741 |
> |
continue; /* occluder outside ellipse */ |
742 |
> |
ang = atan2a(v, u); /* else set direction flags */ |
743 |
> |
ang += 2.0*PI*(ang < 0); |
744 |
> |
ang *= 16./PI; |
745 |
> |
if ((ang < .5) | (ang >= 31.5)) |
746 |
> |
flgs |= 0x80000001; |
747 |
> |
else |
748 |
> |
flgs |= 3L<<(int)(ang-.5); |
749 |
|
} |
750 |
< |
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 |
750 |
> |
return(flgs); |
751 |
|
} |
752 |
|
|
753 |
|
|
759 |
|
FVECT uv[2], /* returned (optional) */ |
760 |
|
float ra[2], /* returned (optional) */ |
761 |
|
float pg[2], /* returned (optional) */ |
762 |
< |
float dg[2] /* returned (optional) */ |
762 |
> |
float dg[2], /* returned (optional) */ |
763 |
> |
uint32 *crlp /* returned (optional) */ |
764 |
|
) |
765 |
|
{ |
766 |
|
AMBHEMI *hp = inithemi(rcol, r, wt); |
780 |
|
pg[0] = pg[1] = 0.0; |
781 |
|
if (dg != NULL) |
782 |
|
dg[0] = dg[1] = 0.0; |
783 |
+ |
if (crlp != NULL) |
784 |
+ |
*crlp = 0; |
785 |
|
/* sample the hemisphere */ |
786 |
|
acol[0] = acol[1] = acol[2] = 0.0; |
787 |
|
cnt = 0; |
835 |
|
ra[0] = 1.0/d; |
836 |
|
if (ra[1]*(d = fabs(pg[1])) > 1.0) |
837 |
|
ra[1] = 1.0/d; |
838 |
+ |
if (ra[0] > ra[1]) |
839 |
+ |
ra[0] = ra[1]; |
840 |
|
} |
840 |
– |
hem_radii(hp, uv, ra); |
841 |
– |
if (ra[0] > ra[1]) |
842 |
– |
ra[0] = ra[1]; |
841 |
|
if (ra[0] < minarad) { |
842 |
|
ra[0] = minarad; |
843 |
|
if (ra[1] < minarad) |
851 |
|
if (ra[0] > maxarad) |
852 |
|
ra[0] = maxarad; |
853 |
|
} |
854 |
+ |
if (crlp != NULL) /* flag encroached directions */ |
855 |
+ |
*crlp = ambcorral(hp, uv, ra[0]*ambacc, ra[1]*ambacc); |
856 |
|
if (pg != NULL) { /* cap gradient if necessary */ |
857 |
|
d = pg[0]*pg[0]*ra[0]*ra[0] + pg[1]*pg[1]*ra[1]*ra[1]; |
858 |
|
if (d > 1.0) { |