--- ray/src/rt/rv2.c 2012/09/06 00:07:43 2.63 +++ ray/src/rt/rv2.c 2025/04/22 15:47:47 2.77 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rv2.c,v 2.63 2012/09/06 00:07:43 greg Exp $"; +static const char RCSid[] = "$Id: rv2.c,v 2.77 2025/04/22 15:47:47 greg Exp $"; #endif /* * rv2.c - command routines used in tracing a view. @@ -16,9 +16,9 @@ static const char RCSid[] = "$Id: rv2.c,v 2.63 2012/09 #include "rtprocess.h" /* win_popen() */ #include "paths.h" #include "ray.h" -#include "source.h" #include "ambient.h" #include "otypes.h" +#include "otspecial.h" #include "rpaint.h" extern int psample; /* pixel sample size */ @@ -26,11 +26,7 @@ extern double maxdiff; /* max. sample difference */ #define CTRL(c) ((c)-'@') -#ifdef SMLFLT -#define sscanvec(s,v) (sscanf(s,"%f %f %f",v,v+1,v+2)==3) -#else -#define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3) -#endif +#define sscanvec(s,v) (sscanf(s,FVFORMAT,v,v+1,v+2)==3) extern char rifname[128]; /* rad input file name */ @@ -373,6 +369,55 @@ getpivot( /* pivot viewpoint */ void +getorigin( /* origin viewpoint */ + char *s +) +{ + VIEW nv = ourview; + double d; + /* get new view origin */ + if (sscanf(s, "%lf %lf", &d, &d) == 1) { + /* just moving some distance */ + VSUM(nv.vp, nv.vp, nv.vdir, d); + } else if (!sscanvec(s, nv.vp)) { + int x, y; /* need to pick origin */ + RAY thisray; + if (dev->getcur == NULL) + return; + (*dev->comout)("Pick point on surface for new origin\n"); + if ((*dev->getcur)(&x, &y) == ABORT) + return; + if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, + &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) { + error(COMMAND, "not on image"); + return; + } + rayorigin(&thisray, PRIMARY, NULL, NULL); + if (!localhit(&thisray, &thescene)) { + error(COMMAND, "not a local object"); + return; + } + if (thisray.rod < 0.0) /* don't look through other side */ + flipsurface(&thisray); + VSUM(nv.vp, thisray.rop, thisray.ron, 20.0*FTINY); + VCOPY(nv.vdir, thisray.ron); + } else if (!sscanvec(sskip2(s,3), nv.vdir) || normalize(nv.vdir) == 0.0) + VCOPY(nv.vdir, ourview.vdir); + + d = DOT(nv.vdir, nv.vup); /* need different up vector? */ + if (d*d >= 1.-2.*FTINY) { + int i; + nv.vup[0] = nv.vup[1] = nv.vup[2] = 0.0; + for (i = 3; i--; ) + if (nv.vdir[i]*nv.vdir[i] < 0.34) + break; + nv.vup[i] = 1.; + } + newview(&nv); +} + + +void getexposure( /* get new exposure */ char *s ) @@ -414,7 +459,7 @@ getexposure( /* get new exposure */ return; } } - if (*cp == '+' || *cp == '-') /* f-stops */ + if ((*cp == '+') | (*cp == '-')) /* f-stops */ e *= pow(2.0, atof(cp)); else /* multiplier */ e *= atof(cp); @@ -438,7 +483,6 @@ getexposure( /* get new exposure */ } typedef union {int i; double d; COLOR C;} *MyUptr; -#define FEQ(x,y) (fabs((x)-(y)) <= FTINY) int getparam( /* get variable from user */ @@ -476,7 +520,7 @@ getparam( /* get variable from user */ if (sscanf(buf, "%lf", &d0) != 1) return(0); } - if (FEQ(ptr->d, d0)) + if (FRELEQ(ptr->d, d0)) return(0); ptr->d = d0; break; @@ -508,9 +552,9 @@ getparam( /* get variable from user */ if (sscanf(buf, "%lf %lf %lf", &d0, &d1, &d2) != 3) return(0); } - if (FEQ(colval(ptr->C,RED), d0) && - FEQ(colval(ptr->C,GRN), d1) && - FEQ(colval(ptr->C,BLU), d2)) + if (FRELEQ(colval(ptr->C,RED), d0) && + FRELEQ(colval(ptr->C,GRN), d1) && + FRELEQ(colval(ptr->C,BLU), d2)) return(0); setcolor(ptr->C, d0, d1, d2); break; @@ -544,12 +588,10 @@ setparam( /* get/set program parameter */ case 'l': /* limit */ switch (s[1]) { case 'w': /* weight */ - getparam(s+2, "limit weight", 'r', - (void *)&minweight); + getparam(s+2, "limit weight", 'r', &minweight); break; case 'r': /* reflection */ - getparam(s+2, "limit reflection", 'i', - (void *)&maxdepth); + getparam(s+2, "limit reflection", 'i', &maxdepth); break; default: goto badparam; @@ -558,24 +600,19 @@ setparam( /* get/set program parameter */ case 'd': /* direct */ switch (s[1]) { case 'j': /* jitter */ - getparam(s+2, "direct jitter", 'r', - (void *)&dstrsrc); + getparam(s+2, "direct jitter", 'r', &dstrsrc); break; case 'c': /* certainty */ - getparam(s+2, "direct certainty", 'r', - (void *)&shadcert); + getparam(s+2, "direct certainty", 'r', &shadcert); break; case 't': /* threshold */ - getparam(s+2, "direct threshold", 'r', - (void *)&shadthresh); + getparam(s+2, "direct threshold", 'r', &shadthresh); break; case 'v': /* visibility */ - getparam(s+2, "direct visibility", 'b', - (void *)&directvis); + getparam(s+2, "direct visibility", 'b', &directvis); break; case 's': /* sampling */ - getparam(s+2, "direct sampling", 'r', - (void *)&srcsizerat); + getparam(s+2, "direct sampling", 'r', &srcsizerat); break; default: goto badparam; @@ -591,8 +628,7 @@ setparam( /* get/set program parameter */ case ' ': case 'y': case 'Y': case 't': case 'T': case '1': case '+': case 'n': case 'N': case 'f': case 'F': case '0': case '-': - getparam(s+1, "black and white", 'b', - (void *)&greyscale); + getparam(s+1, "black and white", 'b', &greyscale); newparam = prev_newp; break; default: @@ -600,39 +636,31 @@ setparam( /* get/set program parameter */ } break; case 'i': /* irradiance */ - getparam(s+1, "irradiance", 'b', - (void *)&do_irrad); + getparam(s+1, "irradiance", 'b', &do_irrad); break; case 'a': /* ambient */ switch (s[1]) { case 'v': /* value */ - getparam(s+2, "ambient value", 'C', - (void *)ambval); + getparam(s+2, "ambient value", 'C', ambval); break; case 'w': /* weight */ - getparam(s+2, "ambient value weight", 'i', - (void *)&ambvwt); + getparam(s+2, "ambient value weight", 'i', &ambvwt); break; case 'a': /* accuracy */ - if (getparam(s+2, "ambient accuracy", 'r', - (void *)&ambacc)) + if (getparam(s+2, "ambient accuracy", 'r', &ambacc)) setambacc(ambacc); break; case 'd': /* divisions */ - getparam(s+2, "ambient divisions", 'i', - (void *)&ambdiv); + getparam(s+2, "ambient divisions", 'i', &ambdiv); break; case 's': /* samples */ - getparam(s+2, "ambient super-samples", 'i', - (void *)&ambssamp); + getparam(s+2, "ambient super-samples", 'i', &ambssamp); break; case 'b': /* bounces */ - getparam(s+2, "ambient bounces", 'i', - (void *)&ambounce); + getparam(s+2, "ambient bounces", 'i', &ambounce); break; case 'r': - if (getparam(s+2, "ambient resolution", 'i', - (void *)&ambres)) + if (getparam(s+2, "ambient resolution", 'i', &ambres)) setambres(ambres); break; default: @@ -642,20 +670,16 @@ setparam( /* get/set program parameter */ case 'm': /* medium */ switch (s[1]) { case 'e': /* extinction coefficient */ - getparam(s+2, "extinction coefficient", 'C', - (void *)cextinction); + getparam(s+2, "extinction coefficient", 'C', cextinction); break; case 'a': /* scattering albedo */ - getparam(s+2, "scattering albedo", 'C', - (void *)salbedo); + getparam(s+2, "scattering albedo", 'C', salbedo); break; case 'g': /* scattering eccentricity */ - getparam(s+2, "scattering eccentricity", 'r', - (void *)&seccg); + getparam(s+2, "scattering eccentricity", 'r', &seccg); break; case 's': /* sampling distance */ - getparam(s+2, "mist sampling distance", 'r', - (void *)&ssampdist); + getparam(s+2, "mist sampling distance", 'r', &ssampdist); break; default: goto badparam; @@ -664,13 +688,11 @@ setparam( /* get/set program parameter */ case 'p': /* pixel */ switch (s[1]) { case 's': /* sample */ - if (getparam(s+2, "pixel sample", 'i', - (void *)&psample)) + if (getparam(s+2, "pixel sample", 'i', &psample)) pdepth = 0; break; case 't': /* threshold */ - if (getparam(s+2, "pixel threshold", 'r', - (void *)&maxdiff)) + if (getparam(s+2, "pixel threshold", 'r', &maxdiff)) pdepth = 0; break; default: @@ -681,12 +703,10 @@ setparam( /* get/set program parameter */ case 's': /* specular */ switch (s[1]) { case 's': /* sampling */ - getparam(s+2, "specular sampling", 'r', - (void *)&specjitter); + getparam(s+2, "specular sampling", 'r', &specjitter); break; case 't': /* threshold */ - getparam(s+2, "specular threshold", 'r', - (void *)&specthresh); + getparam(s+2, "specular threshold", 'r', &specthresh); break; default: goto badparam; @@ -711,6 +731,7 @@ traceray( /* trace a single ray */ { RAY thisray; char buf[512]; + COLOR col; thisray.rmax = 0.0; @@ -748,7 +769,7 @@ traceray( /* trace a single ray */ matspec[0] = '\0'; if (thisray.ro->omod != OVOID) { mod = objptr(thisray.ro->omod); - mat = findmaterial(mod); + mat = findmaterial(thisray.ro); } if (thisray.rod < 0.0) strcpy(matspec, "back of "); @@ -767,20 +788,21 @@ traceray( /* trace a single ray */ ofun[ino->otype].funame, ino->oname); (*dev->comout)(buf); (*dev->comin)(buf, NULL); - if (thisray.rot >= FHUGE) + if (thisray.rot >= FHUGE*.99) (*dev->comout)("at infinity"); else { sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)", thisray.rop[0], thisray.rop[1], - thisray.rop[2], thisray.rt); + thisray.rop[2], raydistance(&thisray)); (*dev->comout)(buf); } (*dev->comin)(buf, NULL); + scolor_rgb(col, thisray.rcol); sprintf(buf, "value (%.5g %.5g %.5g) (%.3gL)", - colval(thisray.rcol,RED), - colval(thisray.rcol,GRN), - colval(thisray.rcol,BLU), - luminance(thisray.rcol)); + colval(col,RED), + colval(col,GRN), + colval(col,BLU), + luminance(col)); (*dev->comout)(buf); } (*dev->comin)(buf, NULL); @@ -826,6 +848,7 @@ writepict( /* write the picture to a file */ fputexpos(exposure, fp); if (dev->pixaspect != 1.0) fputaspect(dev->pixaspect, fp); + fputprims(stdprims, fp); fputformat(COLRFMT, fp); putc('\n', fp); fprtresolu(hresolu, vresolu, fp);