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

  1. /*
  2.  * voxels.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: voxels.c,v 3.0.1.3 90/04/04 19:05:23 craig Exp $
  22.  *
  23.  * $Log:    voxels.c,v $
  24.  * Revision 3.0.1.3  90/04/04  19:05:23  craig
  25.  * patch5: Changes to reflect that free() may be destructive.
  26.  * 
  27.  * Revision 3.0.1.2  90/02/12  13:19:50  craig
  28.  * patch4: Added reporting of total number of primitives.
  29.  * 
  30.  * Revision 3.0.1.1  89/12/06  16:33:29  craig
  31.  * patch2: Added calls to new error/warning routines.
  32.  * 
  33.  * Revision 3.0  89/10/27  02:06:09  craig
  34.  * Baseline for first official release.
  35.  * 
  36.  */
  37. #include <math.h>
  38. #include <stdio.h>
  39. #include "constants.h"
  40. #include "typedefs.h"
  41. #include "funcdefs.h"
  42.  
  43. /*
  44.  * Process World object, converting to a Grid or List.
  45.  */
  46. SetupWorld()
  47. {
  48.     extern FILE *fstats;
  49.     extern Object *World;
  50.     extern int WorldXSize, WorldYSize, WorldZSize, Verbose;
  51.  
  52.     if (World->type == GRID)
  53.         list2grid(World, WorldXSize, WorldYSize, WorldZSize);
  54.     else
  55.         make_list(World);
  56.  
  57.     if (Verbose) {
  58.         fprintf(fstats,"World extent:\n");
  59.         print_bounds(World->bounds);
  60.         fprintf(fstats,"\t%ld primitive%c\n",World->prims,
  61.                 World->prims == 1 ? ' ' : 's');
  62.     }
  63. }
  64.  
  65. /*
  66.  * Add object to grid's unbounded list.
  67.  */
  68. make_unbounded(obj, grid)
  69. Object *obj;
  70. Grid *grid;
  71. {
  72.     ObjList *tmp;
  73.  
  74.     tmp = (ObjList *)Malloc(sizeof(ObjList));
  75.  
  76.     tmp->data = obj;
  77.     tmp->next = grid->unbounded;
  78.     grid->unbounded = tmp;
  79. }
  80.  
  81. /*
  82.  * Place an object in a grid.
  83.  */
  84. engrid(obj, grid)
  85. Object *obj;
  86. Grid *grid;
  87. {
  88.     int x, y, z, low[3], high[3];
  89.     ObjList *ltmp;
  90.  
  91.     /*
  92.      * This routine should *never* be passed an unbounded object, but...
  93.      */
  94.     if (pos2grid(grid, obj->bounds[LOW], low) == 0 ||
  95.         pos2grid(grid, obj->bounds[HIGH], high) == 0 ||
  96.         obj->bounds[LOW][X] > obj->bounds[HIGH][X]) {
  97.         /*
  98.          * Object is partially on wholly outside of
  99.          * grid -- this should never happen, but just
  100.          * in case...
  101.          */
  102.         make_unbounded(obj, grid);
  103.         RSwarning("Strange, engrid got an unbounded object...\n");
  104.         return;
  105.         }
  106.  
  107.     /*
  108.      * For each voxel that intersects the object's bounding
  109.      * box, add pointer to this object to voxel's linked list.
  110.       */
  111.     for (x = low[X]; x <= high[X]; x++) {
  112.         for (y = low[Y]; y <= high[Y]; y++) {
  113.             for (z = low[Z]; z <= high[Z]; z++) {
  114.                 ltmp = (ObjList *)share_malloc(sizeof(ObjList));
  115.                 ltmp->data = obj;
  116.                 ltmp->next = grid->cells[x][y][z];
  117.                 grid->cells[x][y][z] = ltmp;
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. /*
  124.  * Convert 3D point to index into grid's voxels.
  125.  */
  126. pos2grid(grid, pos, index)
  127. Grid *grid;
  128. double pos[3];
  129. int index[3];
  130. {
  131.     index[X] = (int)(x2voxel(grid, pos[0]));
  132.     index[Y] = (int)(y2voxel(grid, pos[1]));
  133.     index[Z] = (int)(z2voxel(grid, pos[2]));
  134.  
  135.     if (index[X] == grid->xsize)
  136.         index[X] = grid->xsize -1;
  137.     if (index[Y] == grid->ysize)
  138.         index[Y] = grid->ysize -1;
  139.     if (index[Z] == grid->zsize)
  140.         index[Z] = grid->zsize -1;
  141.  
  142.     if (index[X] < 0 || index[X] >= grid->xsize ||
  143.         index[Y] < 0 || index[Y] >= grid->ysize ||
  144.         index[Z] < 0 || index[Z] >= grid->zsize)
  145.         return 0;
  146.     return 1;
  147. }
  148.  
  149. /*
  150.  * Convert a linked list of objects to a Grid.
  151.  */
  152. list2grid(obj, xsize, ysize, zsize)
  153. Object *obj;
  154. int xsize, ysize, zsize;
  155. {
  156.     Grid *grid;
  157.     Object *otmp;
  158.     ObjList *ltmp, *nltmp;
  159.     int x, y, i;
  160.     extern ObjList *find_bounds();
  161.  
  162.     grid = (Grid *)Malloc(sizeof(Grid));
  163.  
  164.     /*
  165.      * Find bounding box of bounded objects and get list of
  166.      * unbounded objects.
  167.      */
  168.     grid->unbounded = find_bounds((ObjList **)&obj->data, obj->bounds);
  169.  
  170.     grid->xsize = xsize; grid->ysize = ysize; grid->zsize = zsize;
  171.  
  172.     for (i = 0; i < 3; i++) {
  173.         obj->bounds[LOW][i] -= 2. * EPSILON;
  174.         obj->bounds[HIGH][i] += 2. * EPSILON;
  175.         grid->bounds[LOW][i] = obj->bounds[LOW][i];
  176.         grid->bounds[HIGH][i] = obj->bounds[HIGH][i];
  177.     }
  178.     grid->voxsize[X] = (grid->bounds[HIGH][X]-grid->bounds[LOW][X])/xsize;
  179.     grid->voxsize[Y] = (grid->bounds[HIGH][Y]-grid->bounds[LOW][Y])/ysize;
  180.     grid->voxsize[Z] = (grid->bounds[HIGH][Z]-grid->bounds[LOW][Z])/zsize;
  181.  
  182.     /*
  183.      * Allocate voxels.
  184.      */
  185.     grid->cells = (ObjList ****)share_malloc(xsize * sizeof(ObjList ***));
  186.     for (x = 0; x < xsize; x++) {
  187.         grid->cells[x] = (ObjList ***)share_malloc(ysize*sizeof(ObjList **));
  188.         for (y = 0; y < ysize; y++)
  189.             grid->cells[x][y] = (ObjList **)share_calloc((unsigned)zsize,
  190.                             sizeof(ObjList *));
  191.     }
  192.  
  193.     /*
  194.      * obj->data now holds a linked list of bounded objects.
  195.      */
  196.     for(ltmp = (ObjList *)obj->data; ltmp != (ObjList *)0; ltmp = nltmp) {
  197.         otmp = ltmp->data;
  198.         engrid(otmp, grid);
  199.         nltmp = ltmp->next;
  200.         free((char *)ltmp);
  201.     }
  202.     obj->type = GRID;
  203.     obj->data = (char *)grid;
  204. }
  205. #ifdef MULTIMAX
  206.  
  207. char *
  208. share_calloc(num, siz)
  209. int num;
  210. unsigned int siz;
  211. {
  212.     char *res;
  213.  
  214.     res = share_malloc(num*siz);
  215.     bzero(res, num*siz);
  216.     return res;
  217. }
  218. #endif
  219.