--- ray/src/rt/virtuals.c 2004/03/01 18:11:20 2.12 +++ ray/src/rt/virtuals.c 2012/09/14 13:34:02 2.20 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: virtuals.c,v 2.12 2004/03/01 18:11:20 greg Exp $"; +static const char RCSid[] = "$Id: virtuals.c,v 2.20 2012/09/14 13:34:02 greg Exp $"; #endif /* * Routines for simulating virtual light sources @@ -21,16 +21,31 @@ static const char RCSid[] = "$Id: virtuals.c,v 2.12 20 #define MINSAMPLES 16 /* minimum number of pretest samples */ #define STESTMAX 32 /* maximum seeks per sample */ +#define FEQ(a,b) ((a)-(b)+FTINY >= 0 && (b)-(a)+FTINY >= 0) + static OBJECT *vobject; /* virtual source objects */ static int nvobjects = 0; /* number of virtual source objects */ +static int +isident4(MAT4 m) +{ + int i, j; + + for (i = 4; i--; ) + for (j = 4; j--; ) + if (!FEQ(m[i][j], i==j)) + return(0); + return(1); +} + + void -markvirtuals() /* find and mark virtual sources */ +markvirtuals(void) /* find and mark virtual sources */ { - register OBJREC *o; - register int i; + OBJREC *o; + int i; /* check number of direct relays */ if (directrelay <= 0) return; @@ -70,11 +85,12 @@ markvirtuals() /* find and mark virtual sources */ void -addvirtuals(sn, nr) /* add virtuals associated with source */ -int sn; -int nr; +addvirtuals( /* add virtuals associated with source */ + int sn, + int nr +) { - register int i; + int i; /* check relay limit first */ if (nr <= 0) return; @@ -88,13 +104,14 @@ int nr; void -vproject(o, sn, n) /* create projected source(s) if they exist */ -OBJREC *o; -int sn; -int n; +vproject( /* create projected source(s) if they exist */ + OBJREC *o, + int sn, + int n +) { - register int i; - register VSMATERIAL *vsmat; + int i; + VSMATERIAL *vsmat; MAT4 proj; int ns; @@ -116,14 +133,17 @@ int n; OBJREC * -vsmaterial(o) /* get virtual source material pointer */ -OBJREC *o; +vsmaterial( /* get virtual source material pointer */ + OBJREC *o +) { - register int i; - register OBJREC *m; + int i; + OBJREC *m; i = o->omod; m = findmaterial(objptr(i)); + if (m == NULL) + return(objptr(i)); if (m->otype != MAT_ILLUM || m->oargs.nsargs < 1 || !strcmp(m->oargs.sarg[0], VOIDID) || (i = lastmod(objndx(m), m->oargs.sarg[0])) == OVOID) @@ -133,17 +153,20 @@ OBJREC *o; int -makevsrc(op, sn, pm) /* make virtual source if reasonable */ -OBJREC *op; -register int sn; -MAT4 pm; +makevsrc( /* make virtual source if reasonable */ + OBJREC *op, + int sn, + MAT4 pm +) { FVECT nsloc, nsnorm, ocent, v; double maxrad2, d; int nsflags; SPOT theirspot, ourspot; - register int i; - + int i; + /* check for no-op */ + if (isident4(pm)) + return(0); nsflags = source[sn].sflags | (SVIRTUAL|SSPOT|SFOLLOW); /* get object center and max. radius */ maxrad2 = getdisk(ocent, op, sn); @@ -253,14 +276,16 @@ MAT4 pm; return(i); memerr: error(SYSTEM, "out of memory in makevsrc"); + return -1; /* pro forma return */ } double -getdisk(oc, op, sn) /* get visible object disk */ -FVECT oc; -OBJREC *op; -register int sn; +getdisk( /* get visible object disk */ + FVECT oc, + OBJREC *op, + int sn +) { double rad2, roffs, offs, d, rd, rdoto; FVECT rnrm, nrm; @@ -289,21 +314,22 @@ register int sn; int -vstestvis(f, o, oc, or2, sn) /* pretest source visibility */ -int f; /* virtual source flags */ -OBJREC *o; /* relay object */ -FVECT oc; /* relay object center */ -double or2; /* relay object radius squared */ -register int sn; /* target source number */ +vstestvis( /* pretest source visibility */ + int f, /* virtual source flags */ + OBJREC *o, /* relay object */ + FVECT oc, /* relay object center */ + double or2, /* relay object radius squared */ + int sn /* target source number */ +) { RAY sr; FVECT onorm; FVECT offsdir; SRCINDEX si; - double or, d; + double or, d, d1; int stestlim, ssn; int nhit, nok; - register int i, n; + int i, n; /* return if pretesting disabled */ if (vspretest <= 0) return(f); @@ -351,8 +377,7 @@ register int sn; /* target source number */ sr.rorg[i] = oc[i] + offsdir[i] + d*onorm[i]; sr.rdir[i] = -onorm[i]; } - sr.rmax = 0.0; - rayorigin(&sr, NULL, PRIMARY, 1.0); + rayorigin(&sr, PRIMARY, NULL, NULL); } while (!(*ofun[o->otype].funp)(o, &sr)); /* check against source */ VCOPY(sr.rorg, sr.rop); /* starting from intersection */ @@ -366,14 +391,21 @@ register int sn; /* target source number */ } sr.revf = srcvalue; rayvalue(&sr); /* check sample validity */ - if (bright(sr.rcol) <= FTINY) + if ((d = bright(sr.rcol)) <= FTINY) continue; nok++; /* got sample; check obstructions */ rayclear(&sr); sr.revf = raytrace; rayvalue(&sr); - if (bright(sr.rcol) > FTINY) + if ((d1 = bright(sr.rcol)) > FTINY) { + if (d - d1 > FTINY) { +#ifdef DEBUG + fprintf(stderr, "\tpartially shadowed\n"); +#endif + return(f); /* intervening transmitter */ + } nhit++; + } if (nhit > 0 && nhit < nok) { #ifdef DEBUG fprintf(stderr, "\tpartially occluded\n"); @@ -396,12 +428,11 @@ register int sn; /* target source number */ #ifdef DEBUG void -virtverb(sn, fp) /* print verbose description of virtual source */ -register int sn; -FILE *fp; +virtverb( /* print verbose description of virtual source */ + int sn, + FILE *fp +) { - register int i; - fprintf(fp, "%s virtual source %d in %s %s\n", source[sn].sflags & SDISTANT ? "distant" : "local", sn, ofun[source[sn].so->otype].funame,