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

Comparing ray/src/rt/srcdraw.c (file contents):
Revision 2.1 by greg, Fri Mar 15 21:26:42 1996 UTC vs.
Revision 2.20 by greg, Tue Nov 13 19:58:33 2018 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1996 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Draw small sources into image in case we missed them.
6 + *
7 + *  External symbols declared in ray.h
8   */
9  
10 < #include  "ray.h"
10 > #include "copyright.h"
11  
12 + #include  "ray.h"
13   #include  "view.h"
14 <
14 > #include  "otypes.h"
15 > #include  "otspecial.h"
16   #include  "source.h"
17  
18  
# Line 22 | Line 23 | static char SCCSid[] = "$SunId$ LBL";
23  
24   #define MAXVERT         10
25  
26 + typedef struct splist {
27 +        struct splist   *next;                  /* next source in list */
28 +        int     sn;                             /* source number */
29 +        short   nv;                             /* number of vertices */
30 +        RREAL   vl[3][2];                       /* vertex array (last) */
31 + } SPLIST;                               /* source polygon list */
32  
33 + extern VIEW     ourview;                /* our view parameters */
34 + extern int      hres, vres;             /* our image resolution */
35 + static SPLIST   *sphead = NULL;         /* our list of source polys */
36 +
37 + static int inregion(RREAL p[2], double cv, int crit);
38 + static void clipregion(RREAL a[2], RREAL b[2], double cv, int crit, RREAL r[2]);
39 + static int hp_clip_poly(RREAL vl[][2], int nv, double cv, int crit,
40 +                RREAL vlo[][2]);
41 + static int box_clip_poly(RREAL vl[MAXVERT][2], int nv,
42 +                double xl, double xr, double yb, double ya, RREAL vlo[MAXVERT][2]);
43 + static double minw2(RREAL vl[][2], int nv, double ar2);
44 + static void convex_center(RREAL vl[][2], int nv, RREAL cv[2]);
45 + static double poly_area(RREAL vl[][2], int nv);
46 + static int convex_hull(RREAL vl[][2], int nv, RREAL vlo[][2]);
47 + static void spinsert(int sn, RREAL vl[][2], int nv);
48 + static int sourcepoly(int sn, RREAL sp[MAXVERT][2]);
49 +
50 +
51   static int
52 < inregion(p, cv, crit)                   /* check if vertex is in region */
53 < FLOAT   p[2];
54 < double  cv;
55 < int     crit;
52 > inregion(                       /* check if vertex is in region */
53 >        RREAL   p[2],
54 >        double  cv,
55 >        int     crit
56 > )
57   {
58          switch (crit) {
59          case CLIP_ABOVE:
# Line 43 | Line 69 | int    crit;
69   }
70  
71  
72 < static
73 < clipregion(a, b, cv, crit, r)           /* find intersection with boundary */
74 < register FLOAT  a[2], b[2];
75 < double  cv;
76 < int     crit;
77 < FLOAT   r[2];   /* return value */
72 > static void
73 > clipregion(             /* find intersection with boundary */
74 >        RREAL   a[2],
75 >        RREAL   b[2],
76 >        double  cv,
77 >        int     crit,
78 >        RREAL   r[2]    /* return value */
79 > )
80   {
81          switch (crit) {
82          case CLIP_ABOVE:
# Line 66 | Line 94 | FLOAT  r[2];   /* return value */
94  
95  
96   static int
97 < hp_clip_poly(vl, nv, cv, crit, vlo)     /* clip polygon to half-plane */
98 < FLOAT   vl[][2];
99 < int     nv;
100 < double  cv;
101 < int     crit;
102 < FLOAT   vlo[][2];       /* return value */
97 > hp_clip_poly(   /* clip polygon to half-plane */
98 >        RREAL   vl[][2],
99 >        int     nv,
100 >        double  cv,
101 >        int     crit,
102 >        RREAL   vlo[][2]        /* return value */
103 > )
104   {
105 <        FLOAT   *s, *p;
106 <        register int    j, nvo;
105 >        RREAL   *s, *p;
106 >        int     j, nvo;
107  
108          s = vl[nv-1];
109          nvo = 0;
# Line 93 | Line 122 | FLOAT  vlo[][2];       /* return value */
122  
123  
124   static int
125 < box_clip_poly(vl, nv, xl, xr, yb, ya, vlo)      /* clip polygon to box */
126 < FLOAT   vl[MAXVERT][2];
127 < int     nv;
128 < double  xl, xr, yb, ya;
129 < FLOAT   vlo[MAXVERT][2];        /* return value */
125 > box_clip_poly(  /* clip polygon to box */
126 >        RREAL   vl[MAXVERT][2],
127 >        int     nv,
128 >        double  xl,
129 >        double  xr,
130 >        double  yb,
131 >        double  ya,
132 >        RREAL   vlo[MAXVERT][2] /* return value */
133 > )
134   {
135 <        FLOAT   vlt[MAXVERT][2];
135 >        RREAL   vlt[MAXVERT][2];
136          int     nvt, nvo;
137  
138          nvt = hp_clip_poly(vl, nv, yb, CLIP_BELOW, vlt);
# Line 112 | Line 145 | FLOAT  vlo[MAXVERT][2];        /* return value */
145  
146  
147   static double
148 < minw2(vl, nv, ar2)                      /* compute square of minimum width */
149 < FLOAT   vl[][2];
150 < int     nv;
151 < double  ar2;
148 > minw2(                  /* compute square of minimum width */
149 >        RREAL   vl[][2],
150 >        int     nv,
151 >        double  ar2
152 > )
153   {
154          double  d2, w2, w2min, w2max;
155 <        register FLOAT  *p0, *p1, *p2;
155 >        RREAL   *p0, *p1, *p2;
156          int     i, j;
157                                  /* find minimum for all widths */
158          w2min = FHUGE;
# Line 144 | Line 178 | double ar2;
178   }
179  
180  
181 < static
182 < convex_center(vl, nv, cv)               /* compute center of convex polygon */
183 < register FLOAT  vl[][2];
184 < int     nv;
185 < FLOAT   cv[2];          /* return value */
181 > static void
182 > convex_center(          /* compute center of convex polygon */
183 >        RREAL   vl[][2],
184 >        int     nv,
185 >        RREAL   cv[2]           /* return value */
186 > )
187   {
188 <        register int    i;
188 >        int     i;
189                                          /* simple average (suboptimal) */
190          cv[0] = cv[1] = 0.;
191          for (i = 0; i < nv; i++) {
# Line 163 | Line 198 | FLOAT  cv[2];          /* return value */
198  
199  
200   static double
201 < poly_area(vl, nv)                       /* compute area of polygon */
202 < register FLOAT  vl[][2];
203 < int     nv;
201 > poly_area(                      /* compute area of polygon */
202 >        RREAL   vl[][2],
203 >        int     nv
204 > )
205   {
206          double  a;
207 <        FLOAT   v0[2], v1[2];
208 <        register int    i;
207 >        RREAL   v0[2], v1[2];
208 >        int     i;
209  
210          a = 0.;
211          v0[0] = vl[1][0] - vl[0][0];
# Line 185 | Line 221 | int    nv;
221  
222  
223   static int
224 < convex_hull(vl, nv, vlo)                /* compute polygon's convex hull */
225 < FLOAT   vl[][2];
226 < int     nv;
227 < FLOAT   vlo[][2];       /* return value */
224 > convex_hull(            /* compute polygon's convex hull */
225 >        RREAL   vl[][2],
226 >        int     nv,
227 >        RREAL   vlo[][2]        /* return value */
228 > )
229   {
230          int     nvo, nvt;
231 <        FLOAT   vlt[MAXVERT][2];
231 >        RREAL   vlt[MAXVERT][2];
232          double  voa, vta;
233 <        register int    i, j;
233 >        int     i, j;
234                                          /* start with original polygon */
235          for (i = nvo = nv; i--; ) {
236                  vlo[i][0] = vl[i][0]; vlo[i][1] = vl[i][1];
# Line 220 | Line 257 | FLOAT  vlo[][2];       /* return value */
257   }
258  
259  
260 < int
261 < sourcepoly(vw, sn, sp)                  /* compute image polygon for source */
262 < VIEW    *vw;
263 < int     sn;
264 < FLOAT   sp[MAXVERT][2];
260 > static void
261 > spinsert(                       /* insert new source polygon */
262 >        int     sn,
263 >        RREAL   vl[][2],
264 >        int     nv
265 > )
266   {
267 <        static char     cubeord[8][6] = {{1,3,2,6,4,5},{0,4,5,7,3,2},
267 >        SPLIST  *spn;
268 >        int     i;
269 >
270 >        if (nv < 3)
271 >                return;
272 >        if (nv > 3)
273 >                spn = (SPLIST *)malloc(sizeof(SPLIST)+sizeof(RREAL)*2*(nv-3));
274 >        else
275 >                spn = (SPLIST *)malloc(sizeof(SPLIST));
276 >        if (spn == NULL)
277 >                error(SYSTEM, "out of memory in spinsert");
278 >        spn->sn = sn;
279 >        for (i = spn->nv = nv; i--; ) {
280 >                spn->vl[i][0] = vl[i][0]; spn->vl[i][1] = vl[i][1];
281 >        }
282 >        spn->next = sphead;             /* push onto global list */
283 >        sphead = spn;
284 > }
285 >
286 >
287 > static int
288 > sourcepoly(                     /* compute image polygon for source */
289 >        int     sn,
290 >        RREAL   sp[MAXVERT][2]
291 > )
292 > {
293 >        static short    cubeord[8][6] = {{1,3,2,6,4,5},{0,4,5,7,3,2},
294                                           {0,1,3,7,6,4},{0,1,5,7,6,2},
295                                           {0,2,6,7,5,1},{0,4,6,7,3,1},
296                                           {0,2,3,7,5,4},{1,5,4,6,2,3}};
297 <        register SRCREC *s = source + sn;
297 >        SRCREC  *s = source + sn;
298          FVECT   ap, ip;
299 <        FLOAT   pt[6][2];
299 >        RREAL   pt[6][2];
300          int     dir;
301 <        register int    i, j;
301 >        int     i, j;
302  
303          if (s->sflags & (SDISTANT|SFLAT)) {
304 <                if (s->sflags & SDISTANT && vw->type == VT_PAR)
305 <                        return(0);              /* all or nothing case */
304 >                if (s->sflags & SDISTANT) {
305 >                        if (ourview.type == VT_PAR)
306 >                                return(0);      /* all or nothing case */
307 >                        if (s->srad >= 0.05)
308 >                                return(0);      /* should never be a problem */
309 >                }
310                  if (s->sflags & SFLAT) {
311                          for (i = 0; i < 3; i++)
312 <                                ap[i] = s->sloc[i] - vw->vp[i];
312 >                                ap[i] = s->sloc[i] - ourview.vp[i];
313                          if (DOT(ap, s->snorm) >= 0.)
314                                  return(0);      /* source faces away */
315                  }
316                  for (j = 0; j < 4; j++) {       /* four corners */
317                          for (i = 0; i < 3; i++) {
318                                  ap[i] = s->sloc[i];
319 <                                if (j==1|j==2) ap[i] += s->ss[SU][i];
319 >                                if ((j==1)|(j==2)) ap[i] += s->ss[SU][i];
320                                  else ap[i] -= s->ss[SU][i];
321 <                                if (j==2|j==3) ap[i] += s->ss[SV][i];
321 >                                if ((j==2)|(j==3)) ap[i] += s->ss[SV][i];
322                                  else ap[i] -= s->ss[SV][i];
323                                  if (s->sflags & SDISTANT) {
324 <                                        ap[i] *= 1. + vw->vfore;
325 <                                        ap[i] += vw->vp[i];
324 >                                        ap[i] *= 1. + ourview.vfore;
325 >                                        ap[i] += ourview.vp[i];
326                                  }
327                          }
328 <                        viewloc(ip, vw, ap);            /* find image point */
329 <                        if (ip[2] <= 0.)
328 >                                                        /* find image point */
329 >                        if (viewloc(ip, &ourview, ap) <= 0)
330                                  return(0);              /* in front of view */
331                          sp[j][0] = ip[0]; sp[j][1] = ip[1];
332                  }
# Line 266 | Line 334 | FLOAT  sp[MAXVERT][2];
334          }
335                                          /* identify furthest corner */
336          for (i = 0; i < 3; i++)
337 <                ap[i] = s->sloc[i] - vw->vp[i];
337 >                ap[i] = s->sloc[i] - ourview.vp[i];
338          dir =   (DOT(ap,s->ss[SU])>0.) |
339                  (DOT(ap,s->ss[SV])>0.)<<1 |
340                  (DOT(ap,s->ss[SW])>0.)<<2 ;
# Line 281 | Line 349 | FLOAT  sp[MAXVERT][2];
349                          if (cubeord[dir][j] & 4) ap[i] += s->ss[SW][i];
350                          else ap[i] -= s->ss[SW][i];
351                  }
352 <                viewloc(ip, vw, ap);            /* find image point */
353 <                if (ip[2] <= 0.)
352 >                                                /* find image point */
353 >                if (viewloc(ip, &ourview, ap) <= 0)
354                          return(0);              /* in front of view */
355                  pt[j][0] = ip[0]; pt[j][1] = ip[1];
356          }
# Line 290 | Line 358 | FLOAT  sp[MAXVERT][2];
358   }
359  
360  
361 <                        /* add sources smaller than rad to computed subimage */
362 < drawsources(vw, xr, yr, pic, zbf, x0, xsiz, y0, ysiz, rad)
363 < VIEW    *vw;                            /* full image view */
364 < int     xr, yr;                         /* full image dimensions */
365 < COLOR   *pic[];                         /* subimage pixel value array */
298 < float   *zbf[];                         /* subimage distance array (opt.) */
299 < int     x0, xsiz, y0, ysiz;             /* origin and size of subimage */
300 < int     rad;                            /* source sample size */
361 >                        /* initialize by finding sources smaller than rad */
362 > void
363 > init_drawsources(
364 >        int     rad                             /* source sample size */
365 > )
366   {
367 <        int     sn;
368 <        FLOAT   spoly[MAXVERT][2], ppoly[MAXVERT][2];
369 <        int     nsv, npv;
370 <        int     xmin, xmax, ymin, ymax, x, y, i;
371 <        FLOAT   cxy[2];
372 <        double  pa;
373 <        RAY     sr;
367 >        RREAL   spoly[MAXVERT][2];
368 >        int     nsv;
369 >        SPLIST  *sp;
370 >        int     i;
371 >                                        /* free old source list if one */
372 >        for (sp = sphead; sp != NULL; sp = sphead) {
373 >                sphead = sp->next;
374 >                free((void *)sp);
375 >        }
376                                          /* loop through all sources */
377 <        for (sn = 0; sn < nsources; sn++) {
377 >        for (i = nsources; i--; ) {
378 >                                        /* skip illum's */
379 >                if (findmaterial(source[i].so)->otype == MAT_ILLUM)
380 >                        continue;
381                                          /* compute image polygon for source */
382 <                if (!(nsv = sourcepoly(vw, sn, spoly)))
382 >                if (!(nsv = sourcepoly(i, spoly)))
383                          continue;
384 +                                        /* clip to image boundaries */
385 +                if (!(nsv = box_clip_poly(spoly, nsv, 0., 1., 0., 1., spoly)))
386 +                        continue;
387 +                                        /* big enough for standard sampling? */
388 +                if (minw2(spoly, nsv, ourview.vn2/ourview.hn2) >
389 +                                (double)rad*rad/hres/hres)
390 +                        continue;
391 +                                        /* OK, add to our list */
392 +                spinsert(i, spoly, nsv);
393 +        }
394 + }
395 +
396 + void                            /* add sources smaller than rad to computed subimage */
397 + drawsources(
398 +        COLOR   *pic[],                         /* subimage pixel value array */
399 +        float   *zbf[],                         /* subimage distance array (opt.) */
400 +        int     x0,                             /* origin and size of subimage */
401 +        int     xsiz,
402 +        int     y0,
403 +        int     ysiz
404 + )
405 + {
406 +        RREAL   spoly[MAXVERT][2], ppoly[MAXVERT][2];
407 +        int     nsv, npv;
408 +        int     xmin, xmax, ymin, ymax, x, y;
409 +        RREAL   cxy[2];
410 +        double  w;
411 +        RAY     sr;
412 +        SPLIST  *sp;
413 +        int     i;
414 +                                        /* check each source in our list */
415 +        for (sp = sphead; sp != NULL; sp = sp->next) {
416                                          /* clip source poly to subimage */
417 <                nsv = box_clip_poly(spoly, nsv,
418 <                                (double)x0/xr, (double)(x0+xsiz)/xr,
419 <                                (double)y0/yr, (double)(y0+ysiz)/yr, spoly);
417 >                nsv = box_clip_poly(sp->vl, sp->nv,
418 >                                (double)x0/hres, (double)(x0+xsiz)/hres,
419 >                                (double)y0/vres, (double)(y0+ysiz)/vres, spoly);
420                  if (!nsv)
421                          continue;
320                                        /* is it big so sampling found it? */
321                if (minw2(spoly, nsv, vw->vn2/vw->hn2) > (double)rad*rad/xr/xr)
322                        continue;
422                                          /* find common subimage (BBox) */
423                  xmin = x0 + xsiz; xmax = x0;
424                  ymin = y0 + ysiz; ymax = y0;
425                  for (i = 0; i < nsv; i++) {
426 <                        if ((double)xmin/xr > spoly[i][0])
427 <                                xmin = spoly[i][0]*xr + FTINY;
428 <                        if ((double)xmax/xr < spoly[i][0])
429 <                                xmax = spoly[i][0]*xr - FTINY;
430 <                        if ((double)ymin/yr > spoly[i][1])
431 <                                ymin = spoly[i][1]*yr + FTINY;
432 <                        if ((double)ymax/yr < spoly[i][1])
433 <                                ymax = spoly[i][1]*yr - FTINY;
426 >                        if ((double)xmin/hres > spoly[i][0])
427 >                                xmin = spoly[i][0]*hres + FTINY;
428 >                        if ((double)xmax/hres < spoly[i][0])
429 >                                xmax = spoly[i][0]*hres - FTINY;
430 >                        if ((double)ymin/vres > spoly[i][1])
431 >                                ymin = spoly[i][1]*vres + FTINY;
432 >                        if ((double)ymax/vres < spoly[i][1])
433 >                                ymax = spoly[i][1]*vres - FTINY;
434                  }
435                                          /* evaluate each pixel in BBox */
436                  for (y = ymin; y <= ymax; y++)
437                          for (x = xmin; x <= xmax; x++) {
438                                                          /* subarea for pixel */
439                                  npv = box_clip_poly(spoly, nsv,
440 <                                                (double)x/xr, (x+1.)/xr,
441 <                                                (double)y/yr, (y+1.)/yr, ppoly);
440 >                                                (double)x/hres, (x+1.)/hres,
441 >                                                (double)y/vres, (y+1.)/vres,
442 >                                                ppoly);
443                                  if (!npv)
444                                          continue;       /* no overlap */
445                                  convex_center(ppoly, npv, cxy);
446 <                                if ((sr.rmax = viewray(sr.rorg, sr.rdir, vw,
447 <                                                cxy[0], cxy[1])) < -FTINY)
446 >                                if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview,
447 >                                                cxy[0],cxy[1])) < -FTINY)
448                                          continue;       /* not in view */
449 <                                if (source[sn].sflags & SSPOT &&
450 <                                                spotout(sr, source[sn].sl.s))
449 >                                if (source[sp->sn].sflags & SSPOT &&
450 >                                                spotout(&sr, source[sp->sn].sl.s))
451                                          continue;       /* outside spot */
452 <                                rayorigin(&sr, NULL, SHADOW, 1.0);
453 <                                sr.rsrc = sn;
452 >                                rayorigin(&sr, SHADOW, NULL, NULL);
453 >                                sr.rsrc = sp->sn;
454                                  rayvalue(&sr);          /* compute value */
455                                  if (bright(sr.rcol) <= FTINY)
456                                          continue;       /* missed/blocked */
457                                                          /* modify pixel */
458 +                                w = poly_area(ppoly, npv) * hres * vres;
459                                  if (zbf[y-y0] != NULL &&
460 <                                                sr.rt < zbf[y-y0][x-x0])
461 <                                        zbf[y-y0][x-x0] = sr.rt;
462 <                                pa = poly_area(ppoly, npv);
463 <                                scalecolor(sr.rcol, pa*xr*yr);
464 <                                scalecolor(pic[y-y0][x-x0], (1.-pa*xr*yr));
460 >                                                sr.rxt < 0.99*zbf[y-y0][x-x0]) {
461 >                                        zbf[y-y0][x-x0] = sr.rxt;
462 >                                } else if (!bigdiff(sr.rcol, pic[y-y0][x-x0],
463 >                                                0.01)) { /* source sample */
464 >                                        scalecolor(pic[y-y0][x-x0], w);
465 >                                        continue;
466 >                                }
467 >                                scalecolor(sr.rcol, w);
468 >                                scalecolor(pic[y-y0][x-x0], 1.-w);
469                                  addcolor(pic[y-y0][x-x0], sr.rcol);
470                          }
471          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines