home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / raytrace / dbw_render / source / c / INT < prev    next >
Encoding:
Text File  |  1992-10-23  |  8.0 KB  |  268 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. /* INT.C - calculations for ray intersections with primitives */
  25.  
  26. #define MODULE_INTER
  27. #include "ray.h"
  28.  
  29. node *get_next_intersection(which,best_p,best_t)
  30. int         which;
  31. vector      best_p;
  32. float       *best_t;
  33. {
  34.      /* This routine returns the pertinent data for the i'th intersection */
  35.  
  36.      if (which >= g_objcounter)
  37.           return NULL;  /* No more intersections */
  38.      else
  39.      {
  40.           *best_t   = g_distances[which];
  41.           veccopy(g_points[which],best_p);
  42.           return g_objpairs[which];
  43.      }
  44. }
  45.  
  46.  
  47. void add_intersection(np,p,t,attenuating)
  48. node        *np;
  49. vector      p;
  50. float       t;
  51. int         attenuating;
  52. {
  53.      int add;
  54.  
  55. /* 
  56.  *   This routine adds the passed intersection information to the global list
  57.  *   of intersections.  As a performance optimization,if we know that all
  58.  *   objects are opaque,then rather than accumulating the entire list and
  59.  *   sorting it later,we merely keep track of the closest intersection.
  60.  */
  61.      add = FALSE;
  62.  
  63.      if ( allopaque    == 0 ||  /* Some transparency, all everything */
  64.           g_objcounter == 0 ||  /* First opaque intersection         */
  65.           t < g_distances[0])
  66.      {
  67.           add = TRUE;  /* Nearer opaque intersection */
  68.      }
  69.      
  70.      if ( attenuating &&
  71.          np->attr.tra[0] >= .99 &&
  72.          np->attr.tra[1] >= .99 &&
  73.          np->attr.tra[2] >= .99)
  74.      {
  75.                add = FALSE;  /* ignore invisible objects when doing shadows */
  76.      }
  77.  
  78.      if (add) 
  79.      {
  80.           g_distances[g_objcounter] = t;
  81.           veccopy(p,g_points[g_objcounter]);
  82.           g_objpairs[g_objcounter] = np;
  83.           if (g_objcounter < MAXOBJ)
  84.                g_objcounter++;
  85.      }
  86. }
  87.  
  88. void calc_intersections(np,eye,d,attenuating)
  89. node      *np;           /* current node                     */
  90. vector    d;             /* direction vector for current ray */
  91. vector    eye;           /* current ray origin (eye point)   */
  92. int       attenuating;   /* attenuation factor for each hit  */
  93. {
  94.  
  95. /* 
  96.  *   This routine calculates the intersection of a ray with a given object.
  97.  *   If an intersection is found,the appropriate parameters are added to a
  98.  *   global list.  This routine is recursive,to handle nested extents. 
  99.  */
  100.  
  101.      vector      p;
  102.      float       t;
  103.      int         hit;
  104.      long        curs;
  105.  
  106.      /* keep track of maximum stack extent */
  107.      curs = curstack();
  108.      if (curs < stackbot)
  109.           stackbot = curs;
  110.  
  111.      while (np) 
  112.      {
  113.           hit = FALSE;
  114.           switch (np->kind) 
  115.           {
  116.           case EXTENT :
  117.                if (hitsphere(eptr(np)->center,eptr(np)->radius,eye,d,p,&t))
  118.                     calc_intersections(eptr(np)->sub,eye,d,attenuating);
  119.                break;
  120.  
  121.           case SPHERE :
  122.                hit = hitsphere(sptr(np)->center,sptr(np)->radius,eye,d,p,&t);
  123.                break;
  124.  
  125.           case TRIANGLE :
  126.                hit = hittriangle(np,eye,d,p,&t);
  127.                break;
  128.  
  129.           case QUAD :
  130.                hit = hitquad(np,eye,d,p,&t);
  131.                break;
  132.  
  133.           case RING :
  134.                hit = hitring(np,eye,d,p,&t);
  135.                break;
  136.  
  137.           case CYLINDER :
  138.                hit = hitcylinder(np,eye,d,p,&t);
  139.                break;
  140.  
  141.           default :
  142.                hit = FALSE;
  143.                break;
  144.           }
  145.  
  146.           if (hit)
  147.                add_intersection(np,p,t,attenuating);  /* Add to global list */
  148.  
  149.           np = np->next;  /* On to the next object */
  150.      }
  151. }
  152.  
  153. void all_intersects(eye,d,attenuating)
  154. vector  d;
  155. vector  eye;
  156. int     attenuating;
  157. {
  158.  
  159. /* 
  160.  *   This routine computes all of the ray-object intersections that occur for
  161.  *   the specified ray.  The intersections are stored in global arrays, sorted
  162.  *   closest intersection to furthest. 
  163.  */
  164.  
  165.      g_objcounter = 0;  /* Clear the intersection list */
  166.  
  167.      calc_intersections(root,eye,d,attenuating);  /* Find them & add to list */
  168.  
  169.      if (g_objcounter > 1)
  170.           shell(g_distances,g_points,g_objpairs,g_objcounter);  /* Sort them */
  171.  
  172.      /* Keep statistics (and decide when to GIVE UP!!) */
  173.      if (++curr_runs >= max_runs)
  174.           longjmp(env,-1);
  175.  
  176.      if (g_objcounter > max_intersects)
  177.           max_intersects = g_objcounter;
  178. }
  179.  
  180. int bouncelighting(pseudointensity,pseudolitdir,bouncenp,lit)
  181. vector  pseudointensity,
  182.   pseudolitdir;
  183. node    *bouncenp;
  184. int     lit;
  185. {
  186.      vector n,bouncepoint,lightdir;
  187.  
  188.      if (bouncenp->kind == SPHERE || bouncenp->attr.ref == 0.0)
  189.           return FALSE;  /* No pseudo light source from here */
  190.      else
  191.      { 
  192.           switch (bouncenp->kind) 
  193.           {
  194.           case TRIANGLE :
  195.                veccopy(tptr(bouncenp)->position,bouncepoint);
  196.                break;
  197.           case QUAD     :
  198.                veccopy(qptr(bouncenp)->position,bouncepoint);
  199.                break;
  200.           case RING     :
  201.                veccopy(rptr(bouncenp)->position,bouncepoint);
  202.                break;
  203.           }
  204.           findnormal(bouncenp,bouncepoint,n);
  205.           veccopy(light[lit].direction,lightdir);  /* Assume directional light */
  206.           if (light[lit].kind != 0) 
  207.           { /* Point source */
  208.                DIRECTION(bouncepoint,lightdir,lightdir);
  209.           }
  210.  
  211.           vecscale(2.0 * DOT(lightdir,n),n,pseudolitdir);
  212.           vecsub(lightdir,pseudolitdir,pseudolitdir);
  213.           vecscale(bouncenp->attr.ref,light[lit].intensity,pseudointensity);
  214.           return TRUE;
  215.      }
  216. }
  217.  
  218. void blendcolor(original,target,scale,result)
  219. vector original;
  220. vector target;
  221. vector result;
  222. float  scale;
  223. {
  224.      vector path;
  225.  
  226.      if (scale < 0.0)
  227.           scale = 0.0;  /* clip off excessive blending */
  228.      if (scale > 1.0)
  229.           scale = 1.0;
  230.      vecsub(target,original,path);
  231.      vecscale(scale,path,path);
  232.      vecsum(original,path,result);
  233. }
  234.  
  235. void getatten(atten,p,d,lit,pointdist)
  236. vector atten;
  237. vector p;
  238. vector d;
  239. int    lit;
  240. float  pointdist;
  241. {
  242.      vector  best_p;
  243.      float   best_t;
  244.      int     hitnext;
  245.  
  246. #ifdef MCH_AMIGA
  247.      node    *occlude = 1L;
  248. #else
  249.      node    *occlude = (node *)1L;
  250. #endif
  251.  
  252.      atten[0] = 1.0;  /* assume no attenuation */
  253.      atten[1] = 1.0;
  254.      atten[2] = 1.0;
  255.      hitnext = 0;
  256.      all_intersects(p,d,1);  /* Compute all intersections */
  257.  
  258.      while (occlude && (atten[0] > 0.01 || atten[1] > 0.01 || atten[2] > 0.01))
  259.           if (occlude = get_next_intersection(hitnext,best_p,&best_t)) 
  260.           {
  261.                if (light[lit].kind == 0 || best_t <= pointdist) 
  262.                {
  263.                     vecmul(atten,occlude->attr.tra,atten);
  264.                }
  265.                hitnext++;
  266.           }
  267. }
  268.