home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 015.lha / tracer_source / shade.c < prev    next >
C/C++ Source or Header  |  1986-11-10  |  6KB  |  322 lines

  1. /*
  2.  * this subroutine does all the gritty work- it calculates 
  3.  * what shade each pixel should be. I like recursion.
  4.  */
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include "MyMath.h"
  8. #include "rtd.h"
  9. #include "macros.h"
  10. #include "extern.h"
  11.  
  12. extern    FFP    big,
  13.         little;
  14.  
  15. int    shade (r)
  16. struct    ray    *r;
  17. {
  18.     int    i,
  19.         c,
  20.         refract ();
  21.  
  22.     struct    ray    refr;
  23.  
  24.     FFP    lght,
  25.         z,
  26.         l,
  27.         k,
  28.         sanity,
  29.         find (), shadow ();
  30.  
  31.     int    sx,
  32.         sy;
  33.  
  34.     FFP    stupid;
  35.  
  36.     struct    vector    new,
  37.             norm;
  38.  
  39.     struct    mat    trans;
  40.  
  41.     struct    sphere    ss;
  42.  
  43.     if (++level <= LEVEL) {
  44.         c = -1;
  45.         l = ieee_to_ffp(1.0e37);
  46.  
  47.         /* get vector length and xz component for mt() */
  48.         r -> dir.l = LEN (r -> dir);
  49.         r -> dir.xzl = XZL (r -> dir);
  50.  
  51.         /*
  52.             make a transform matrix that rotates
  53.             something in space so that the ray will
  54.             be aligned with the x axis
  55.         */
  56.         mt (&(r -> dir), &trans);
  57.  
  58.         /* for starters we find out whether we hit anything. */
  59.         for (i = 0; i < nob; i++) {
  60.             ss.rad = bl[i] -> s.rad;
  61.             SV (ss.cent, bl[i] -> s.cent, r -> org);
  62.             k = find (&trans, &ss);
  63. /*
  64.             if( SPTst( k ) > 0 )
  65.                 printf("k = %f\n", ffp_to_ieee(k) );
  66. */
  67.             if (
  68.                 ( SPTst( k ) > 0 )    /* k>0.0 */
  69.                 && 
  70.                 ( SPCmp(l, k) > 0 )    /* k<l */
  71.             ) {
  72.                 c = i;
  73.                 l = k;
  74.             }
  75.         }
  76.  
  77.         if (
  78.             c >= 0 && 
  79.             SPTst( SPAdd( SPMul(l, trans.x.y), r->org.y)) > 0
  80.         ) {
  81.             /* WE HIT SOMETHING */
  82. /*
  83.             printf("HIT: ball # %d, l = %f\n",
  84.                 c, ffp_to_ieee(l) );
  85. */
  86.             MV (SPMul(l, trans.x.x),SPMul(l, trans.x.y),SPMul(l, trans.x.z),new );
  87.  
  88.             /*
  89.                 move the new orgin of the ray
  90.                 to the intersection
  91.             */
  92.             AV (refr.org, new, r -> org);
  93.             AV (r -> org, new, r -> org);
  94.             MV (r -> dir.x, r -> dir.y, r -> dir.z, refr.dir);
  95.  
  96.             /* get a normal vector for the intersection point */
  97.             SV (norm, r -> org, bl[c] -> s.cent);
  98.             norm.l = LEN (norm);
  99.  
  100.             /* ambient lighting */
  101.             lght = SPMul( SPFlt(200), bl[c] -> amb);
  102.  
  103.             /*
  104.                 shaded lighting (diffuse).
  105.                 subroutine shadow is in find.c
  106.             */
  107.             if ( SPTst( bl[c] -> dif) ) {
  108.                 SV (new, ls.cent, r -> org);
  109.                 new.l = LEN (new);
  110.  
  111.                 if( SPTst( (k=DOT(new, norm)) ) > 0)
  112.                     lght =    SPAdd(
  113.                          SPDiv(
  114.                           (norm.l),
  115.                           SPDiv(
  116.                            (new.l),
  117.                            SPMul(
  118.                             SPMul(
  119.                              bl[c]->dif,
  120.                              shadow( &(r -> org) )
  121.                             ),
  122.                             k
  123.                            )
  124.                           )
  125.                          ),
  126.                          lght
  127.                         );
  128.  
  129. /*
  130.                     lght += bl[c]->dif *
  131.                         shadow( &(r -> org) ) *
  132.                         k / (new.l) / (norm.l);
  133. */
  134.             }
  135.  
  136.             /*reflection... easy */
  137.             if ( SPTst(bl[c] -> rfl) ) {
  138.                 /* make the normal unit length */
  139.                 norm.l = LEN (norm);
  140.                 SCMLT ( SPDiv(norm.l, SPFlt(1) ), norm);
  141.  
  142.                 /*
  143.                     get the length of the ray's 
  144.                     component in the normal direction
  145.                 */
  146.                 stupid = SPMul(
  147.                         SPFlt(2),
  148.                         DOT (norm, r -> dir)
  149.                     );
  150.                 SCMLT (stupid, norm);
  151.  
  152.                 /*
  153.                     subtract double the normal
  154.                     component-!reflection!
  155.                 */
  156.                 SV (r -> dir, r -> dir, norm);
  157.                 lght =    SPAdd(
  158.                         lght,
  159.                         SPMul(
  160.                             bl[c] -> rfl, 
  161.                             SPFlt( shade (r) )
  162.                         )
  163.                     );
  164. /*
  165.                 lght += bl[c] -> rfl * (double) shade (r);
  166. */
  167.             }
  168.  
  169.             /*
  170.                 refraction. this is ugly as sin,
  171.                 which is why I choose to deal with
  172.                 it in it's own subroutine, which is 
  173.                 in it's own file now.
  174.             */
  175.             if ( SPTst(bl[c] -> rfr) ) {
  176.                 lght =     SPAdd(
  177.                       lght,
  178.                       SPMul(
  179.                         bl[c] -> rfr,
  180.                         SPFlt( refract (&refr, bl[c] ) )
  181.                       )
  182.                     );
  183. /*
  184.                 lght += bl[c] -> rfr *
  185.                     (double) refract (&refr, bl[c]);
  186. */
  187.             }
  188.  
  189.         } else {
  190.             /* hit no objects... */
  191.             if (SPTst(r -> dir.y) < 0) {
  192.                 /* crosses floor */
  193.                 z = SPDiv(
  194.                     (r -> dir.y),
  195.                     SPNeg(r -> org.y)
  196.                 );
  197.  
  198.                 (r -> org.x) =    SPAdd(
  199.                             (r -> org.x),
  200.                             SPMul(
  201.                                 z, 
  202.                                 (r -> dir.x)
  203.                             )
  204.                         );
  205.  
  206.                 (r -> org.z) =    SPAdd(
  207.                             (r -> org.z),
  208.                             SPMul(
  209.                                 z, 
  210.                                 (r -> dir.z)
  211.                             )
  212.                         );
  213. /*
  214.                 z = -(r -> org.y) / (r -> dir.y);
  215.                 (r -> org.x) += z * (r -> dir.x);
  216.                 (r -> org.z) += z * (r -> dir.z);
  217. */
  218.  
  219.                 (r -> org.y) = SPFlt(0);
  220.  
  221.                 /*
  222.                     find out the mod of the value to 
  223.                     see where it hits susie. (ouch)
  224.                     mess here if you only want the
  225.                     pattern once.
  226.                 */
  227.                 SV (new, ls.cent, r -> org);
  228.                 new.l = LEN (new);
  229.  
  230.                 sx =    SPFix(
  231.                         SPDiv(
  232.                             ieee_to_ffp(1.5),
  233.                             r -> org.x
  234.                         )
  235.                     ) % xsue;
  236.  
  237.                 if (sx < 0)
  238.                     sx += xsue;
  239.  
  240.                 sy =    -SPFix(
  241.                         SPDiv(
  242.                             ieee_to_ffp(1.5),
  243.                             r -> org.z
  244.                         )
  245.                     ) % ysue;
  246.  
  247. /*
  248.                 sy = -(int) (r -> org.z / 1.5) % ysue;
  249. */
  250.  
  251.                 if (sy < 0)
  252.                     sy += ysue;
  253. /*
  254.                 lght =    (
  255.                         sam *
  256.                         suzie[sx][sy]+ 
  257.                         1.0 - sam
  258.                     ) * 
  259.                     (0.8 * shadow (&(r -> org)) *
  260.                     (new.y) / (new.l) + 40.0);
  261. */
  262.  
  263.                 sanity = SPMul(
  264.                       sam,
  265.                       SPAdd(
  266.                         SPSub(
  267.                           sam,
  268.                           SPFlt(1)
  269.                         ),
  270.                         SPDiv(
  271.                           big,
  272.                           SPSub(
  273.                         little,
  274.                         SPFlt(suzie[sx][sy])
  275.                           )
  276.                         )
  277.                       )
  278.                     );
  279.             
  280.                 lght =    SPAdd(
  281.                       SPFlt(40),
  282.                       SPDiv(
  283.                         (new.l),
  284.                         SPMul(
  285.                           (new.y),
  286.                           SPMul(
  287.                         ieee_to_ffp(0.8),
  288.                         SPMul(
  289.                           shadow ( &(r -> org) ),
  290.                           sanity
  291.                         )
  292.                           )
  293.                         )
  294.                       )
  295.                     );
  296.  
  297.             } else {
  298.                 /* check to see if it hit lightsource */
  299.                 SV (ss.cent, ls.cent, r -> org);
  300.                 ss.rad = ls.rad;
  301.                 if (SPTst(find (&trans, &(ss.cent))) > 0)
  302.                     lght = SPFlt(255);
  303.                 else
  304.                     lght = SPFlt(0);
  305.             }
  306.         }
  307.     }
  308.         /* too many levels return 0 cause it shouldn't matter */
  309.     else
  310.         lght = SPFlt(0);
  311.     level--;
  312.  
  313.     if (SPTst(lght) < 0)
  314.         lght = SPFlt(0);
  315.  
  316.     if (SPCmp(lght, SPFlt(255) ) > 0 )
  317.         lght = SPFlt(255);
  318.  
  319.  
  320.     return ( SPFix(lght) );
  321. }
  322.