Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Raycast/DatGrid.cpp

Go to the documentation of this file.
00001 // DatGrid.cpp: Implementierung der Klasse DatGrid.
00002 //
00004 
00005 #include <iostream>
00006 #include <math.h>
00007 
00008 #include "Raycast.h"
00009 #include "DatGrid.h"
00010 #include "vuSampleRay.h"
00011 
00012 #define RET_OK   0
00013 #define RET_ERR -1
00014 
00015 #define TOLERANCE       0.001
00016 
00017 // Check if value is within TOLERANCE of zero.  If it
00018 // is then make value equal to zero.
00019 static float SnapToZero(float t)
00020 {
00021   return (fabs(t)<TOLERANCE)?(float)(0.0):t;
00022 }
00023 
00025 // Konstruktion/Destruktion
00027 
00028 DatGrid::DatGrid()
00029 {
00030   maxX=maxY=maxZ=layXY = 0;
00031   vol = NULL;
00032 }
00033 
00034 DatGrid::~DatGrid()
00035 {
00036   free_vol_mem();
00037 }
00038 
00039 int DatGrid::free_vol_mem()
00040 {
00041   if(vol)
00042     {
00043       delete [] vol;
00044       vol = NULL;
00045     }
00046   
00047   return RET_OK;
00048 }
00049 
00050 // allocates memory according to axis extents
00051 int DatGrid::get_vol_mem()
00052 {
00053   free_vol_mem();
00054   vol = new DatPnt[maxX*maxY*maxZ];
00055   if(!vol) return RET_ERR;
00056   else return RET_OK;
00057 }
00058 
00059 // initialises the grid
00060 int DatGrid::init(int maxx, int maxy, int maxz)
00061 {
00062   maxX = maxx; maxY = maxy; maxZ = maxz;
00063   layXY = maxX*maxY;
00064   size = layXY*maxZ;
00065   m_C0 = vuVector(0.0);
00066   m_C1 = vuVector((float)maxx-1,(float)maxy-1,(float)maxz-1);
00067   return get_vol_mem();
00068 }
00069 
00070 float DatGrid::clipRay(vuSampleRay &r, bool bidirectional, int& m_Side) const
00071 {
00072     vuVector pos;
00073     vuVector dir;
00074     float X;
00075     float Y;
00076     float Z;
00077     float tMin=0;
00078     float t;
00079 
00080     m_Side = -1;
00081 
00082     pos = r.m_Position;
00083     dir = r.m_Direction;
00084 
00085     // m_Side == 6 if rendering within the volume
00086     if( bidirectional &&
00087         (pos[0] > m_C0[0]) && (pos[0] < m_C1[0]) &&
00088         (pos[1] > m_C0[1]) && (pos[1] < m_C1[1]) &&
00089         (pos[2] > m_C0[2]) && (pos[2] < m_C1[2]) )
00090       {
00091         m_Side = 6;
00092         return t = 0;
00093       }
00094 
00095     // Test the X0 wall
00096     t = SnapToZero((m_C0[0] - pos[0]) / dir[0]);
00097     if (t > 0)
00098     {
00099         Y = pos[1] + t * dir[1];
00100         Z = pos[2] + t * dir[2];
00101         if ((Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00102             (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00103                         (bidirectional || t>=0))
00104         {
00105             tMin = t;
00106             m_Side = 0;
00107         }
00108     }
00109 
00110     // Test the X1 wall
00111     t = SnapToZero((m_C1[0] - pos[0]) / dir[0]);
00112     if (t > 0)
00113     {
00114         Y = pos[1] + t * dir[1];
00115         Z = pos[2] + t * dir[2];
00116         if ((Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00117             (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00118                         (bidirectional || t>=0))
00119         {
00120             if ((m_Side==-1) || (t<tMin))
00121             {
00122                 tMin = t;
00123                 m_Side = 1;
00124             }
00125         }
00126     }
00127 
00128     // Test the Y0 wall
00129     t = SnapToZero((m_C0[1] - pos[1]) / dir[1]);
00130     if (t > 0)
00131     {
00132         X = pos[0] + t * dir[0];
00133         Z = pos[2] + t * dir[2];
00134         if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00135             (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00136                         (bidirectional || t>=0))
00137         {
00138             if ((m_Side==-1) || (t<tMin))
00139             {
00140                 tMin = t;
00141                 m_Side = 2;
00142             }
00143         }
00144     }
00145 
00146     // Test the Y1 walla
00147     t = SnapToZero((m_C1[1] - pos[1]) / dir[1]);
00148     if (t > 0)
00149     {
00150         X = pos[0] + t * dir[0];
00151         Z = pos[2] + t * dir[2];
00152         if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00153             (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00154                         (bidirectional || t>=0))
00155         {
00156             if ((m_Side==-1) || (t<tMin))
00157             {
00158                 tMin = t;
00159                 m_Side = 3;
00160             }
00161         }
00162     }
00163 
00164     // Test the Z0 wall
00165     t = SnapToZero((m_C0[2] - pos[2]) / dir[2]);
00166     if (t > 0)
00167     {
00168         X = pos[0] + t * dir[0];
00169         Y = pos[1] + t * dir[1];
00170         if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00171             (Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00172                         (bidirectional || t>=0))
00173         {
00174             if ((m_Side==-1) || (t<tMin))
00175             {
00176                 tMin = t;
00177                 m_Side = 4;
00178             }
00179         }
00180     }
00181 
00182     // Test the Z1 wall
00183     t = SnapToZero((m_C1[2] - pos[2]) / dir[2]);
00184     if (t > 0)
00185     {
00186         X = pos[0] + t * dir[0];
00187         Y = pos[1] + t * dir[1];
00188         if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00189             (Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00190                         (bidirectional || t>=0))
00191         {
00192             if ((m_Side==-1) || (t<tMin))
00193             {
00194                 tMin = t;
00195                 m_Side = 5;
00196             }
00197         }
00198     }
00199         return tMin; 
00200 }
00201 
00202 /*---------------------------------------------------------------------------*/
00203 bool DatGrid::copy_vol(byte* data, vu1112113 &r)
00204 {
00205   if (!data) return false;
00206   maxX = r.m_Dim1Size;
00207   maxY = r.m_Dim2Size;
00208   maxZ = r.m_Dim3Size;
00209   //f.eatwhite();
00210   init(maxX,maxY,maxZ);
00211   int c;
00212   for(c=0;c<size;c++)
00213     {
00214       vol[c].data = data[c];
00215     }
00216   
00217   return true;
00218 }
00219 
00220 /*---------------------------------------------------------------------------*/
00221 void DatGrid::shade(vu1112113 &r)
00222 {
00223   int c;
00224   for(c=0;c<size;c++)
00225     vol[c].shade(r);
00226 }
00227 
00228 /*---------------------------------------------------------------------------*/
00229 void DatGrid::calculate_gradients()
00230 {
00231     int i,j,k;
00232     int offset=0;
00233     for(k=0;k<maxZ;k++)
00234       for(j=0;j<maxY;j++)
00235         for(i=0;i<maxX;i++)
00236           {
00237             DatPnt *cc = vol + offset;
00238             float len = 0, nc;
00239             nc =
00240                 cc->norm[0]= (i          ? (int)vol[offset-1].data:0) -
00241                 ((i<maxX-1) ? (int)vol[offset+1].data:0);
00242             len = nc*nc;
00243             nc =
00244                 cc->norm[1]= (j          ? (int)vol[offset-maxX].data:0)
00245                 -((j<maxY-1) ? (int)vol[offset+maxX].data:0);
00246             len += nc*nc;
00247             nc = 
00248                 cc->norm[2]= (k          ? (int)vol[offset-layXY].data:0)
00249                 -((k<maxZ-1) ? (int)vol[offset+layXY].data:0);
00250             len += nc*nc;
00251             
00252             if(len>0.0) {
00253                 len = sqrt(len);
00254                 float flen = 255.0f*len;
00255                 if(flen > 255) cc->len = 255;
00256                 else cc->len = byte(flen);
00257                 cc->norm[0] /= len;
00258                 cc->norm[1] /= len;
00259                 cc->norm[2] /= len;
00260             } else cc->len = 0;
00261             
00262             offset++;
00263           }
00264 }

Generated on Wed Dec 15 21:20:28 2004 for vuVolume by  doxygen 1.3.9.1