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

Comparing ray/src/rt/virtuals.c (file contents):
Revision 1.3 by greg, Thu Jun 20 13:43:38 1991 UTC vs.
Revision 1.4 by greg, Thu Jun 20 16:36:48 1991 UTC

# Line 15 | Line 15 | static char SCCSid[] = "$SunId$ LBL";
15  
16   #include  "source.h"
17  
18 #include  "cone.h"
18  
20 #include  "face.h"
21
22
19   double  intercircle();
24 SRCREC  *makevsrc();
20  
21   static OBJECT  *vobject;                /* virtual source objects */
22   static int  nvobjects = 0;              /* number of virtual source objects */
# Line 55 | Line 50 | markvirtuals()                 /* find and mark virtual sources */
50          }
51          if (nvobjects == 0)
52                  return;
53 + #ifdef DEBUG
54 +        fprintf(stderr, "found %d virtual source objects\n", nvobjects);
55 + #endif
56                                          /* append virtual sources */
57          for (i = nsources; i-- > 0; )
58                  if (!(source[i].sflags & SSKIP))
59 <                        addvirtuals(&source[i], directrelay);
59 >                        addvirtuals(i, directrelay);
60                                          /* done with our object list */
61          free((char *)vobject);
62          nvobjects = 0;
63   }
64  
65  
66 < addvirtuals(sr, nr)             /* add virtual sources associated with sr */
67 < SRCREC  *sr;
66 > addvirtuals(sn, nr)             /* add virtuals associated with source */
67 > int  sn;
68   int  nr;
69   {
70          register int  i;
# Line 76 | Line 74 | int  nr;
74                                  /* check each virtual object for projection */
75          for (i = 0; i < nvobjects; i++)
76                                          /* vproject() calls us recursively */
77 <                vproject(objptr(i), sr, nr-1);
77 >                vproject(objptr(vobject[i]), sn, nr-1);
78   }
79  
80  
81 < vproject(o, s, n)               /* create projected source(s) if they exist */
81 > vproject(o, sn, n)              /* create projected source(s) if they exist */
82   OBJREC  *o;
83 < SRCREC  *s;
83 > int  sn;
84   int  n;
85   {
86          register int  i;
87          register VSMATERIAL  *vsmat;
88          MAT4  proj;
89 <        SRCREC  *ns;
89 >        int  ns;
90 >
91 >        if (o == source[sn].so) /* objects cannot project themselves */
92 >                return;
93                                  /* get virtual source material */
94          vsmat = sfun[objptr(o->omod)->otype].mf;
95                                  /* project virtual sources */
96          for (i = 0; i < vsmat->nproj; i++)
97 <                if ((*vsmat->vproj)(proj, o, s, i))
98 <                        if ((ns = makevsrc(o, s, proj)) != NULL)
97 >                if ((*vsmat->vproj)(proj, o, &source[sn], i))
98 >                        if ((ns = makevsrc(o, sn, proj)) >= 0) {
99 > #ifdef DEBUG
100 >                                virtverb(&source[sn], stderr);
101 > #endif
102                                  addvirtuals(ns, n);
103 +                        }
104   }
105  
106  
107 < SRCREC *
108 < makevsrc(op, sp, pm)            /* make virtual source if reasonable */
107 > int
108 > makevsrc(op, sn, pm)            /* make virtual source if reasonable */
109   OBJREC  *op;
110 < register SRCREC  *sp;
110 > register int  sn;
111   MAT4  pm;
112   {
113 <        register SRCREC  *newsrc;
113 >        register int  nsn;
114          FVECT  nsloc, ocent, nsnorm;
115          int  nsflags;
116          double  maxrad2;
# Line 113 | Line 118 | MAT4  pm;
118          SPOT  theirspot, ourspot;
119          register int  i;
120  
121 <        nsflags = (sp->sflags|(SVIRTUAL|SFOLLOW)) & ~SSPOT;
121 >        nsflags = (source[sn].sflags|(SVIRTUAL|SFOLLOW)) & ~SSPOT;
122                                          /* get object center and max. radius */
123          if (sfun[op->otype].of->getdisk != NULL) {
124                  maxrad2 = (*sfun[op->otype].of->getdisk)(ocent, op);
# Line 122 | Line 127 | MAT4  pm;
127                  nsflags |= SSPOT;
128          }
129                                          /* get location and spot */
130 <        if (sp->sflags & SDISTANT) {            /* distant source */
131 <                if (sp->sflags & SPROX)
130 >        if (source[sn].sflags & SDISTANT) {             /* distant source */
131 >                if (source[sn].sflags & SPROX)
132                          return(NULL);           /* should never get here! */
133 <                multv3(nsloc, sp->sloc, pm);
133 >                multv3(nsloc, source[sn].sloc, pm);
134                  if (nsflags & SSPOT) {
135                          VCOPY(ourspot.aim, ocent);
136                          ourspot.siz = PI*maxrad2;
137                          ourspot.flen = 0.;
138                  }
139 <                if (sp->sflags & SSPOT) {
140 <                        copystruct(&theirspot, sp->sl.s);
141 <                        multp3(theirspot.aim, sp->sl.s->aim, pm);
139 >                if (source[sn].sflags & SSPOT) {
140 >                        copystruct(&theirspot, source[sn].sl.s);
141 >                        multp3(theirspot.aim, source[sn].sl.s->aim, pm);
142                          if (nsflags & SSPOT &&
143                                  !commonbeam(&ourspot, &theirspot, nsloc))
144                                  return(NULL);           /* no overlap */
145                  }
146          } else {                                /* local source */
147 <                multp3(nsloc, sp->sloc, pm);
147 >                multp3(nsloc, source[sn].sloc, pm);
148                  if (nsflags & SSPOT) {
149                          for (i = 0; i < 3; i++)
150                                  ourspot.aim[i] = ocent[i] - nsloc[i];
151                          if ((d1 = normalize(ourspot.aim)) == 0.)
152                                  return(NULL);           /* at source!! */
153 <                        if (sp->sflags & SPROX && d1 > sp->sl.prox)
153 >                        if (source[sn].sflags & SPROX &&
154 >                                        d1 > source[sn].sl.prox)
155                                  return(NULL);           /* too far away */
156                          ourspot.siz = 2.*PI*(1. - d1/sqrt(d1*d1+maxrad2));
157                          ourspot.flen = 0.;
158 <                } else if (sp->sflags & SPROX) {
158 >                } else if (source[sn].sflags & SPROX) {
159                          FVECT  norm;
160                          double  offs;
161                                                  /* use distance from plane */
162                          offs = (*sfun[op->otype].of->getpleq)(norm, op);
163                          d1 = DOT(norm, nsloc) - offs;
164 <                        if (d1 > sp->sl.prox || d1 < -sp->sl.prox)
164 >                        if (d1 < 0.) d1 = -d1;
165 >                        if (d1 > source[sn].sl.prox)
166                                  return(NULL);           /* too far away */
167                  }
168 <                if (sp->sflags & SSPOT) {
169 <                        copystruct(&theirspot, sp->sl.s);
170 <                        multv3(theirspot.aim, sp->sl.s->aim, pm);
168 >                if (source[sn].sflags & SSPOT) {
169 >                        copystruct(&theirspot, source[sn].sl.s);
170 >                        multv3(theirspot.aim, source[sn].sl.s->aim, pm);
171                          if (nsflags & SSPOT) {
172                                  if (!commonspot(&ourspot, &theirspot, nsloc))
173                                          return(NULL);   /* no overlap */
174                                  ourspot.flen = theirspot.flen;
175                          }
176                  }
177 <                if (sp->sflags & SFLAT) {       /* check for behind source */
178 <                        multv3(nsnorm, sp->snorm, pm);
177 >                if (source[sn].sflags & SFLAT) {        /* behind source? */
178 >                        multv3(nsnorm, source[sn].snorm, pm);
179                          if (nsflags & SSPOT && checkspot(&ourspot, nsnorm) < 0)
180                                  return(NULL);
181                  }
182          }
183                                          /* everything is OK, make source */
184 <        if ((newsrc = newsource()) == NULL)
184 >        if ((nsn = newsource()) < 0)
185                  goto memerr;
186 <        newsrc->sflags = nsflags;
187 <        VCOPY(newsrc->sloc, nsloc);
186 >        source[nsn].sflags = nsflags;
187 >        VCOPY(source[nsn].sloc, nsloc);
188          if (nsflags & SFLAT)
189 <                VCOPY(newsrc->snorm, nsnorm);
190 <        newsrc->ss = sp->ss; newsrc->ss2 = sp->ss2;
191 <        if ((nsflags | sp->sflags) & SSPOT) {
192 <                if ((newsrc->sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL)
189 >                VCOPY(source[nsn].snorm, nsnorm);
190 >        source[nsn].ss = source[sn].ss; source[nsn].ss2 = source[sn].ss2;
191 >        if ((nsflags | source[sn].sflags) & SSPOT) {
192 >                if ((source[nsn].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL)
193                          goto memerr;
194                  if (nsflags & SSPOT)
195 <                        copystruct(newsrc->sl.s, &ourspot);
195 >                        copystruct(source[nsn].sl.s, &ourspot);
196                  else
197 <                        copystruct(newsrc->sl.s, &theirspot);
198 <                newsrc->sflags |= SSPOT;
197 >                        copystruct(source[nsn].sl.s, &theirspot);
198 >                source[nsn].sflags |= SSPOT;
199          }
200          if (nsflags & SPROX)
201 <                newsrc->sl.prox = sp->sl.prox;
202 <        newsrc->sa.svnext = sp - source;
203 <        return(newsrc);
201 >                source[nsn].sl.prox = source[sn].sl.prox;
202 >        source[nsn].sa.svnext = sn;
203 >        source[nsn].so = op;
204 >        return(nsn);
205   memerr:
206          error(SYSTEM, "out of memory in makevsrc");
207   }
# Line 296 | Line 304 | double  r1s, r2s;              /* radii squared */
304                  cc[i] = c1[i] + l*disp[i];
305          return(a2);
306   }
307 +
308 +
309 + #ifdef DEBUG
310 + virtverb(vs, fp)        /* print verbose description of virtual source */
311 + register SRCREC  *vs;
312 + FILE  *fp;
313 + {
314 +        register int  i;
315 +
316 +        fprintf(fp, "%s virtual source %d in %s %s\n",
317 +                        vs->sflags & SDISTANT ? "distant" : "local",
318 +                        vs-source, ofun[vs->so->otype].funame, vs->so->oname);
319 +        fprintf(fp, "\tat (%f,%f,%f)\n",
320 +                        vs->sloc[0], vs->sloc[1], vs->sloc[2]);
321 +        fprintf(fp, "\tlinked to source %d (%s)\n",
322 +                        vs->sa.svnext, source[vs->sa.svnext].so->oname);
323 +        if (vs->sflags & SFOLLOW)
324 +                fprintf(fp, "\talways followed\n");
325 +        else
326 +                fprintf(fp, "\tnever followed\n");
327 +        if (!(vs->sflags & SSPOT))
328 +                return;
329 +        fprintf(fp, "\twith spot aim (%f,%f,%f) and size %f\n",
330 +                        vs->sl.s->aim[0], vs->sl.s->aim[1], vs->sl.s->aim[2],
331 +                        vs->sl.s->siz);
332 + }
333 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines