--- ray/src/rt/raytrace.c 2005/04/14 18:04:12 2.47 +++ ray/src/rt/raytrace.c 2005/04/19 01:15:06 2.49 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: raytrace.c,v 2.47 2005/04/14 18:04:12 greg Exp $"; +static const char RCSid[] = "$Id: raytrace.c,v 2.49 2005/04/19 01:15:06 greg Exp $"; #endif /* * raytrace.c - routines for tracing and shading rays. @@ -36,29 +36,37 @@ static void checkset(OBJECT *os, OBJECT *cs); extern int rayorigin( /* start new ray from old one */ - register RAY *r, - register RAY *ro, + RAY *r, int rt, - double rw + const RAY *ro, + const COLOR rc ) { - double re; - + double rw, re; + /* assign coefficient/weight */ + if (rc == NULL) { + rw = 1.0; + setcolor(r->rcoef, 1., 1., 1.); + } else { + rw = intens(rc); + if (rc != r->rcoef) + copycolor(r->rcoef, rc); + } if ((r->parent = ro) == NULL) { /* primary ray */ r->rlvl = 0; r->rweight = rw; r->crtype = r->rtype = rt; r->rsrc = -1; r->clipset = NULL; - r->revf = raytrace; copycolor(r->cext, cextinction); copycolor(r->albedo, salbedo); r->gecc = seccg; r->slights = NULL; - } else if (ro->rot >= FHUGE) { /* illegal continuation */ - memset(r, 0, sizeof(RAY)); - return(-1); } else { /* spawned ray */ + if (ro->rot >= FHUGE) { + memset(r, 0, sizeof(RAY)); + return(-1); /* illegal continuation */ + } r->rlvl = ro->rlvl; if (rt & RAYREFL) { r->rlvl++; @@ -70,7 +78,6 @@ rayorigin( /* start new ray from old one */ r->clipset = ro->newcset; r->rmax = ro->rmax <= FTINY ? 0.0 : ro->rmax - ro->rot; } - r->revf = ro->revf; copycolor(r->cext, ro->cext); copycolor(r->albedo, ro->albedo); r->gecc = ro->gecc; @@ -78,12 +85,13 @@ rayorigin( /* start new ray from old one */ r->crtype = ro->crtype | (r->rtype = rt); VCOPY(r->rorg, ro->rop); r->rweight = ro->rweight * rw; - /* estimate absorption */ + /* estimate extinction */ re = colval(ro->cext,RED) < colval(ro->cext,GRN) ? colval(ro->cext,RED) : colval(ro->cext,GRN); if (colval(ro->cext,BLU) < re) re = colval(ro->cext,BLU); - if (re > 0.) - r->rweight *= exp(-re*ro->rot); + re *= ro->rot; + if (re > .1) + r->rweight *= exp(-re); } rayclear(r); return(r->rlvl <= maxdepth && r->rweight >= minweight ? 0 : -1); @@ -110,7 +118,7 @@ rayclear( /* clear a ray for (re)evaluation */ extern void -raytrace( /* trace a ray and compute its value */ +rayvalue( /* trace a ray and compute its value */ RAY *r ) { @@ -122,10 +130,10 @@ raytrace( /* trace a ray and compute its value */ } else if (sourcehit(r)) rayshade(r, r->ro->omod); /* distant source */ - rayparticipate(r); /* for participating medium */ - if (trace != NULL) (*trace)(r); /* trace execution */ + + rayparticipate(r); /* for participating medium */ } @@ -147,7 +155,7 @@ raytrans( /* transmit ray as is */ { RAY tr; - if (rayorigin(&tr, r, TRANS, 1.0) == 0) { + if (rayorigin(&tr, TRANS, r, NULL) == 0) { VCOPY(tr.rdir, r->rdir); rayvalue(&tr); copycolor(r->rcol, tr.rcol); @@ -209,10 +217,10 @@ rayparticipate( /* compute ray medium participation ge *= 1. - colval(r->albedo,GRN); be *= 1. - colval(r->albedo,BLU); } - setcolor(ce, re<=0. ? 1. : re>92. ? 0. : exp(-re), - ge<=0. ? 1. : ge>92. ? 0. : exp(-ge), - be<=0. ? 1. : be>92. ? 0. : exp(-be)); - multcolor(r->rcol, ce); /* path absorption */ + setcolor(ce, re<=FTINY ? 1. : re>92. ? 0. : exp(-re), + ge<=FTINY ? 1. : ge>92. ? 0. : exp(-ge), + be<=FTINY ? 1. : be>92. ? 0. : exp(-be)); + multcolor(r->rcol, ce); /* path extinction */ if (r->crtype & SHADOW || intens(r->albedo) <= FTINY) return; /* no scattering */ setcolor(ca, @@ -305,7 +313,7 @@ raymixture( /* mix modifiers */ extern double raydist( /* compute (cumulative) ray distance */ - register RAY *r, + register const RAY *r, register int flags ) { @@ -319,6 +327,34 @@ raydist( /* compute (cumulative) ray distance */ } +extern void +raycontrib( /* compute (cumulative) ray contribution */ + COLOR rc, + const RAY *r, + int flags +) +{ + COLOR eext, ext1; + + setcolor(eext, 0., 0., 0.); + setcolor(rc, 1., 1., 1.); + + while (r != NULL && r->crtype&flags) { + multcolor(rc, r->rcoef); + copycolor(ext1, r->cext); + scalecolor(ext1, r->rot); + addcolor(eext, ext1); + r = r->parent; + } + if (intens(eext) > FTINY) { + setcolor(ext1, exp(-colval(eext,RED)), + exp(-colval(eext,GRN)), + exp(-colval(eext,BLU))); + multcolor(rc, ext1); + } +} + + extern double raynormal( /* compute perturbed normal for ray */ FVECT norm, @@ -365,7 +401,7 @@ newrayxf( /* get new tranformation matrix for ray */ FULLXF xf; } xfseed = { &xfseed }, *xflast = &xfseed; register struct xfn *xp; - register RAY *rp; + register const RAY *rp; /* * Search for transform in circular list that