home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / RT / M_MIRROR.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  3KB  |  119 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)m_mirror.c 2.1 11/12/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Routines for mirror material supporting virtual light sources
  9.  */
  10.  
  11. #include  "ray.h"
  12.  
  13. #include  "otypes.h"
  14.  
  15. #include  "source.h"
  16.  
  17. /*
  18.  * The real arguments for MAT_MIRROR are simply:
  19.  *
  20.  *    3 rrefl grefl brefl
  21.  *
  22.  * Additionally, the user may specify a single string argument
  23.  * which is interpreted as the name of the material to use
  24.  * instead of the mirror if the ray being considered is not
  25.  * part of the direct calculation.
  26.  */
  27.  
  28.  
  29. int  mir_proj();
  30. VSMATERIAL  mirror_vs = {mir_proj, 1};
  31.  
  32.  
  33. m_mirror(m, r)            /* shade mirrored ray */
  34. register OBJREC  *m;
  35. register RAY  *r;
  36. {
  37.     COLOR  mcolor;
  38.     RAY  nr;
  39.     register int  i;
  40.                     /* check arguments */
  41.     if (m->oargs.nfargs != 3 || m->oargs.nsargs > 1)
  42.         objerror(m, USER, "bad number of arguments");
  43.                     /* check for substitute material */
  44.     if (m->oargs.nsargs > 0 &&
  45.             (r->rsrc < 0 || source[r->rsrc].so != r->ro)) {
  46.         rayshade(r, modifier(m->oargs.sarg[0]));
  47.         return;
  48.     }
  49.                     /* check for bad source ray */
  50.     if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
  51.         return;
  52.  
  53.     if (r->rod < 0.)        /* back is black */
  54.         return;
  55.                     /* get modifiers */
  56.     raytexture(r, m->omod);
  57.                     /* assign material color */
  58.     setcolor(mcolor, m->oargs.farg[0],
  59.             m->oargs.farg[1],
  60.             m->oargs.farg[2]);
  61.     multcolor(mcolor, r->pcol);
  62.                     /* compute reflected ray */
  63.     if (r->rsrc >= 0) {            /* relayed light source */
  64.         rayorigin(&nr, r, REFLECTED, 1.);
  65.                     /* ignore textures */
  66.         for (i = 0; i < 3; i++)
  67.             nr.rdir[i] = r->rdir[i] + 2.*r->rod*r->ron[i];
  68.                     /* source we're aiming for next */
  69.         nr.rsrc = source[r->rsrc].sa.sv.sn;
  70.     } else {                /* ordinary reflection */
  71.         FVECT  pnorm;
  72.         double  pdot;
  73.  
  74.         if (rayorigin(&nr, r, REFLECTED, bright(mcolor)) < 0)
  75.             return;
  76.         pdot = raynormal(pnorm, r);    /* use textures */
  77.         for (i = 0; i < 3; i++)
  78.             nr.rdir[i] = r->rdir[i] + 2.*pdot*pnorm[i];
  79.     }
  80.     rayvalue(&nr);
  81.     multcolor(nr.rcol, mcolor);
  82.     addcolor(r->rcol, nr.rcol);
  83. }
  84.  
  85.  
  86. mir_proj(pm, o, s, n)        /* compute a mirror's projection */
  87. MAT4  pm;
  88. register OBJREC  *o;
  89. SRCREC  *s;
  90. int  n;
  91. {
  92.     FVECT  nv;
  93.     double  od;
  94.                 /* get surface normal and offset */
  95.     od = getplaneq(nv, o);
  96.                 /* check for behind */
  97.     if (DOT(s->sloc, nv) <= (s->sflags & SDISTANT ? FTINY : od+FTINY))
  98.         return(0);
  99.                 /* everything OK -- compute projection */
  100.     mirrorproj(pm, nv, od);
  101.     return(1);
  102. }
  103.  
  104.  
  105. mirrorproj(m, nv, offs)        /* get mirror projection for surface */
  106. register MAT4  m;
  107. FVECT  nv;
  108. double  offs;
  109. {
  110.     register int  i, j;
  111.                     /* assign matrix */
  112.     setident4(m);
  113.     for (j = 0; j < 3; j++) {
  114.         for (i = 0; i < 3; i++)
  115.             m[i][j] -= 2.*nv[i]*nv[j];
  116.         m[3][j] = 2.*offs*nv[j];
  117.     }
  118. }
  119.