home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / rayshade.lzh / bounds.c < prev    next >
Text File  |  1990-05-08  |  6KB  |  265 lines

  1. /*
  2.  * bounds.c
  3.  *
  4.  * Copyright (C) 1989, Craig E. Kolb
  5.  *
  6.  * This software may be freely copied, modified, and redistributed,
  7.  * provided that this copyright notice is preserved on all copies.
  8.  *
  9.  * There is no warranty or other guarantee of fitness for this software,
  10.  * it is provided solely .  Bug reports or fixes may be sent
  11.  * to the author, who may or may not act on them as he desires.
  12.  *
  13.  * You may not include this software in a program or other software product
  14.  * without supplying the source, or without informing the end-user that the
  15.  * source is available for no extra charge.
  16.  *
  17.  * If you modify this software, you should include a notice giving the
  18.  * name of the person performing the modification, the date of modification,
  19.  * and the reason for such modification.
  20.  *
  21.  * $Id: bounds.c,v 3.0.1.1 90/04/04 19:03:47 craig Exp $
  22.  *
  23.  * $Log:    bounds.c,v $
  24.  * Revision 3.0.1.1  90/04/04  19:03:47  craig
  25.  * patch5: Substituded FAR_AWAY for HUGE in bounds initialization routines.
  26.  * 
  27.  * Revision 3.0  89/10/27  02:05:46  craig
  28.  * Baseline for first official release.
  29.  * 
  30.  */
  31. #include <stdio.h>
  32. #include <math.h>
  33. #include "constants.h"
  34. #include "typedefs.h"
  35. #include "funcdefs.h"
  36.  
  37. /*
  38.  * Ray-bounding box intersection test.
  39.  */
  40. double
  41. IntBounds(ray, bounds)
  42. Ray *ray;
  43. double bounds[2][3];
  44. {
  45.     double t, tmin, tmax, bmin, bmax;
  46.     double dir, pos;
  47.     extern unsigned long BVTests;
  48.  
  49.     BVTests++;
  50.     tmin = 0.;
  51.     tmax = FAR_AWAY;
  52.  
  53.     dir = ray->dir.x;
  54.     pos = ray->pos.x;
  55.  
  56.     if (dir < 0) {
  57.         bmin = bounds[HIGH][X];
  58.         bmax = bounds[LOW][X];
  59.     } else {
  60.         bmax = bounds[HIGH][X];
  61.         bmin = bounds[LOW][X];
  62.     }
  63.  
  64.     if (dir != 0.) {        /* check x-faces */
  65.         t = (bmax - pos) / dir;
  66.         if (t < 0.)
  67.             return 0.;
  68.         if (t <= tmax)
  69.             tmax = t;
  70.         t = (bmin - pos) / dir;
  71.         if (t >= 0.) {
  72.             if (t > tmax)
  73.                 return 0.;
  74.             tmin = t;
  75.         }
  76.     } else if (pos < bmin || pos > bmax)
  77.         return 0.;
  78.  
  79.     dir = ray->dir.y;
  80.     pos = ray->pos.y;
  81.  
  82.     if (dir < 0) {
  83.         bmin = bounds[HIGH][Y];
  84.         bmax = bounds[LOW][Y];
  85.     } else {
  86.         bmax = bounds[HIGH][Y];
  87.         bmin = bounds[LOW][Y];
  88.     }
  89.  
  90.     if (dir != 0.) {        /* check y-faces */
  91.         t = (bmax - pos) / dir;
  92.         if (t < 0.)
  93.             return 0.;
  94.         if (t <= tmax) {
  95.             if (t < tmin)
  96.                 return 0.;
  97.             tmax = t;
  98.         }
  99.         t = (bmin - pos) / dir;
  100.         if (t >= tmin) {
  101.             if (t > tmax)
  102.                 return 0.;
  103.             tmin = t;
  104.         }
  105.     } else if (pos < bmin || pos > bmax)
  106.         return 0.;
  107.  
  108.     dir = ray->dir.z;
  109.     pos = ray->pos.z;
  110.  
  111.     if (dir < 0) {
  112.         bmin = bounds[HIGH][Z];
  113.         bmax = bounds[LOW][Z];
  114.     } else {
  115.         bmax = bounds[HIGH][Z];
  116.         bmin = bounds[LOW][Z];
  117.     }
  118.  
  119.     if (dir != 0.) {        /* check z-faces */
  120.         t = (bmax - pos) / dir;
  121.         if (t < 0.)
  122.             return 0.;
  123.         if (t <= tmax) {
  124.             if (t < tmin)
  125.                 return 0.;
  126.             tmax = t;
  127.         }
  128.         t = (bmin - pos) / dir;
  129.         if (t >= tmin) {
  130.             if (t > tmax)
  131.                 return 0.;
  132.             tmin = t;
  133.         }
  134.     } else if (pos < bmin || pos > bmax)
  135.         return 0.;
  136.  
  137.     return tmin;
  138. }
  139.  
  140. /*
  141.  * Transform an object's bounding box by the given transformation
  142.  * matrix.
  143.  */
  144. transform_bounds(trans, objbounds)
  145. TransInfo *trans;
  146. double objbounds[2][3];
  147. {
  148.     Vector v, tmp;
  149.     double bounds[2][3];
  150.     int x, y, z;
  151.  
  152.     init_bounds(bounds);
  153.  
  154.     /*
  155.      * Find bounding box of transformed corners of bounding box.
  156.      */
  157.     for (x = 0 ; x < 2; x++) {
  158.         v.x = objbounds[x][X];
  159.         for (y = 0; y < 2; y++) {
  160.             v.y = objbounds[y][Y];
  161.             for (z = 0; z < 2; z++) {
  162.                 v.z = objbounds[z][Z];
  163.                 tmp = v;
  164.                 transform_point(&tmp, trans);
  165.                 if (tmp.x < bounds[LOW][X])
  166.                     bounds[LOW][X] = tmp.x;
  167.                 if (tmp.x > bounds[HIGH][X])
  168.                     bounds[HIGH][X] = tmp.x;
  169.                 if (tmp.y < bounds[LOW][Y])
  170.                     bounds[LOW][Y] = tmp.y;
  171.                 if (tmp.y > bounds[HIGH][Y])
  172.                     bounds[HIGH][Y] = tmp.y;
  173.                 if (tmp.z < bounds[LOW][Z])
  174.                     bounds[LOW][Z] = tmp.z;
  175.                 if (tmp.z > bounds[HIGH][Z])
  176.                     bounds[HIGH][Z] = tmp.z;
  177.             }
  178.         }
  179.     }
  180.  
  181.     for (x = 0; x < 3; x++) {
  182.         objbounds[LOW][x] = bounds[LOW][x];
  183.         objbounds[HIGH][x] = bounds[HIGH][x];
  184.     }
  185. }
  186.  
  187. init_bounds(bounds)
  188. double bounds[2][3];
  189. {
  190.     bounds[LOW][X] = bounds[LOW][Y] = bounds[LOW][Z] = FAR_AWAY;
  191.     bounds[HIGH][X] = bounds[HIGH][Y] = bounds[HIGH][Z] = -FAR_AWAY;
  192. }
  193.  
  194. /*
  195.  * Walk through a linked-list of objects.  If the object is unbounded,
  196.  * unlink it it from the list and add it to the 'unbounded' list.
  197.  * If the object is bounded, enlarge the given bounding box if
  198.  * necessary.  Return pointer to unbounded list.
  199.  */
  200. ObjList *
  201. find_bounds(list, bounds)
  202. ObjList **list;
  203. double bounds[2][3];
  204. {
  205.     ObjList *ltmp, *prev, *oltmp;
  206.     ObjList *unbounded;
  207.     Object *otmp;
  208.  
  209.     init_bounds(bounds);
  210.     prev = unbounded = (ObjList *)0;
  211.  
  212.     for (ltmp = *list; ltmp; ltmp = ltmp->next) {
  213.         otmp = ltmp->data;
  214.         if (otmp->bounds[LOW][X] > otmp->bounds[HIGH][X]) {
  215.             /*
  216.              * Object is unbounded -- unlink it...
  217.              */
  218.             if (prev)
  219.                 prev->next = ltmp->next;
  220.             else
  221.                 *list = ltmp->next;
  222.             /*
  223.              * And add it to unbounded object list.
  224.              */
  225.             oltmp = (ObjList *)Malloc(sizeof(ObjList));
  226.             oltmp->data = otmp;
  227.             oltmp->next = unbounded;
  228.             unbounded = oltmp;
  229.         } else {
  230.             /*
  231.              * Object is bounded.
  232.              */
  233.             enlarge_bounds(bounds, otmp->bounds);
  234.             prev = ltmp;
  235.         }
  236.     }
  237.     return unbounded;
  238. }
  239.  
  240. #define SetIfLess(a, b)        (a = (a) < (b) ? (a) : (b))
  241. #define SetIfGreater(a, b)    (a = (a) > (b) ? (a) : (b))
  242.  
  243. /*
  244.  * Find bounding box of the union of two bounding boxes.
  245.  */
  246. enlarge_bounds(old, new)
  247. double old[2][3], new[2][3];
  248. {
  249.     SetIfLess(old[LOW][X], new[LOW][X]);
  250.     SetIfLess(old[LOW][Y], new[LOW][Y]);
  251.     SetIfLess(old[LOW][Z], new[LOW][Z]);
  252.     SetIfGreater(old[HIGH][X], new[HIGH][X]);
  253.     SetIfGreater(old[HIGH][Y], new[HIGH][Y]);
  254.     SetIfGreater(old[HIGH][Z], new[HIGH][Z]);
  255. }
  256.  
  257. print_bounds(box)
  258. double box[2][3];
  259. {
  260.     extern FILE *fstats;
  261.     fprintf(fstats,"\tX: %f to %f\n",box[LOW][X], box[HIGH][X]);
  262.     fprintf(fstats,"\tY: %f to %f\n",box[LOW][Y], box[HIGH][Y]);
  263.     fprintf(fstats,"\tZ: %f to %f\n",box[LOW][Z], box[HIGH][Z]);
  264. }
  265.