home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / raytrace / dbw_render / source / c / CAL next >
Encoding:
Text File  |  1992-10-23  |  7.3 KB  |  238 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1987, David B. Wecker                 *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * This file is part of DBW_Render                                      *
  7.  *                                                                      *
  8.  * DBW_Render is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts               *
  10.  * responsibility to anyone for the consequences of using it or for     *
  11.  * whether it serves any particular purpose or works at all, unless     *
  12.  * he says so in writing. Refer to the DBW_Render General Public        *
  13.  * License for full details.                                            *
  14.  *                                                                      *
  15.  * Everyone is granted permission to copy, modify and redistribute      *
  16.  * DBW_Render, but only under the conditions described in the           *
  17.  * DBW_Render General Public License. A copy of this license is         *
  18.  * supposed to have been given to you along with DBW_Render so you      *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this     *
  21.  * notice must be preserved on all copies.                              *
  22.  ************************************************************************
  23.  
  24.  
  25. #define MODULE_CALC
  26. #include "ray.h"
  27.  
  28. void spherenormal(center,p,n)
  29. vector   center,p,n;
  30. {
  31.      DIRECTION(center,p,n);
  32. }
  33.  
  34. void planenormal(ve,vp,n)
  35. vector ve, vp, n;
  36. {
  37.      cross(vp,ve,n);
  38.      normalize(n);
  39. }
  40.  
  41. void calcripple(point,w,ripple)
  42. vector  point;
  43. int     w;
  44. vector  ripple;
  45. {
  46.      float riprad,temp1,temp2,temp3,damper;
  47.      int iriprad;
  48.  
  49.      direction(point,wave[w].center,ripple); /* unit vector pointing away from wave center */
  50.  
  51.      temp1 = wave[w].center[0] - point[0];
  52.      temp2 = wave[w].center[1] - point[1];
  53.      temp3 = wave[w].center[2] - point[2];
  54.  
  55.      temp1 = temp1 * temp1;  /* square it */
  56.      temp2 = temp2 * temp2;  /* square it */
  57.      temp3 = temp3 * temp3;  /* square it */
  58.  
  59.      riprad = (float)sqrt(temp1 + temp2 + temp3);  /* distance from center to point */
  60.      riprad += wave[w].propagate * wave[w].wavelength;  /* move it */
  61.  
  62.      riprad /= wave[w].wavelength;  /* scale half-wave crest to 0..1 */
  63.      if (wave[w].drag == 1.0) 
  64.           damper = 1.0;
  65.      else 
  66.           damper = (float)pow(wave[w].drag,riprad);  /* exponential damping */
  67.  
  68.      iriprad = (int) riprad;
  69.      if (iriprad & 1)  
  70.      {               /* negate it */
  71.           ripple[0] = -ripple[0];
  72.           ripple[1] = -ripple[1];
  73.           ripple[2] = -ripple[2];
  74.      }
  75.      riprad -= (float) iriprad;  /* just get fraction 0..1 */
  76.      riprad -= 0.5;  /* scale to -0.5 .. +0.5 */
  77.      if (riprad < 0.0) 
  78.           riprad = -riprad;  /* absolute value */
  79.      riprad  = 0.5 - riprad;  /* invert */
  80.      riprad *= damper;
  81.      riprad *= wave[w].amplitude;
  82.      vecscale(riprad,ripple,ripple);  /* scale bend */
  83. }
  84.  
  85. void noise3(point,total)
  86. vector  point,
  87.   total;
  88. {
  89.      vector ripple;
  90.      float s;
  91.      int w;
  92.  
  93.      veczero(total);
  94.      for (w = 0; w < numwaves; w++) 
  95.      {
  96.           calcripple(point,w,ripple);  /* calculate the wave perturbation */
  97.           vecsum(ripple,total,total); /* sum the ripple bends */
  98.      }
  99.      s = NORM(total);
  100.      if (s < 0.001) 
  101.           total[0] = 1.0;
  102.      else 
  103.      {
  104.           s = 1.0 / s;
  105.           vecscale(s,total,total);  /* Make it unit vector */
  106.      }
  107. }
  108.  
  109.  
  110. float noise(point)
  111. vector point;
  112. {
  113.      vector total;
  114.      float s;
  115.  
  116.      noise3(point,total);
  117.      s = total[0] + total[1] + total[2];  /* sum is between -sqrt(3)..+sqrt(3) */
  118.      s += sqrt3;  /* now between 0.0 and 2*sqrt(3) */
  119.      s /= sqrt3times2;  /* scale to range 0..1 */
  120.  
  121.      return( s );
  122. }
  123.  
  124. float turbulence(point)
  125. vector point;
  126. {
  127.      vector temp;
  128.      float t,scale;
  129.  
  130.      if (numwaves > 0) 
  131.      {
  132.           t = 0.0;
  133.           scale = 1.0;
  134.  
  135.           while (scale < 64.0) 
  136.           {
  137.                vecscale(scale,point,temp);
  138.                t += fabs(noise(temp) / scale);
  139.                scale *= 2.0;
  140.           }
  141.      }
  142.      else 
  143.      {
  144.           t = 1.5;
  145.      }
  146.  
  147.      return( t );
  148. }
  149.  
  150. void dodirection(val,eye2,d2,atten,amblits)
  151. vector val;
  152. vector eye2;
  153. vector d2;
  154. float  atten;
  155. int    amblits;
  156. {
  157.      vector transparency,nextval,best_p,n,temp,q,eye,d;
  158.  
  159. #ifdef MCH_AMIGA
  160.      node *best_obj = 1L;
  161. #else
  162.      node *best_obj = (node *)1L;
  163. #endif
  164.  
  165.      float best_t,qnorm,ddotn,n1,n2;
  166.      int hitnext;
  167.  
  168.      /* make local modifyable copies */
  169.      veccopy(eye2,eye);
  170.      veccopy(d2,d);
  171.      veczero(val);
  172.      CV(1.0,1.0,1.0,transparency);
  173.      all_intersects(eye,d,0);
  174.  
  175.      hitnext = 0;
  176.      while ( best_obj && 
  177.        (transparency[0] > 0.01 ||
  178.        transparency[1] > 0.01 || 
  179.        transparency[2] > 0.01 ) ) 
  180.      {
  181.           best_obj = get_next_intersection(hitnext,best_p,&best_t);
  182.           if (best_obj) 
  183.           {
  184.                getval(nextval,best_obj,best_p,d,atten,amblits);
  185.                vecmul(transparency,nextval,nextval);
  186.                vecsum(val,nextval,val);
  187.                vecmul(best_obj->attr.tra,transparency,transparency);
  188.  
  189.                if (transparency[0] > 0.01 ||  /* Can some light get through? */
  190.                  transparency[1] > 0.01 ||
  191.                  transparency[2] > 0.01)
  192.                     if ((best_obj->attr.idx != idxref) ||  /* Is it refractive? */
  193.                       (best_obj->kind     == SPHERE)) 
  194.                     {               /* Is it a volume object? */
  195.  
  196.                          /* apply refraction by changing ray direction and origin */
  197.  
  198.                          findnormal(best_obj,best_p,n);
  199.                          ddotn = DOT(d,n);
  200.  
  201.                          if (ddotn < 0.0) 
  202.                          {
  203.                               n2 = best_obj->attr.idx;
  204.                               n1 = idxref;
  205.                          }
  206.                          else 
  207.                          {
  208.                               n1 = best_obj->attr.idx;
  209.                               n2 = idxref;
  210.                               n[0] = -n[0];  /* Negate the normal */
  211.                               n[1] = -n[1];
  212.                               n[2] = -n[2];
  213.                               ddotn = -ddotn;
  214.                          }
  215.  
  216.                          vecscale(ddotn,n,temp);
  217.                          vecsub(d,temp,temp);
  218.                          vecscale(n1 / n2,temp,q);
  219.  
  220.                          qnorm = NORM(q);  /* magnitude */
  221.                          if (qnorm >= 1.0)
  222.                               best_obj = NULL;  /* past critical angle,no more light */
  223.                          else 
  224.                          {
  225.                               vecscale(sqrt(1.0-(qnorm*qnorm)),n,temp);
  226.                               vecsub(q,temp,d);
  227.                               veccopy(best_p,eye);
  228.                               hitnext = -1;  /* new direction vector,so re-depth-sort intersections */
  229.                               all_intersects(eye,d,0);  /* Compute intersections with new ray */
  230.                          }
  231.                     }
  232.                hitnext++;
  233.           }
  234.      }
  235.      vecmul(backgroundval,transparency,nextval);
  236.      vecsum(val,nextval,val);
  237. }
  238.