| 21 |
|
|
| 22 |
|
/* |
| 23 |
|
* This routine implements the anisotropic Gaussian |
| 24 |
< |
* model described by Ward in Siggraph `92 article. |
| 24 |
> |
* model described by Ward in Siggraph `92 article, updated with |
| 25 |
> |
* normalization and sampling adjustments due to Geisler-Moroder and Duer. |
| 26 |
|
* We orient the surface towards the incoming ray, so a single |
| 27 |
|
* surface can be used to represent an infinitely thin object. |
| 28 |
|
* |
| 29 |
|
* Arguments for MAT_PLASTIC2 and MAT_METAL2 are: |
| 30 |
|
* 4+ ux uy uz funcfile [transform...] |
| 31 |
|
* 0 |
| 32 |
< |
* 6 red grn blu specular-frac. u-facet-slope v-facet-slope |
| 32 |
> |
* 6 red grn blu specular-frac. u-rough v-rough |
| 33 |
|
* |
| 34 |
|
* Real arguments for MAT_TRANS2 are: |
| 35 |
|
* 8 red grn blu rspec u-rough v-rough trans tspec |
| 61 |
|
double pdot; /* perturbed dot product */ |
| 62 |
|
} ANISODAT; /* anisotropic material data */ |
| 63 |
|
|
| 63 |
– |
static srcdirf_t diraniso; |
| 64 |
|
static void getacoords(RAY *r, ANISODAT *np); |
| 65 |
|
static void agaussamp(RAY *r, ANISODAT *np); |
| 66 |
|
|
| 68 |
|
static void |
| 69 |
|
diraniso( /* compute source contribution */ |
| 70 |
|
COLOR cval, /* returned coefficient */ |
| 71 |
< |
void *nnp, /* material data */ |
| 71 |
> |
void *nnp, /* material data */ |
| 72 |
|
FVECT ldir, /* light source direction */ |
| 73 |
|
double omega /* light source size */ |
| 74 |
|
) |
| 75 |
|
{ |
| 76 |
< |
register ANISODAT *np = nnp; |
| 76 |
> |
ANISODAT *np = nnp; |
| 77 |
|
double ldot; |
| 78 |
|
double dtmp, dtmp1, dtmp2; |
| 79 |
|
FVECT h; |
| 87 |
|
if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY) |
| 88 |
|
return; /* wrong side */ |
| 89 |
|
|
| 90 |
< |
if (ldot > FTINY && np->rdiff > FTINY) { |
| 90 |
> |
if ((ldot > FTINY) & (np->rdiff > FTINY)) { |
| 91 |
|
/* |
| 92 |
|
* Compute and add diffuse reflected component to returned |
| 93 |
|
* color. The diffuse reflected component will always be |
| 111 |
|
au2 += np->u_alpha*np->u_alpha; |
| 112 |
|
av2 += np->v_alpha*np->v_alpha; |
| 113 |
|
/* half vector */ |
| 114 |
< |
h[0] = ldir[0] - np->rp->rdir[0]; |
| 115 |
< |
h[1] = ldir[1] - np->rp->rdir[1]; |
| 116 |
< |
h[2] = ldir[2] - np->rp->rdir[2]; |
| 114 |
> |
VSUB(h, ldir, np->rp->rdir); |
| 115 |
|
/* ellipse */ |
| 116 |
|
dtmp1 = DOT(np->u, h); |
| 117 |
|
dtmp1 *= dtmp1 / au2; |
| 131 |
|
addcolor(cval, ctmp); |
| 132 |
|
} |
| 133 |
|
} |
| 134 |
< |
if (ldot < -FTINY && np->tdiff > FTINY) { |
| 134 |
> |
if ((ldot < -FTINY) & (np->tdiff > FTINY)) { |
| 135 |
|
/* |
| 136 |
|
* Compute diffuse transmission. |
| 137 |
|
*/ |
| 150 |
|
au2 += np->u_alpha*np->u_alpha; |
| 151 |
|
av2 += np->v_alpha*np->v_alpha; |
| 152 |
|
/* "half vector" */ |
| 153 |
< |
h[0] = ldir[0] - np->prdir[0]; |
| 156 |
< |
h[1] = ldir[1] - np->prdir[1]; |
| 157 |
< |
h[2] = ldir[2] - np->prdir[2]; |
| 153 |
> |
VSUB(h, ldir, np->prdir); |
| 154 |
|
dtmp = DOT(h,h); |
| 155 |
|
if (dtmp > FTINY*FTINY) { |
| 156 |
|
dtmp1 = DOT(h,np->pnorm); |
| 177 |
|
} |
| 178 |
|
|
| 179 |
|
|
| 180 |
< |
extern int |
| 180 |
> |
int |
| 181 |
|
m_aniso( /* shade ray that hit something anisotropic */ |
| 182 |
< |
register OBJREC *m, |
| 183 |
< |
register RAY *r |
| 182 |
> |
OBJREC *m, |
| 183 |
> |
RAY *r |
| 184 |
|
) |
| 185 |
|
{ |
| 186 |
|
ANISODAT nd; |
| 187 |
|
COLOR ctmp; |
| 188 |
< |
register int i; |
| 188 |
> |
int i; |
| 189 |
|
/* easy shadow test */ |
| 190 |
|
if (r->crtype & SHADOW) |
| 191 |
|
return(1); |
| 212 |
|
nd.specfl = 0; |
| 213 |
|
nd.u_alpha = m->oargs.farg[4]; |
| 214 |
|
nd.v_alpha = m->oargs.farg[5]; |
| 215 |
< |
if (nd.u_alpha <= FTINY || nd.v_alpha <= FTINY) |
| 215 |
> |
if ((nd.u_alpha <= FTINY) | (nd.v_alpha <= FTINY)) |
| 216 |
|
objerror(m, USER, "roughness too small"); |
| 217 |
|
|
| 218 |
|
nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ |
| 305 |
|
static void |
| 306 |
|
getacoords( /* set up coordinate system */ |
| 307 |
|
RAY *r, |
| 308 |
< |
register ANISODAT *np |
| 308 |
> |
ANISODAT *np |
| 309 |
|
) |
| 310 |
|
{ |
| 311 |
< |
register MFUNC *mf; |
| 312 |
< |
register int i; |
| 311 |
> |
MFUNC *mf; |
| 312 |
> |
int i; |
| 313 |
|
|
| 314 |
|
mf = getfunc(np->mp, 3, 0x7, 1); |
| 315 |
|
setfunc(np->mp, r); |
| 316 |
|
errno = 0; |
| 317 |
|
for (i = 0; i < 3; i++) |
| 318 |
|
np->u[i] = evalue(mf->ep[i]); |
| 319 |
< |
if (errno == EDOM || errno == ERANGE) { |
| 319 |
> |
if ((errno == EDOM) | (errno == ERANGE)) { |
| 320 |
|
objerror(np->mp, WARNING, "compute error"); |
| 321 |
|
np->specfl |= SP_BADU; |
| 322 |
|
return; |
| 336 |
|
static void |
| 337 |
|
agaussamp( /* sample anisotropic Gaussian specular */ |
| 338 |
|
RAY *r, |
| 339 |
< |
register ANISODAT *np |
| 339 |
> |
ANISODAT *np |
| 340 |
|
) |
| 341 |
|
{ |
| 342 |
|
RAY sr; |
| 345 |
|
double d, sinp, cosp; |
| 346 |
|
COLOR scol; |
| 347 |
|
int maxiter, ntrials, nstarget, nstaken; |
| 348 |
< |
register int i; |
| 348 |
> |
int i; |
| 349 |
|
/* compute reflection */ |
| 350 |
|
if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL && |
| 351 |
|
rayorigin(&sr, SPECULAR, r, np->scolor) == 0) { |