home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / Light / pbvol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-21  |  8.7 KB  |  264 lines

  1. /**********************************************************************/
  2. /* pbvol.c                                                            */
  3. /*                                                                    */
  4. /* Bounding volume creation and manipulation routines                 */
  5. /* (See also hbvol.c for hierarchical bounding volume routines        */
  6. /* (See also raysp.c for culling bounding volume routines             */
  7. /*                                                                    */
  8. /* Copyright (C) 1992, Bernard Kwok                                   */
  9. /* All rights reserved.                                               */
  10. /* Revision 1.0                                                       */
  11. /* May, 1992                                                          */
  12. /**********************************************************************/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include "misc.h"
  17. #include "geo.h"
  18.  
  19. #define NUMDIM 3
  20. #define SetIfLess(a, b, c)    ((c) = ((a) < (b) ? (a) : (b)))
  21. #define SetIfGreater(a, b, c)    ((c) = ((a) > (b) ? (a) : (b)))
  22.  
  23. void BoundsPrint();
  24.  
  25. /**********************************************************************/
  26. /* Initialize box to invalid box */
  27. /**********************************************************************/
  28. void BoxInit(box)
  29.      BoundingBoxType *box;
  30. {
  31.   box->min.x = VERY_LARGE;
  32.   box->min.y = VERY_LARGE;
  33.   box->min.z = VERY_LARGE;
  34.   box->max.x = -VERY_LARGE;
  35.   box->max.y = -VERY_LARGE;
  36.   box->max.z = -VERY_LARGE;
  37. }
  38.  
  39. /**********************************************************************/
  40. /* Update the size of a box by a given point */
  41. /**********************************************************************/
  42. void Update_BoxSize(pt,box)
  43.      Vector pt;
  44.      BoundingBoxType *box;
  45. {
  46.   if (pt.x > box->max.x)  box->max.x = pt.x;
  47.   if (pt.y > box->max.y)  box->max.y = pt.y;
  48.   if (pt.z > box->max.z)  box->max.z = pt.z;
  49.  
  50.   if (pt.x < box->min.x)  box->min.x = pt.x;
  51.   if (pt.y < box->min.y)  box->min.y = pt.y;
  52.   if (pt.z < box->min.z)  box->min.z = pt.z;
  53. }
  54.  
  55. /**********************************************************************/
  56. /* Form bounding box for a cone - unit cube. Sits on z = 0 plane      */
  57. /**********************************************************************/
  58. BoundingBoxType BoxCone()
  59. {
  60.   BoundingBoxType box;
  61.   
  62.   box.min.x= -1.0;
  63.   box.min.y= -1.0;
  64.   box.min.z= 0.0;
  65.   box.max.x= 1.0;
  66.   box.max.y= 1.0;
  67.   box.max.z= 2.0;
  68.   return(box);
  69. }
  70.  
  71. /**********************************************************************/
  72. /* Form bounding box for a cube - unit cube */
  73. /**********************************************************************/
  74. BoundingBoxType BoxCube()
  75. {
  76.   BoundingBoxType box;
  77.   
  78.   box.min.x= -1.;
  79.   box.min.y= -1.;
  80.   box.min.z= -1.;
  81.   box.max.x= 1.;
  82.   box.max.y= 1.;
  83.   box.max.z= 1.;
  84.   return(box);
  85. }
  86.  
  87. /**********************************************************************/
  88. /* Form bounding box for cylinder - unit box */
  89. /**********************************************************************/
  90. BoundingBoxType BoxCylinder()
  91. {
  92.   BoundingBoxType box;
  93.   
  94.   box.min.x= -1.;
  95.   box.min.y= -1.;
  96.   box.min.z= -1.;
  97.   box.max.x= 1.;
  98.   box.max.y= 1.;
  99.   box.max.z= 1.;
  100.   return(box);
  101. }
  102.  
  103. /**********************************************************************/
  104. /* Form bounding box for sphere - unit box */
  105. /**********************************************************************/
  106. BoundingBoxType BoxSphere()
  107. {
  108.   BoundingBoxType box;
  109.   
  110.   box.min.x= -1.;
  111.   box.min.y= -1.;
  112.   box.min.z= -1.;
  113.   box.max.x= 1.;
  114.   box.max.y= 1.;
  115.   box.max.z= 1.;
  116.   return(box);
  117. }
  118.  
  119. /**********************************************************************/
  120. /* Find bounding box of the union of two bounding boxes.  */
  121. /**********************************************************************/
  122. void Bounds_Union(box1, box2, new)
  123.      BoundingBoxType box1, box2;
  124.      BoundingBoxType *new;
  125. {
  126.   SetIfLess(box1.min.x, box2.min.x, new->min.x);
  127.   SetIfLess(box1.min.y, box2.min.y, new->min.y);
  128.   SetIfLess(box1.min.z, box2.min.z, new->min.z);
  129.   SetIfGreater(box1.max.x, box2.max.x, new->max.x);
  130.   SetIfGreater(box1.max.y, box2.max.y, new->max.y);
  131.   SetIfGreater(box1.max.z, box2.max.z, new->max.z);
  132. }
  133.  
  134. /**********************************************************************/
  135. /* Bounds box 1 same as box 2 */
  136. /**********************************************************************/
  137. int Bounds_Same(box1, box2)
  138.      BoundingBoxType *box1, *box2;
  139. {
  140.   if (box2->min.x != box1->min.x) return 0;
  141.   if (box2->min.y != box1->min.y) return 0;
  142.   if (box2->min.z != box1->min.z) return 0;
  143.   if (box2->max.x != box1->max.x) return 0;
  144.   if (box2->max.y != box1->max.y) return 0;
  145.   if (box2->max.z != box1->max.z) return 0;
  146.   return 1;
  147. }
  148.  
  149. #define OUTSIDE 0
  150. #define OVERLAP 1
  151. #define INSIDE 2
  152. #define CONTAINS 3
  153. /**********************************************************************/
  154. /* Test if 2 bounding boxes intersect, inside, or outside each other */
  155. /**********************************************************************/
  156. int Bounds_Compare(box1,box2)
  157.      BoundingBoxType *box1, *box2;
  158. {
  159.   int xoverlap, yoverlap, zoverlap;
  160.   BoundingBoxType box12;
  161.  
  162.   Bounds_Union(*box1, *box2, &box12);
  163.   if (Bounds_Same(box1, &box12)) {   /* Test box contains other box */
  164.     /* BoundsPrint(*box1, stdout, "box1 contains");
  165.        BoundsPrint(*box2, stdout, "box2."); */
  166.     return CONTAINS;
  167.   }
  168.   if (Bounds_Same(box2, &box12)) {    /* Test box is inside other box */
  169.     /* BoundsPrint(*box1, stdout, "box1 inside");
  170.        BoundsPrint(*box2, stdout, "box2."); */
  171.     return INSIDE; 
  172.   }
  173.   
  174.   xoverlap = ((box1->max.x > box2->min.x && box1->max.x < box2->max.x) ||
  175.           (box1->min.x > box2->min.x && box1->min.x < box2->max.x));
  176.   yoverlap = ((box1->max.y > box2->min.y && box1->max.y < box2->max.y) ||
  177.           (box1->min.y > box2->min.y && box1->min.y < box2->max.y));
  178.   zoverlap = ((box1->max.z > box2->min.z && box1->max.z < box2->max.z) ||
  179.           (box1->min.z > box2->min.z && box1->min.z < box2->max.z));
  180.   if (xoverlap && yoverlap && zoverlap) {
  181.     /* BoundsPrint(*box1, stdout, "box1 overlaps");
  182.        BoundsPrint(*box2, stdout, "box2."); */
  183.     return OVERLAP;
  184.   }
  185.   return OUTSIDE;
  186. }
  187.  
  188. /**********************************************************************/
  189. /* Copy bounds from box 1 to box 2                                    */
  190. /**********************************************************************/
  191. void Bounds_Copy(box1, box2)
  192.      BoundingBoxType box1, *box2;
  193. {
  194.   box2->min.x = box1.min.x;
  195.   box2->min.y = box1.min.y;
  196.   box2->min.z = box1.min.z;
  197.   box2->max.x = box1.max.x;
  198.   box2->max.y = box1.max.y;
  199.   box2->max.z = box1.max.z;
  200. }
  201.  
  202. /**********************************************************************/
  203. /* Transforming Axis-Aligned Bounding Boxes by James Arvo             */
  204. /* from "Graphics Gems", Academic Press, 1990                         */
  205. /*                                                                    */
  206. /* Transform axis-aligned bounding box via transformation, and        */
  207. /* computing the axis-aligned bounding box enclosing the result       */   
  208. /* (translation in x,y,z is in M[3][0 to 2]                           */
  209. /**********************************************************************/
  210. void Bounds_Transform( M, A, B )
  211.      Matrix  M;              /* Transform matrix.             */
  212.      BoundingBoxType A;      /* The original bounding box.    */
  213.      BoundingBoxType *B;      /* The transformed bounding box. */
  214. {
  215.   float  a, b;
  216.   float  Amin[3], Amax[3];
  217.   float  Bmin[3], Bmax[3];
  218.   int    i, j;
  219.  
  220.   /* Copy box A into a min array and a max array for easy reference.*/
  221.   Amin[0] = A.min.x;  Amax[0] = A.max.x;
  222.   Amin[1] = A.min.y;  Amax[1] = A.max.y;
  223.   Amin[2] = A.min.z;  Amax[2] = A.max.z;
  224.  
  225.   /* Take care of translation by beginning at T. */
  226.   Bmin[0] = Bmax[0] = M[3][0];
  227.   Bmin[1] = Bmax[1] = M[3][1];
  228.   Bmin[2] = Bmax[2] = M[3][2];
  229.  
  230.   /* Now find the extreme points by considering the product of the */
  231.   /* min and max with each component of M.  */
  232.   for( i=0; i<3; i++ ) {
  233.     for( j=0; j<3; j++ ) {
  234.       a = M[i][j] * Amin[j];
  235.       b = M[i][j] * Amax[j];
  236.       if( a < b ) {
  237.     Bmin[i] += a; 
  238.     Bmax[i] += b;
  239.       } else { 
  240.     Bmin[i] += b; 
  241.     Bmax[i] += a;
  242.       }
  243.     }
  244.   }
  245.   /* Copy the result into the new box. */
  246.   B->min.x = Bmin[0];  B->max.x = Bmax[0];
  247.   B->min.y = Bmin[1];  B->max.y = Bmax[1];
  248.   B->min.z = Bmin[2];  B->max.z = Bmax[2];
  249. }
  250.  
  251. /**********************************************************************/
  252. /* Print a bounding box                                               */
  253. /**********************************************************************/
  254. void BoundsPrint(box, fp, label)
  255.      BoundingBoxType box;
  256.      FILE *fp;
  257.      char *label;
  258. {
  259.   fprintf(fp,"\tBounding box: %s : ", label);
  260.   fprintf(fp,"X: %g to %g; ", box.min.x, box.max.x);
  261.   fprintf(fp,"Y: %g to %g; ", box.min.y, box.max.y);
  262.   fprintf(fp,"Z: %g to %g\n", box.min.z, box.max.z);
  263. }
  264.