home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / libray / libobj / intersect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-09  |  4.2 KB  |  184 lines

  1. /*
  2.  * intersect.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * intersect.c,v 4.1 1994/08/09 07:59:29 explorer Exp
  17.  *
  18.  * intersect.c,v
  19.  * Revision 4.1  1994/08/09  07:59:29  explorer
  20.  * Bump version to 4.1
  21.  *
  22.  * Revision 1.1.1.1  1994/08/08  04:52:09  explorer
  23.  * Initial import.  This is a prerelease of 4.0.6enh3, or 4.1 possibly.
  24.  *
  25.  * Revision 4.0  91/07/17  14:38:37  kolb
  26.  * Initial version.
  27.  * 
  28.  */
  29. #include "geom.h"
  30.  
  31. static void AddToHitList();
  32. /*
  33.  * Number of bounding volume tests.
  34.  * External modules have read access via IntersectStats().
  35.  */
  36. static unsigned long BVTests;
  37.  
  38. /*
  39.  * Intersect object & ray.  Return distance from "pos" along "ray" to
  40.  * intersection point.  Return value <= 0 indicates no intersection.
  41.  */
  42. int
  43. intersect(obj, ray, hitlist, mindist, maxdist)
  44. Geom *obj;                /* Geom to be tested. */
  45. Ray *ray;                /* Ray origin, direction. */
  46. HitList *hitlist;            /* Intersection path */
  47. Float mindist, *maxdist;
  48. {
  49.     Ray newray;
  50.     Vector vtmp;
  51.     Trans *curtrans;    
  52.     Float distfact, nmindist, nmaxdist;
  53.  
  54.     /*
  55.      * Check ray/bounding volume intersection, if required.
  56.      */
  57.     if (obj->methods->checkbounds) {
  58.         VecAddScaled(ray->pos, mindist, ray->dir, &vtmp);
  59.         if (OutOfBounds(&vtmp, obj->bounds)) {
  60.             nmaxdist = *maxdist;
  61.             BVTests++;
  62.             if (!BoundsIntersect(ray, obj->bounds, mindist,
  63.                             &nmaxdist))
  64.                 return FALSE;
  65.         }
  66.     }
  67.  
  68.     newray = *ray;
  69.     nmindist = mindist;
  70.     nmaxdist = *maxdist;
  71.  
  72.     /*
  73.      * Transform the ray if necessary.
  74.      */
  75.     if (obj->trans != (Trans *)0) {
  76.         /*
  77.          * If object's idea of the current time is wrong,
  78.          * update the transformations.
  79.          */
  80.         if (obj->animtrans && !equal(obj->timenow, ray->time)) {
  81.             TransResolveAssoc(obj->trans);
  82.         }
  83.                 
  84.         /*
  85.          * Transforming the ray can change the distance between
  86.          * the ray origin and the point of intersection.
  87.          * We save the amount the ray is "stretched" and later
  88.          * divide the computed distance by this amount.
  89.          */
  90.         distfact = 1.;
  91.         for (curtrans = obj->transtail; curtrans; 
  92.              curtrans = curtrans->prev)
  93.             distfact *= RayTransform(&newray, &curtrans->itrans);
  94.         nmindist *= distfact;
  95.         nmaxdist *= distfact;
  96.     }
  97.     /*
  98.      * Geom has been updated to current time.
  99.      */
  100.     obj->timenow = ray->time;
  101.  
  102.     /*
  103.      * Call correct intersection routine.
  104.      */
  105.     if (IsAggregate(obj)) {
  106.         /*
  107.          * Aggregate
  108.          */
  109.         if (!(*obj->methods->intersect)
  110.              (obj->obj, &newray, hitlist, nmindist, &nmaxdist))
  111.         return FALSE;
  112.     } else {
  113.         /*
  114.          * Primitive
  115.          */
  116.         if (!(*obj->methods->intersect)
  117.               (obj->obj, &newray, nmindist, &nmaxdist))
  118.             return FALSE;
  119.         hitlist->nodes = 0;
  120.     }
  121.  
  122.     /*
  123.      * Had a hit -- add ray, distance and object to tail of hitlist.
  124.      */
  125.     AddToHitList(hitlist, &newray, nmindist, nmaxdist, obj);
  126.  
  127.     /*
  128.      * Set dist to distance to intersection point from the origin
  129.      * of the untransformed ray.
  130.      */
  131.     if (obj->trans != (Trans *)0)
  132.         *maxdist = nmaxdist / distfact;
  133.     else
  134.         *maxdist = nmaxdist;
  135.  
  136.     return TRUE;
  137. }
  138.  
  139. static void
  140. AddToHitList(hitlist, ray, mind, dist, obj)
  141. HitList *hitlist;
  142. Ray *ray;
  143. Float mind, dist;
  144. Geom *obj;
  145. {
  146.     HitNode *np;
  147.     Trans *list;
  148.         int i;
  149.  
  150.     np = &hitlist->data[i = hitlist->nodes++];
  151.  
  152.     if (i >= MAXMODELDEPTH)
  153.         RLerror(RL_ABORT, "HitList full. Increase libray/libobj/geom.h:MAXMODELDEPTH.\n");
  154.  
  155.     np->ray = *ray;
  156.     np->obj = obj;
  157.     np->mindist = mind;
  158.     np->dist = dist;
  159.     np->enter = 0;
  160.  
  161.     if (obj->trans) {
  162.         /*
  163.          * Compute total transformation, forward and inverse,
  164.          * for this object, and store in hitlist for use later.
  165.          */
  166.         TransCopy(obj->trans, &np->trans);
  167.         for (list = obj->trans->next; list; list = list->next)
  168.             TransCompose(&np->trans, list, &np->trans);
  169.         np->dotrans = TRUE;
  170.     } else
  171.         np->dotrans = FALSE;
  172. }
  173.  
  174. /*
  175.  * Return intersection statistics.
  176.  * Currently, this is limited to the # of bounding volume test performed.
  177.  */
  178. void
  179. IntersectStats(bvtests)
  180. unsigned long *bvtests;
  181. {
  182.     *bvtests = BVTests;
  183. }
  184.