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.5 by greg, Thu Jun 20 17:08:39 1991 UTC vs.
Revision 1.6 by greg, Fri Jun 21 13:25:42 1991 UTC

# Line 16 | Line 16 | static char SCCSid[] = "$SunId$ LBL";
16   #include  "source.h"
17  
18  
19 < double  intercircle();
19 > double  intercircle(), getdisk();
20  
21   static OBJECT  *vobject;                /* virtual source objects */
22   static int  nvobjects = 0;              /* number of virtual source objects */
# Line 97 | Line 97 | int  n;
97                  if ((*vsmat->vproj)(proj, o, &source[sn], i))
98                          if ((ns = makevsrc(o, sn, proj)) >= 0) {
99   #ifdef DEBUG
100 <                                virtverb(&source[ns], stderr);
100 >                                virtverb(ns, stderr);
101   #endif
102                                  addvirtuals(ns, n);
103                          }
# Line 110 | Line 110 | OBJREC  *op;
110   register int  sn;
111   MAT4  pm;
112   {
113 <        register int  nsn;
114 <        FVECT  nsloc, ocent, nsnorm;
115 <        int  nsflags;
113 >        FVECT  nsloc, nsnorm, ocent;
114          double  maxrad2;
115 +        int  nsflags;
116          double  d1;
117          SPOT  theirspot, ourspot;
118          register int  i;
119  
120 <        nsflags = (source[sn].sflags|(SVIRTUAL|SFOLLOW)) & ~SSPOT;
120 >        nsflags = source[sn].sflags | (SVIRTUAL|SSPOT|SFOLLOW);
121                                          /* get object center and max. radius */
122 <        if (sfun[op->otype].of->getdisk != NULL) {
123 <                maxrad2 = (*sfun[op->otype].of->getdisk)(ocent, op);
124 <                if (maxrad2 <= FTINY)                   /* too small? */
126 <                        return(-1);
127 <                nsflags |= SSPOT;
128 <        }
122 >        maxrad2 = getdisk(ocent, op, sn);
123 >        if (maxrad2 <= FTINY)                   /* too small? */
124 >                return(-1);
125                                          /* get location and spot */
126          if (source[sn].sflags & SDISTANT) {             /* distant source */
127                  if (source[sn].sflags & SPROX)
128                          return(-1);             /* should never get here! */
129                  multv3(nsloc, source[sn].sloc, pm);
130 <                if (nsflags & SSPOT) {
131 <                        VCOPY(ourspot.aim, ocent);
132 <                        ourspot.siz = PI*maxrad2;
137 <                        ourspot.flen = 0.;
138 <                }
130 >                VCOPY(ourspot.aim, ocent);
131 >                ourspot.siz = PI*maxrad2;
132 >                ourspot.flen = 0.;
133                  if (source[sn].sflags & SSPOT) {
134                          copystruct(&theirspot, source[sn].sl.s);
135                          multp3(theirspot.aim, source[sn].sl.s->aim, pm);
136 <                        if (nsflags & SSPOT &&
143 <                                !commonbeam(&ourspot, &theirspot, nsloc))
136 >                        if (!commonbeam(&ourspot, &theirspot, nsloc))
137                                  return(-1);             /* no overlap */
138                  }
139          } else {                                /* local source */
140                  multp3(nsloc, source[sn].sloc, pm);
141 <                if (nsflags & SSPOT) {
142 <                        for (i = 0; i < 3; i++)
143 <                                ourspot.aim[i] = ocent[i] - nsloc[i];
144 <                        if ((d1 = normalize(ourspot.aim)) == 0.)
145 <                                return(-1);             /* at source!! */
146 <                        if (source[sn].sflags & SPROX &&
147 <                                        d1 > source[sn].sl.prox)
148 <                                return(-1);             /* too far away */
156 <                        ourspot.siz = 2.*PI*(1. - d1/sqrt(d1*d1+maxrad2));
157 <                        ourspot.flen = 0.;
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 < 0.) d1 = -d1;
165 <                        if (d1 > source[sn].sl.prox)
166 <                                return(-1);             /* too far away */
167 <                }
141 >                for (i = 0; i < 3; i++)
142 >                        ourspot.aim[i] = ocent[i] - nsloc[i];
143 >                if ((d1 = normalize(ourspot.aim)) == 0.)
144 >                        return(-1);             /* at source!! */
145 >                if (source[sn].sflags & SPROX && d1 > source[sn].sl.prox)
146 >                        return(-1);             /* too far away */
147 >                ourspot.siz = 2.*PI*(1. - d1/sqrt(d1*d1+maxrad2));
148 >                ourspot.flen = 0.;
149                  if (source[sn].sflags & SSPOT) {
150                          copystruct(&theirspot, source[sn].sl.s);
151                          multv3(theirspot.aim, source[sn].sl.s->aim, pm);
152 <                        if (nsflags & SSPOT) {
153 <                                if (!commonspot(&ourspot, &theirspot, nsloc))
154 <                                        return(-1);     /* no overlap */
174 <                                ourspot.flen = theirspot.flen;
175 <                        }
152 >                        if (!commonspot(&ourspot, &theirspot, nsloc))
153 >                                return(-1);     /* no overlap */
154 >                        ourspot.flen = theirspot.flen;
155                  }
156                  if (source[sn].sflags & SFLAT) {        /* behind source? */
157                          multv3(nsnorm, source[sn].snorm, pm);
158 <                        if (nsflags & SSPOT && checkspot(&ourspot, nsnorm) < 0)
158 >                        if (checkspot(&ourspot, nsnorm) < 0)
159                                  return(-1);
160                  }
161          }
162                                          /* everything is OK, make source */
163 <        if ((nsn = newsource()) < 0)
163 >        if ((i = newsource()) < 0)
164                  goto memerr;
165 <        source[nsn].sflags = nsflags;
166 <        VCOPY(source[nsn].sloc, nsloc);
165 >        source[i].sflags = nsflags;
166 >        VCOPY(source[i].sloc, nsloc);
167          if (nsflags & SFLAT)
168 <                VCOPY(source[nsn].snorm, nsnorm);
169 <        source[nsn].ss = source[sn].ss; source[nsn].ss2 = source[sn].ss2;
170 <        if ((nsflags | source[sn].sflags) & SSPOT) {
171 <                if ((source[nsn].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL)
172 <                        goto memerr;
194 <                if (nsflags & SSPOT)
195 <                        copystruct(source[nsn].sl.s, &ourspot);
196 <                else
197 <                        copystruct(source[nsn].sl.s, &theirspot);
198 <                source[nsn].sflags |= SSPOT;
199 <        }
168 >                VCOPY(source[i].snorm, nsnorm);
169 >        source[i].ss = source[sn].ss; source[i].ss2 = source[sn].ss2;
170 >        if ((source[i].sl.s = (SPOT *)malloc(sizeof(SPOT))) == NULL)
171 >                goto memerr;
172 >        copystruct(source[i].sl.s, &ourspot);
173          if (nsflags & SPROX)
174 <                source[nsn].sl.prox = source[sn].sl.prox;
175 <        source[nsn].sa.svnext = sn;
176 <        source[nsn].so = op;
177 <        return(nsn);
174 >                source[i].sl.prox = source[sn].sl.prox;
175 >        source[i].sa.svnext = sn;
176 >        source[i].so = op;
177 >        return(i);
178   memerr:
179          error(SYSTEM, "out of memory in makevsrc");
180   }
181  
182  
183 + double
184 + getdisk(oc, op, sn)             /* get visible object disk */
185 + FVECT  oc;
186 + OBJREC  *op;
187 + register int  sn;
188 + {
189 +        double  rad2, roffs, offs, d, rd, rdoto;
190 +        FVECT  rnrm, nrm;
191 +                                /* first, use object getdisk function */
192 +        rad2 = (*sfun[op->otype].of->getdisk)(oc, op);
193 +        if (!(source[sn].sflags & SVIRTUAL))
194 +                return(rad2);           /* all done for normal source */
195 +                                /* check for correct side of relay surface */
196 +        roffs = (*sfun[source[sn].so->otype].of->getpleq)(rnrm, source[sn].so);
197 +        rd = DOT(rnrm, source[sn].sloc);        /* source projection */
198 +        if (!(source[sn].sflags & SDISTANT))
199 +                rd -= roffs;
200 +        d = DOT(rnrm, oc) - roffs;      /* disk distance to relay plane */
201 +        if ((d > 0.) ^ (rd > 0.))
202 +                return(rad2);           /* OK if opposite sides */
203 +        if (d*d >= rad2)
204 +                return(.0);             /* no relay is possible */
205 +                                /* we need a closer look */
206 +        offs = (*sfun[op->otype].of->getpleq)(nrm, op);
207 +        rdoto = DOT(rnrm, nrm);
208 +        if (d*d >= rad2*(1.-rdoto*rdoto))
209 +                return(0.);             /* disk entirely on projection side */
210 +                                /* should shrink disk but I'm lazy */
211 +        return(rad2);
212 + }
213 +
214 +
215   commonspot(sp1, sp2, org)       /* set sp1 to intersection of sp1 and sp2 */
216   register SPOT  *sp1, *sp2;
217   FVECT  org;
# Line 307 | Line 312 | double  r1s, r2s;              /* radii squared */
312  
313  
314   #ifdef DEBUG
315 < virtverb(vs, fp)        /* print verbose description of virtual source */
316 < register SRCREC  *vs;
315 > virtverb(sn, fp)        /* print verbose description of virtual source */
316 > register int  sn;
317   FILE  *fp;
318   {
319          register int  i;
320  
321          fprintf(fp, "%s virtual source %d in %s %s\n",
322 <                        vs->sflags & SDISTANT ? "distant" : "local",
323 <                        vs-source, ofun[vs->so->otype].funame, vs->so->oname);
322 >                        source[sn].sflags & SDISTANT ? "distant" : "local",
323 >                        sn, ofun[source[sn].so->otype].funame,
324 >                        source[sn].so->oname);
325          fprintf(fp, "\tat (%f,%f,%f)\n",
326 <                        vs->sloc[0], vs->sloc[1], vs->sloc[2]);
326 >                source[sn].sloc[0], source[sn].sloc[1], source[sn].sloc[2]);
327          fprintf(fp, "\tlinked to source %d (%s)\n",
328 <                        vs->sa.svnext, source[vs->sa.svnext].so->oname);
329 <        if (vs->sflags & SFOLLOW)
328 >                source[sn].sa.svnext, source[source[sn].sa.svnext].so->oname);
329 >        if (source[sn].sflags & SFOLLOW)
330                  fprintf(fp, "\talways followed\n");
331          else
332                  fprintf(fp, "\tnever followed\n");
333 <        if (!(vs->sflags & SSPOT))
333 >        if (!(source[sn].sflags & SSPOT))
334                  return;
335          fprintf(fp, "\twith spot aim (%f,%f,%f) and size %f\n",
336 <                        vs->sl.s->aim[0], vs->sl.s->aim[1], vs->sl.s->aim[2],
337 <                        vs->sl.s->siz);
336 >                        source[sn].sl.s->aim[0], source[sn].sl.s->aim[1],
337 >                        source[sn].sl.s->aim[2], source[sn].sl.s->siz);
338   }
339   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines