home *** CD-ROM | disk | FTP | other *** search
- /*
- Functions dealing with the voxels.
- Voxels are spacially adjacent, and together form the total
- bounding volume of the scene.
- Important of the functions is create_vlist.
- Creates a list of voxels pierced by the ray along its path.
- The list is ordered with piercing order as the ordering.
- The routine has been developed in two phases.
- Phase I : A brute force algorithm (but correct) was developed.
- -------------- 10 April 1991.
- Phase II : A 3d DDA being tested and subsequently abanodned.
- -------------- 16 April 1991.
- Phase III : A 3d DDA Adapted from RayShade of Yale Univ.
- -------------- 24 April 1991.
- As the codes for create_vlist and create_svlist are
- the adapted versions of the 3d-dda code used in Rayshade
- I am obliged to put the following copyright message.
-
- * Copyright (C) 1989, 1991, Craig E. Kolb
- * All rights reserved.
- *
- * This software may be freely copied, modified, and
- * redistributed
- * provided that this copyright notice is preserved on
- * all copies.
- *
- * You may not distribute this software, in whole or in
- * part, as part of
- * any commercial product without the express consent of
- * the original authours i.e. Craig E. Kolb.
-
- NOTE
- ----
- The bruteforce method and the working 3dDDA method give slightly
- different output for the cases where the ray pieces exactly a voxel
- corner or edge without actually entering the voxel. So they donot
- create any problem.
- ------
- sumant
- */
- #include <stdio.h>
- #include <math.h>
- #include <malloc.h>
-
- #include "GraphicsGems.h"
- #include "data_structure.h"
- #include "vox.h"
- #include "raddecl.h"
-
- Vlist *create_vlist(ray_start,ray_direction,tmin,tmax)
- /*
- Creates the list of voxels along the ray using 3dDDA.
-
- IMPORTANT
- --------
- 'create_svlist' is a duplicate of this routine with slight
- modification. So any change to this routine must be propagated to
- 'create_svlist'.
- --------
- sumant 24-April-91
- */
- Point3 *ray_start;
- Vector3 *ray_direction;
- double tmin,tmax;
- {
- Vlist *vlist=NULL;
- int x,stepX,outX;
- double tMaxX,tDeltaX;
- int y,stepY,outY;
- double tMaxY,tDeltaY;
- int z,stepZ,outZ;
- double tMaxZ,tDeltaZ;
-
- double t1;
-
- Point3 ray_entry,ray_exit;
-
- point_on_line(*ray_start,*ray_direction,tmin,ray_entry);
- point_on_line(*ray_start,*ray_direction,tmax,ray_exit);
-
- x=x2voxel(volume_grid,ray_entry.x); if (x == volume_grid.x_subdivision) x--;
- if (ray_direction->x < 0.){
- tMaxX = tmin + (voxel2x(volume_grid,x)-ray_entry.x)/ray_direction->x;
- tDeltaX = volume_grid.voxel_size.x/(-ray_direction->x);
- stepX = outX = -1;
- }
- else if (ray_direction->x > 0.){
- tMaxX = tmin + (voxel2x(volume_grid,x+1)-ray_entry.x)/ray_direction->x;
- tDeltaX = volume_grid.voxel_size.x/ray_direction->x;
- stepX = 1;
- outX = volume_grid.x_subdivision;
- }
- else{
- tMaxX=LARGE;
- tDeltaX = 0.;
- }
-
- y=y2voxel(volume_grid,ray_entry.y); if (y == volume_grid.y_subdivision) y--;
- if (ray_direction->y < 0.){
- tMaxY = tmin + (voxel2y(volume_grid,y)-ray_entry.y)/ray_direction->y;
- tDeltaY = volume_grid.voxel_size.y/(-ray_direction->y);
- stepY = outY = -1;
- }
- else if (ray_direction->y > 0.){
- tMaxY = tmin + (voxel2y(volume_grid,y+1)-ray_entry.y)/ray_direction->y;
- tDeltaY = volume_grid.voxel_size.y/ray_direction->y;
- stepY = 1;
- outY = volume_grid.y_subdivision;
- }
- else{
- tMaxY=LARGE;
- tDeltaY = 0.;
- }
-
- z=z2voxel(volume_grid,ray_entry.z); if (z == volume_grid.z_subdivision) z--;
- if (ray_direction->z < 0.){
- tMaxZ = tmin + (voxel2z(volume_grid,z)-ray_entry.z)/ray_direction->z;
- tDeltaZ = volume_grid.voxel_size.z/(-ray_direction->z);
- stepZ = outZ = -1;
- }
- else if (ray_direction->z > 0.){
- tMaxZ = tmin + (voxel2z(volume_grid,z+1)-ray_entry.z)/ray_direction->z;
- tDeltaZ = volume_grid.voxel_size.z/ray_direction->z;
- stepZ = 1;
- outZ = volume_grid.z_subdivision;
- }
- else{
- tMaxZ=LARGE;
- tDeltaZ = 0.;
- }
- t1 = tmin;
- while(1){
- int index=voxel_index(volume_grid,x,y,z);
- /*
- Voxel *vox=volume_grid.voxels+index;
- HitBoundingBox(&(vox->extent.min),&(vox->extent.max),
- ray_start,ray_direction,&t1,&t2);
- add_to_list(&vlist,index,t1,t2);
- */
-
- if ((tMaxX < tMaxY) && (tMaxX < tMaxZ)) {
- add_to_list(&vlist,index,t1,tMaxX); t1 = tMaxX;
- x += stepX;
- if ((tmax < tMaxX) || (x == outX)) break;
- tMaxX += tDeltaX;
- }else if (tMaxZ < tMaxY) {
- add_to_list(&vlist,index,t1,tMaxZ); t1 = tMaxZ;
- z += stepZ;
- if ((tmax < tMaxZ) || (z == outZ))
- break;
- tMaxZ += tDeltaZ;
- } else {
- add_to_list(&vlist,index,t1,tMaxY); t1 = tMaxY;
- y += stepY;
- if ((tmax < tMaxY) || (y == outY))
- break;
- tMaxY += tDeltaY;
- }
- }
- return(vlist);
- }
-
- int add_to_list(vlist,voxnum,t1,t2)
- Vlist **vlist;
- int voxnum;
- double t1,t2;
- {
- Vlist *newvox;
- static Vlist *p;
- newvox=(Vlist *)malloc (sizeof(Vlist));
- if (newvox==NULL) error("In Newbox");
- newvox->voxnum=voxnum;
- newvox->t_near=t1;
- newvox->t_far=t2;
- newvox->next=NULL;
-
- if (*vlist==NULL) *vlist = p = newvox;
- else { p->next = newvox; p = newvox; }
- }
-
- int purge_vlist(vlist)
- Vlist *vlist;
- {
- while(vlist != NULL){
- Vlist *tlist=vlist;
- vlist=vlist->next;
- free((char *)tlist);
- }
- }