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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines