--- ray/src/rt/virtuals.c 1998/08/10 18:37:06 2.6 +++ ray/src/rt/virtuals.c 2014/07/15 23:44:53 2.21 @@ -1,18 +1,17 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: virtuals.c,v 2.21 2014/07/15 23:44:53 greg Exp $"; #endif - /* * Routines for simulating virtual light sources * Thus far, we only support planar mirrors. + * + * External symbols declared in source.h */ +#include "copyright.h" + #include "ray.h" -#include "octree.h" - #include "otypes.h" #include "source.h" @@ -22,22 +21,36 @@ static char SCCSid[] = "$SunId$ SGI"; #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) -double getdisk(); static OBJECT *vobject; /* virtual source objects */ static int nvobjects = 0; /* number of virtual source objects */ -markvirtuals() /* find and mark virtual sources */ +static int +isident4(MAT4 m) { - register OBJREC *o; - register int i; + int i, j; + + for (i = 4; i--; ) + for (j = 4; j--; ) + if (!FEQ(m[i][j], i==j)) + return(0); + return(1); +} + + +void +markvirtuals(void) /* find and mark virtual sources */ +{ + OBJREC *o; + int i; /* check number of direct relays */ if (directrelay <= 0) return; /* find virtual source objects */ - for (i = 0; i < nobjects; i++) { + for (i = 0; i < nsceneobjs; i++) { o = objptr(i); if (!issurface(o->otype) || o->omod == OVOID) continue; @@ -51,7 +64,7 @@ markvirtuals() /* find and mark virtual sources */ if (nvobjects == 0) vobject = (OBJECT *)malloc(sizeof(OBJECT)); else - vobject = (OBJECT *)realloc((char *)vobject, + vobject = (OBJECT *)realloc((void *)vobject, (unsigned)(nvobjects+1)*sizeof(OBJECT)); if (vobject == NULL) error(SYSTEM, "out of memory in addvirtuals"); @@ -66,16 +79,18 @@ markvirtuals() /* find and mark virtual sources */ for (i = nsources; i-- > 0; ) addvirtuals(i, directrelay); /* done with our object list */ - free((char *)vobject); + free((void *)vobject); nvobjects = 0; } -addvirtuals(sn, nr) /* add virtuals associated with source */ -int sn; -int nr; +void +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 +103,15 @@ int nr; } -vproject(o, sn, n) /* create projected source(s) if they exist */ -OBJREC *o; -int sn; -int n; +void +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 = objptr(i); + 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); @@ -194,7 +217,7 @@ MAT4 pm; else nsflags &= ~SSPOT; if (source[sn].sflags & SSPOT) { - copystruct(&theirspot, source[sn].sl.s); + theirspot = *(source[sn].sl.s); multv3(theirspot.aim, source[sn].sl.s->aim, pm); normalize(theirspot.aim); if (nsflags & SSPOT) { @@ -204,7 +227,7 @@ MAT4 pm; return(-1); /* no overlap */ } else { nsflags |= SSPOT; - copystruct(&ourspot, &theirspot); + ourspot = theirspot; d = 2.*ourspot.siz; } if (ourspot.siz < d-FTINY) { /* it shrunk */ @@ -244,7 +267,7 @@ MAT4 pm; if (nsflags & SSPOT) { if ((source[i].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL) goto memerr; - copystruct(source[i].sl.s, &ourspot); + *(source[i].sl.s) = ourspot; } if (nsflags & SPROX) source[i].sl.prox = source[sn].sl.prox; @@ -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; + double offsdir[3]; 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); @@ -314,8 +340,7 @@ register int sn; /* target source number */ /* 32. == heuristic constant */ n = 32.*or2/(thescene.cusize*thescene.cusize)*vspretest + .5; } else { - for (i = 0; i < 3; i++) - offsdir[i] = source[sn].sloc[i] - oc[i]; + VSUB(offsdir, source[sn].sloc, oc); d = DOT(offsdir,offsdir); if (d <= FTINY) n = 2.*PI * vspretest + .5; @@ -351,8 +376,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 +390,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"); @@ -395,12 +426,12 @@ register int sn; /* target source number */ #ifdef DEBUG -virtverb(sn, fp) /* print verbose description of virtual source */ -register int sn; -FILE *fp; +void +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,