home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2213 / bound.c next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  3.7 KB  |  236 lines

  1.  
  2. /*
  3.  * bound.c
  4.  * 
  5.  * This module contains the code for creating a bounding box hierarchy. Most of
  6.  * the code here has stolen from MTV's raytracer.
  7.  *
  8.  * Copyright (C) 1990, Kory Hamzeh.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <math.h>
  13.  
  14. #include "rt.h"
  15. #include "externs.h"
  16.  
  17. static int      axis;
  18.  
  19. /*
  20.  * Build_bounding_slabs()
  21.  * 
  22.  * This function attempts to use median cut to generate tighter bounding volumes
  23.  * than the old code...
  24.  */
  25.  
  26. Build_bounding_slabs()
  27. {
  28.     int             low = 0;
  29.     int             high, i;
  30.  
  31.     high = nobjects;
  32.     while (Sort_split(low, high) == 0)
  33.     {
  34.         low = high;
  35.         high = nobjects;
  36.     }
  37. }
  38.  
  39. /*
  40.  * Compslabs()
  41.  * 
  42.  * Compare the given slabs of the current axis.
  43.  */
  44.  
  45.  
  46. Compslabs(a, b)
  47. OBJECT        **a, **b;
  48. {
  49.     double          am, bm;
  50.  
  51.     switch (axis)
  52.     {
  53.     case 0:
  54.         am = (*a)->b_min.x + (*a)->b_max.x;
  55.         bm = (*b)->b_min.x + (*b)->b_max.x;
  56.         break;
  57.  
  58.     case 1:
  59.         am = (*a)->b_min.y + (*a)->b_max.y;
  60.         bm = (*b)->b_min.y + (*b)->b_max.y;
  61.         break;
  62.  
  63.     case 2:
  64.         am = (*a)->b_min.z + (*a)->b_max.z;
  65.         bm = (*b)->b_min.z + (*b)->b_max.z;
  66.         break;
  67.     }
  68.  
  69.     if (am < bm)
  70.         return (-1);
  71.     else if (am == bm)
  72.         return (0);
  73.     else
  74.         return (1);
  75. }
  76.  
  77. /*
  78.  * Find the most dominant axis for this group of objects.
  79.  */
  80.  
  81. Find_axis(first, last)
  82. int             first, last;
  83. {
  84.     OBJECT         *obj;
  85.     VECTOR          mins, maxs;
  86.     double          d, e;
  87.     int             i, which;
  88.  
  89.     d = -HUGE;
  90.  
  91.     mins.x = mins.y = mins.z = HUGE;
  92.     maxs.x = maxs.y = maxs.z = -HUGE;
  93.  
  94.     for (i = first; i < last; i++)
  95.     {
  96.         obj = objects[i];
  97.  
  98.         if (obj->b_min.x < mins.x)
  99.             mins.x = obj->b_min.x;
  100.         if (obj->b_min.y < mins.y)
  101.             mins.y = obj->b_min.y;
  102.         if (obj->b_min.z < mins.z)
  103.             mins.z = obj->b_min.z;
  104.  
  105.         if (obj->b_max.x > maxs.x)
  106.             maxs.x = obj->b_max.x;
  107.         if (obj->b_max.y > maxs.y)
  108.             maxs.y = obj->b_max.y;
  109.         if (obj->b_max.z > maxs.z)
  110.             maxs.z = obj->b_max.z;
  111.     }
  112.  
  113.     e = maxs.x - mins.x;
  114.  
  115.     if (e > d)
  116.     {
  117.         d = e;
  118.         which = 0;
  119.     }
  120.  
  121.     e = maxs.y - mins.y;
  122.  
  123.     if (e > d)
  124.     {
  125.         d = e;
  126.         which = 1;
  127.     }
  128.  
  129.     e = maxs.z - mins.z;
  130.  
  131.     if (e > d)
  132.     {
  133.         d = e;
  134.         which = 0;
  135.     }
  136.  
  137.     return (which);
  138. }
  139.  
  140.  
  141. Sort_split(first, last)
  142. int             first, last;
  143. {
  144.     OBJECT         *cp;
  145.     COMPOSITE      *cd;
  146.     int             size, i, j;
  147.     double          dmin, dmax;
  148.     int             m;
  149.  
  150.     axis = Find_axis(first, last);
  151.  
  152.     size = last - first;
  153.  
  154.     qsort((char *) (objects + first), size, sizeof(OBJECT *), Compslabs);
  155.  
  156.     if (size <= GROUP_SIZE)
  157.     {
  158.         /* build a box to contain them */
  159.  
  160.         cp = (OBJECT *) malloc(sizeof(OBJECT));
  161.         cp->type = T_COMPOSITE;
  162.         cd = (COMPOSITE *) malloc(sizeof(COMPOSITE));
  163.         cd->num = size;
  164.  
  165.         for (i = 0; i < size; i++)
  166.         {
  167.             cd->child[i] = objects[first + i];
  168.         }
  169.  
  170.         dmin = HUGE;
  171.         dmax = -HUGE;
  172.  
  173.         for (j = 0; j < size; j++)
  174.         {
  175.             if (cd->child[j]->b_min.x < dmin)
  176.                 dmin = cd->child[j]->b_min.x;
  177.             if (cd->child[j]->b_max.x > dmax)
  178.                 dmax = cd->child[j]->b_max.x;
  179.         }
  180.  
  181.         cp->b_min.x = dmin;
  182.         cp->b_max.x = dmax;
  183.  
  184.         dmin = HUGE;
  185.         dmax = -HUGE;
  186.  
  187.         for (j = 0; j < size; j++)
  188.         {
  189.             if (cd->child[j]->b_min.y < dmin)
  190.                 dmin = cd->child[j]->b_min.y;
  191.             if (cd->child[j]->b_max.y > dmax)
  192.                 dmax = cd->child[j]->b_max.y;
  193.         }
  194.  
  195.         cp->b_min.y = dmin;
  196.         cp->b_max.y = dmax;
  197.  
  198.         dmin = HUGE;
  199.         dmax = -HUGE;
  200.  
  201.         for (j = 0; j < size; j++)
  202.         {
  203.             if (cd->child[j]->b_min.z < dmin)
  204.                 dmin = cd->child[j]->b_min.z;
  205.             if (cd->child[j]->b_max.z > dmax)
  206.                 dmax = cd->child[j]->b_max.z;
  207.         }
  208.  
  209.         cp->b_min.z = dmin;
  210.         cp->b_max.z = dmax;
  211.  
  212.  
  213.         cp->obj = (void *) cd;
  214.         root = cp;
  215.  
  216.         if (nobjects < MAX_PRIMS)
  217.         {
  218.             objects[nobjects++] = cp;
  219.             return (1);
  220.         }
  221.         else
  222.         {
  223.             fprintf(stderr, "%s: too many primitives, max is %d\n",
  224.                 my_name, MAX_PRIMS);
  225.             exit(0);
  226.         }
  227.     }
  228.     else
  229.     {
  230.         m = (first + last) / 2;
  231.         Sort_split(first, m);
  232.         Sort_split(m, last);
  233.         return (0);
  234.     }
  235. }
  236.