home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / util / raytracr.sit / shade.c.bin / shade.c
Encoding:
C/C++ Source or Header  |  1988-11-15  |  3.4 KB  |  138 lines  |  [TEXT/KAHL]

  1. #define _MC68881_
  2.  
  3. /*
  4.  * this subroutine does all the gritty work- it calculates 
  5.  * what shade each pixel should be. I like recursion.
  6.  */
  7. #include <math.h>
  8. #include "rtd.h"
  9. #include "macros.h"
  10. #include "extern.h"
  11.  
  12. int     shade (r)
  13. struct ray *r;
  14. {
  15.     int     i,
  16.             c,
  17.             refract ();
  18.     struct ray  refr;
  19.     double  lght,
  20.             x,
  21.             y,
  22.             z,
  23.             l,
  24.             k,
  25.             dot (), find (), Shadow ();
  26.     int     sx,
  27.             sy;
  28.     double  stupid;
  29.     struct vector   new,
  30.                     norm;
  31.     struct mat  trans;
  32.     struct sphere   ss;
  33.     if (++level <= LEVEL) {
  34.     c = -1;
  35.     l = HUGE;
  36. /* get vector length and xz component for mt() */
  37.     r -> dir.l = LEN (r -> dir);
  38.     r -> dir.xzl = XZL (r -> dir);
  39. /* make a transform matrix that rotates something in space so
  40.    that the ray will be aligned with the x axis */
  41.     mt (&(r -> dir), &trans);
  42.  
  43. /* for starters we find out whether we hit anything. */
  44.     for (i = 0; i < nob; i++) {
  45.         ss.rad = bl[i] -> s.rad;
  46.         SV (ss.cent, bl[i] -> s.cent, r -> org);
  47.         if ((k = find (&trans, &ss)) > 0.0 && k < l) {
  48.         c = i;
  49.         l = k;
  50.         }
  51.     }
  52.  
  53.     
  54.     if (c >= 0 && (l * trans.x.y + r -> org.y) > 0.0) {
  55.                 /* WE HIT SOMETHING */
  56.         MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
  57.         new.l=l;
  58. /* move the new orgin of the ray to the intersection */
  59.         AV (refr.org, new, r -> org);
  60.         AV (r -> org, new, r -> org);
  61.         MV (r -> dir.x, r -> dir.y, r -> dir.z, refr.dir);
  62. /* get a normal vector for the intersection point */
  63.         SV (norm, r -> org, bl[c] -> s.cent);
  64.         norm.l=bl[c] ->s.rad;
  65.  
  66. /* ambient lighting */
  67.         lght = 200.0 * bl[c] -> amb;
  68.  
  69. /* shaded lighting (diffuse). subroutine Shadow is in find.c */
  70.         if (bl[c] -> dif != 0.0) {
  71.         SV (new, ls.cent, r -> org);
  72.         new.l = LEN(new);
  73.         if ((k = DOT (new, norm)) > 0.0)
  74.             lght += bl[c] -> dif * Shadow (&(r -> org)) * k / (new.l) / (norm.l);
  75.         }
  76.  
  77.     CallStdEvent();
  78. /*reflection... easy */
  79.            if (bl[c] -> rfl != 0.0) {
  80. /* make the normal unit length */
  81.         SCMLT ((1.0 / norm.l), norm);
  82. /* get the length of the ray's component in the normal direction */
  83.         stupid = 2.0 * DOT (norm, r -> dir);
  84.         SCMLT (stupid, norm);
  85. /* subtract double the normal component- !reflection! */
  86.         SV (r -> dir, r -> dir, norm);
  87.         lght += bl[c] -> rfl * (double) shade (r);
  88.         }
  89.  
  90. /* refraction. this is ugly, which is why I choose to deal with
  91.    it in it's own subroutine which comes after this one */
  92.         if (bl[c] -> rfr != 0.0) {
  93.         lght += bl[c] -> rfr * (double) refract (&refr, bl[c]);
  94.         }
  95.  
  96.  
  97.  
  98.     }
  99.     else {            /* hit no objects... */
  100.         if ((r -> dir.y) < 0.0) {/* crosses floor */
  101.         z = -(r -> org.y) / (r -> dir.y);
  102.         (r -> org.x) += z * (r -> dir.x);
  103.         (r -> org.z) += z * (r -> dir.z);
  104.         (r -> org.y) = 0.0;
  105.  
  106.         SV (new, ls.cent, r -> org);
  107.         new.l = LEN(new);
  108.         sx = (int) (r -> org.x / 1.5) % xsue;
  109.         if (sx < 0)
  110.             sx += xsue;
  111.         sy = -(int) (r -> org.z / 1.5) % ysue;
  112.         if (sy < 0)
  113.             sy += ysue;
  114.         lght = (sam * suzie[sx][sy] + 1.0 - sam) * (0.8 *
  115.             Shadow (&(r -> org)) * (new.y) / (new.l) + 40.0);
  116.  
  117.  
  118.         }
  119.         else {        /* check to see if it hit lightsource */
  120.         SV (ss.cent, ls.cent, r -> org);
  121.         ss.rad = ls.rad;
  122.         if (find (&trans, &(ss.cent)) > 0.0)
  123.             lght = 255;
  124.         else
  125.             lght = 0;
  126.         }
  127.     }
  128.     }
  129. /* to many levels return 0 cause it shouldn't matter */
  130.     else
  131.     lght = 0;
  132.     level--;
  133.     if (lght < 0.0)
  134.     lght = 0.0;
  135.     if (lght > 255.0)
  136.     lght = 255.0;
  137.     return ((int) lght);
  138. }