00001
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
00018
00019 static float SnapToZero(float t)
00020 {
00021 return (fabs(t)<TOLERANCE)?(float)(0.0):t;
00022 }
00023
00025
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
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
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
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
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
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
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
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
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
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
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 }