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

Comparing ray/src/rt/m_wgmdf.c (file contents):
Revision 2.1 by greg, Mon Dec 9 00:44:29 2024 UTC vs.
Revision 2.13 by greg, Fri Jun 20 16:48:39 2025 UTC

# Line 94 | Line 94 | typedef struct {
94          RAY             *rp;            /* ray pointer */
95          OBJREC          *mtp;           /* material pointer */
96          MFUNC           *mf;            /* pointer to expression list */
97 +        OBJECT          mto;            /* material object index (or -2) */
98          int             specfl;         /* specularity flags, defined above */
99          FVECT           ulocal;         /* u-vector in local coordinates */
100          DCOMP           rd, td;         /* diffuse component params */
# Line 101 | Line 102 | typedef struct {
102          FVECT           prdir;          /* vector in transmitted direction */
103   } WGMDDAT;              /* WGMD material data */
104  
105 < #define clr_comps(wp)   ((wp)->specfl = 0, \
105 > #define clr_comps(wp)   ((wp)->specfl = 0, (wp)->mto = OVOID-1, \
106                          (wp)->rd.mo.nam = (wp)->td.mo.nam = \
107                          (wp)->rs.mo.nam = (wp)->ts.mo.nam = "")
108  
# Line 133 | Line 134 | set_modval(MODVAL *mp, OBJECT omod, const RAY *r)
134  
135   /* fill modifier values, using previous setting if found */
136   static int
137 < fill_modval(MODVAL *mp, const WGMDDAT *wp)
137 > fill_modval(MODVAL *mp, WGMDDAT *wp)
138   {
139          if (mp == &wp->rd.mo) {         /* special case (should be first) */
140                  set_modval(mp, wp->mtp->omod, wp->rp);
# Line 154 | Line 155 | fill_modval(MODVAL *mp, const WGMDDAT *wp)
155          if (mp != &wp->ts.mo && !strcmp(mp->nam, wp->ts.mo.nam)) {
156                  *mp = wp->ts.mo;
157                  return(1);
158 <        }                               /* new modifier */
159 <        return(set_modval(mp, lastmod(objndx(wp->mtp), mp->nam), wp->rp));
158 >        }
159 >        if (wp->mto < OVOID)
160 >                wp->mto = objndx(wp->mtp);
161 >                                        /* new modifier */
162 >        return(set_modval(mp, lastmod(wp->mto, mp->nam), wp->rp));
163   }
164  
165 + /* set calculation context for given component of MAT_WGMDF */
166 + static int
167 + setWGMDfunc(MODVAL *mp, const WGMDDAT *wp)
168 + {
169 +        static char     lastMod[MAXSTR];
170 +        double          sf;
171 +        FVECT           vec;
172 +
173 +        if (setfunc(wp->mtp, wp->rp) == 0 &&
174 +                        !strcmp(mp->nam, lastMod))
175 +                return(0);      /* already set */
176 +        strcpy(lastMod, mp->nam);
177 +                                /* else (re)assign special variables */
178 +        sf = 1 - 2*(wp->rp->rod < 0);
179 +        varset("RdotP`", '=', mp->pdot*sf);
180 +        multv3(vec, mp->pnorm, funcxf.xfm);
181 +        sf /= funcxf.sca;
182 +        varset("NxP`", '=', vec[0]*sf);
183 +        varset("NyP`", '=', vec[1]*sf);
184 +        varset("NzP`", '=', vec[2]*sf);
185 +        return(1);
186 + }
187 +
188   /* assign indicated diffuse component (do !trans first) */
189   static void
190   set_dcomp(WGMDDAT *wp, int trans)
# Line 190 | Line 217 | set_dcomp(WGMDDAT *wp, int trans)
217   static void
218   set_scomp(WGMDDAT *wp, int trans)
219   {
220 <        SCOMP           *sp = trans ? &wp->ts : &wp->rs;
221 <        const int       eoff = 3*(trans != 0);
222 <        double          coef;
223 <
224 <        setfunc(wp->mtp, wp->rp);       /* get coefficient, first */
225 <        errno = 0;
226 <        coef = evalue(wp->mf->ep[eoff]);
200 <        if ((errno == EDOM) | (errno == ERANGE)) {
201 <                objerror(wp->mtp, WARNING, "specular compute error");
202 <                scolorblack(sp->scol);
203 <                return;
204 <        }
205 <        if (coef <= FTINY) {            /* negligible value? */
206 <                scolorblack(sp->scol);
207 <                return;
208 <        }                               /* else get modifier */
220 >        SCOMP   *sp = trans ? &wp->ts : &wp->rs;
221 >        EPNODE  **exa = wp->mf->ep + 3*(trans != 0);
222 >        double  coef;
223 >                                        /* constant zero check */
224 >        if (exa[0]->type == NUM && exa[0]->v.num <= FTINY)
225 >                goto blackout;
226 >                                        /* need modifier */
227          sp->mo.nam = wp->mtp->oargs.sarg[4*(trans != 0)];
228          if (!fill_modval(&sp->mo, wp)) {
229                  sprintf(errmsg, "unknown specular %s modifier '%s'",
230                          trans ? "transmission" : "reflection", sp->mo.nam);
231                  objerror(wp->mtp, USER, errmsg);
232          }
233 +        if (sintens(sp->mo.pcol) <= FTINY)
234 +                goto blackout;          /* got black pattern */
235 +        setWGMDfunc(&sp->mo, wp);       /* else compute coefficient */
236 +        errno = 0;
237 +        coef = evalue(exa[0]);
238 +        if ((errno == EDOM) | (errno == ERANGE)) {
239 +                objerror(wp->mtp, WARNING, "specular compute error");
240 +                goto blackout;
241 +        }
242 +        if (coef <= FTINY)              /* negligible value? */
243 +                goto blackout;
244          copyscolor(sp->scol, sp->mo.pcol);
245          scalescolor(sp->scol, coef);
246 <        if (sintens(sp->scol) <= FTINY) {
247 <                scolorblack(sp->scol);
248 <                return;                 /* got black pattern */
220 <        }
221 <        setfunc(wp->mtp, wp->rp);       /* else get roughness */
222 <        errno = 0;
223 <        sp->u_alpha = evalue(wp->mf->ep[eoff+1]);
224 <        sp->v_alpha = (sp->u_alpha > FTINY) ? evalue(wp->mf->ep[eoff+2]) : 0.0;
246 >        errno = 0;                      /* else get roughness */
247 >        sp->u_alpha = evalue(exa[1]);
248 >        sp->v_alpha = (sp->u_alpha > FTINY) ? evalue(exa[2]) : 0.0;
249          if ((errno == EDOM) | (errno == ERANGE)) {
250                  objerror(wp->mtp, WARNING, "roughness compute error");
251 <                scolorblack(sp->scol);
228 <                return;
251 >                goto blackout;
252          }                               /* we have something... */
253          wp->specfl |= trans ? SP_TRAN : SP_REFL;
254          if (sp->v_alpha <= FTINY) {     /* is it pure specular? */
255                  wp->specfl |= trans ? SP_TPURE : SP_RPURE;
256                  sp->u_alpha = sp->v_alpha = 0.0;
257                  return;
258 <        }
236 <                                        /* get anisotropic coordinates */
258 >        }                               /* else get aniso coordinates */
259          fcross(sp->v, sp->mo.pnorm, wp->ulocal);
260          if (normalize(sp->v) == 0.0) {  /* orientation vector==normal? */
261                  if (fabs(sp->u_alpha - sp->v_alpha) > 0.001)
262                          objerror(wp->mtp, WARNING, "bad orientation vector");
263 <                getperpendicular(sp->u, sp->mo.pnorm, 1);       /* punting */
263 >                getperpendicular(sp->u, sp->mo.pnorm, 0);       /* punting */
264                  fcross(sp->v, sp->mo.pnorm, sp->u);
265                  sp->u_alpha = sp->v_alpha = sqrt( 0.5 *
266                          (sp->u_alpha*sp->u_alpha + sp->v_alpha*sp->v_alpha) );
267          } else
268                  fcross(sp->u, sp->v, sp->mo.pnorm);
269 +        return;
270 + blackout:
271 +        scolorblack(sp->scol);          /* zero out component */
272   }
273  
274   /* sample anisotropic Gaussian specular */
# Line 273 | Line 298 | agaussamp(WGMDDAT *wp)
298                                  nstarget = 1;
299                  }
300                  scolorblack(scol);
301 <                dimlist[ndims++] = (int)(size_t)wp->mtp;
301 >                dimlist[ndims_inc] = (int)(size_t)wp->mtp;
302                  maxiter = MAXITER*nstarget;
303                  for (nstaken = ntrials = 0; (nstaken < nstarget) &
304                                                  (ntrials < maxiter); ntrials++) {
# Line 322 | Line 347 | agaussamp(WGMDDAT *wp)
347                          scalescolor(scol, d);
348                          saddscolor(wp->rp->rcol, scol);
349                  }
350 <                ndims--;
350 >                dec_ndims;
351          }
352                                          /* compute transmission */
353          if ((wp->specfl & (SP_TRAN|SP_TPURE|SP_TBLT)) == SP_TRAN &&
# Line 339 | Line 364 | agaussamp(WGMDDAT *wp)
364                          } else
365                                  nstarget = 1;
366                  }
367 <                dimlist[ndims++] = (int)(size_t)wp->mtp;
367 >                dimlist[ndims_inc] = (int)(size_t)wp->mtp;
368                  maxiter = MAXITER*nstarget;
369                  for (nstaken = ntrials = 0; (nstaken < nstarget) &
370                                                  (ntrials < maxiter); ntrials++) {
# Line 376 | Line 401 | agaussamp(WGMDDAT *wp)
401                          saddscolor(wp->rp->rcol, sr.rcol);
402                          ++nstaken;
403                  }
404 <                ndims--;
404 >                dec_ndims;
405          }
406   }
407  
# Line 431 | Line 456 | dirwgmdf(SCOLOR scval, void *uwp, FVECT ldir, double o
456                   */
457                                                  /* add source width if flat */
458                  if (wp->specfl & SP_FLAT)
459 <                        au2 = av2 = omega * (0.25/PI);
459 >                        au2 = av2 = (1. - dstrsrc) * omega * (0.25/PI);
460                  else
461                          au2 = av2 = 0.0;
462                  au2 += wp->rs.u_alpha*wp->rs.u_alpha;
# Line 510 | Line 535 | m_wgmdf(OBJREC *m, RAY *r)
535          }
536          if ((m->oargs.nsargs < 13) | (m->oargs.nfargs < 9))
537                  objerror(m, USER, "bad number of arguments");
538 +
539 +        if (r->crtype & SHADOW && !strcmp(m->oargs.sarg[5], "0"))
540 +                return(1);              /* first shadow test */
541          clr_comps(&wd);
542          wd.rp = r;
543          wd.mtp = m;
544          wd.mf = getfunc(m, 12, 0xEEE, 1);
545 <        setfunc(m, r);                  /* get local u vector */
545 >        set_dcomp(&wd, 0);              /* gets main modifier */
546 >        setWGMDfunc(&wd.rd.mo, &wd);    /* get local u vector */
547          errno = 0;
548          for (i = 0; i < 3; i++)
549                  wd.ulocal[i] = evalue(wd.mf->ep[6+i]);
# Line 523 | Line 552 | m_wgmdf(OBJREC *m, RAY *r)
552          else if (wd.mf->fxp != &unitxf)
553                  multv3(wd.ulocal, wd.ulocal, wd.mf->fxp->xfm);
554  
526        set_dcomp(&wd, 0);              /* call this first */
527        set_dcomp(&wd, 1);              /* call this second */
555          set_scomp(&wd, 1);              /* sets SP_TPURE */
556          if (r->crtype & SHADOW && !(wd.specfl & SP_TPURE))
557 <                return(1);              /* early shadow test */
557 >                return(1);              /* second shadow test */
558 >        set_dcomp(&wd, 1);
559          set_scomp(&wd, 0);
560 <        wd.specfl |= SP_FLAT*(r->ro != NULL && isflat(r->ro->otype));
560 >        wd.specfl |= SP_FLAT*(!wd.rs.mo.hastexture &&
561 >                                r->ro != NULL && isflat(r->ro->otype));
562                                          /* apply Fresnel adjustments? */
563          if (wd.specfl & SP_RPURE && pbright(wd.rs.scol) >= FRESTHRESH) {
564                  const double    fest = FRESNE(fabs(wd.rs.mo.pdot));
565                  for (i = NCSAMP; i--; )
566                          wd.rs.scol[i] += fest*(1. - wd.rs.scol[i]);
567 +                scalescolor(wd.rd.scol, 1.-fest);
568                  scalescolor(wd.ts.scol, 1.-fest);
569                  scalescolor(wd.td.scol, 1.-fest);
570          }
# Line 587 | Line 617 | m_wgmdf(OBJREC *m, RAY *r)
617                  copyscolor(r->mcol, lr.rcol);
618                  saddscolor(r->rcol, lr.rcol);
619                  r->rmt = r->rot;
620 <                if (wd.specfl & SP_FLAT &&
591 <                                !wd.rs.mo.hastexture | (r->crtype & AMBIENT))
620 >                if (wd.specfl & SP_FLAT && r->crtype & AMBIENT)
621                          r->rmt += raydistance(&lr);
622          }
623          if (wd.specfl & (SP_REFL|SP_TRAN))      /* specularly scattered rays */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines