00001
00002
00004
00005 #include "spectral.h"
00006 #include "DatGrid.h"
00007 #include "fstream.h"
00008 #include "iostream.h"
00009 #include "vuSampleRay.h"
00010 #include "Util.h"
00011 #include <math.h>
00012
00013 #define RET_OK 0
00014 #define RET_ERR -1
00015
00016 namespace ns_vu1112112 {
00017 using namespace ns_vu1112112;
00018
00019 extern float light[];
00020 extern float ambient[];
00021
00023
00025
00026 DatGrid::DatGrid()
00027 {
00028 maxX=maxY=maxZ=layXY = 0;
00029 vol = NULL;
00030 }
00031
00032 DatGrid::~DatGrid()
00033 {
00034 free_vol_mem();
00035 }
00036
00037 int DatGrid::free_vol_mem()
00038 {
00039 if(vol)
00040 {
00041 delete [] vol;
00042 vol = NULL;
00043 }
00044
00045 return RET_OK;
00046 }
00047
00048
00049 int DatGrid::get_vol_mem()
00050 {
00051 free_vol_mem();
00052 vol = new DatPnt[maxX*maxY*maxZ];
00053 if(!vol) return RET_ERR;
00054
00055 return RET_OK;
00056 }
00057
00058
00059 int DatGrid::init(int maxx, int maxy, int maxz)
00060 {
00061 maxX = maxx; maxY = maxy; maxZ = maxz;
00062 layXY = maxX*maxY;
00063 size = layXY*maxZ;
00064 m_C0 = vuVector(0.0);
00065 m_C1 = vuVector((float)maxx-1,(float)maxy-1,(float)maxz-1);
00066 return get_vol_mem();
00067 }
00068
00069 void DatGrid::distributeIllum(ColourType &il)
00070 {
00071
00072
00073
00074 }
00075
00076 float DatGrid::clipRay(vuSampleRay &r, bool bidirectional, int& m_Side) const
00077 {
00078 vuVector pos;
00079 vuVector dir;
00080 float X;
00081 float Y;
00082 float Z;
00083 float tMin=0;
00084 float t;
00085
00086 m_Side = -1;
00087
00088 pos = r.m_Position;
00089 dir = r.m_Direction;
00090
00091
00092 t = SnapToZero((m_C0[0] - pos[0]) / dir[0]);
00093 if (t > 0)
00094 {
00095 Y = pos[1] + t * dir[1];
00096 Z = pos[2] + t * dir[2];
00097 if ((Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00098 (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00099 (bidirectional || t>=0))
00100 {
00101 tMin = t;
00102 m_Side = 0;
00103 }
00104 }
00105
00106
00107 t = SnapToZero((m_C1[0] - pos[0]) / dir[0]);
00108 if (t > 0)
00109 {
00110 Y = pos[1] + t * dir[1];
00111 Z = pos[2] + t * dir[2];
00112 if ((Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00113 (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00114 (bidirectional || t>=0))
00115 {
00116 if ((m_Side==-1) || (t<tMin))
00117 {
00118 tMin = t;
00119 m_Side = 1;
00120 }
00121 }
00122 }
00123
00124
00125 t = SnapToZero((m_C0[1] - pos[1]) / dir[1]);
00126 if (t > 0)
00127 {
00128 X = pos[0] + t * dir[0];
00129 Z = pos[2] + t * dir[2];
00130 if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00131 (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00132 (bidirectional || t>=0))
00133 {
00134 if ((m_Side==-1) || (t<tMin))
00135 {
00136 tMin = t;
00137 m_Side = 2;
00138 }
00139 }
00140 }
00141
00142
00143 t = SnapToZero((m_C1[1] - pos[1]) / dir[1]);
00144 if (t > 0)
00145 {
00146 X = pos[0] + t * dir[0];
00147 Z = pos[2] + t * dir[2];
00148 if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00149 (Z >= m_C0[2]) && (Z <= m_C1[2]) &&
00150 (bidirectional || t>=0))
00151 {
00152 if ((m_Side==-1) || (t<tMin))
00153 {
00154 tMin = t;
00155 m_Side = 3;
00156 }
00157 }
00158 }
00159
00160
00161 t = SnapToZero((m_C0[2] - pos[2]) / dir[2]);
00162 if (t > 0)
00163 {
00164 X = pos[0] + t * dir[0];
00165 Y = pos[1] + t * dir[1];
00166 if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00167 (Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00168 (bidirectional || t>=0))
00169 {
00170 if ((m_Side==-1) || (t<tMin))
00171 {
00172 tMin = t;
00173 m_Side = 4;
00174 }
00175 }
00176 }
00177
00178
00179 t = SnapToZero((m_C1[2] - pos[2]) / dir[2]);
00180 if (t > 0)
00181 {
00182 X = pos[0] + t * dir[0];
00183 Y = pos[1] + t * dir[1];
00184 if ((X >= m_C0[0]) && (X <= m_C1[0]) &&
00185 (Y >= m_C0[1]) && (Y <= m_C1[1]) &&
00186 (bidirectional || t>=0))
00187 {
00188 if ((m_Side==-1) || (t<tMin))
00189 {
00190 tMin = t;
00191 m_Side = 5;
00192 }
00193 }
00194 }
00195 return tMin;
00196 }
00197
00198 void DatGrid::createSphere()
00199 {
00200 int i,j,k;
00201 int radius = maxX/2;
00202 for(i=0;i<maxZ;i++)
00203 for(j=0;j<maxY;j++)
00204 for(k=0;k<maxX;k++)
00205 {
00206 float d=(float)k-(maxX/2);
00207 float dist = d*d;
00208 d=(float)j-(maxY/2);
00209 dist += d*d;
00210 d=(float)i-(maxZ/2);
00211 dist += d*d;
00212 dist = (float)sqrt((double)dist);
00213
00214 float v=0;
00215 if (dist<radius)
00216 v= (float)sqrt((double)(radius-dist)/radius);
00217
00218
00219 vol[k+j*maxX+i*layXY].illum = 1.f;
00220 #ifndef DO_POST_CLASSIFICATION
00221 if(j<maxY/2) vol[k+j*maxX+i*layXY].density[2] = v;
00222 else if(k<maxX/2) vol[k+j*maxX+i*layXY].density[0] = v;
00223 else vol[k+j*maxX+i*layXY].density[1] = v;
00224 #else
00225 vol[k+j*maxX+i*layXY].data = (int)(255*v);
00226 #endif
00227 }
00228
00229
00230
00231 }
00232
00233
00234
00235 bool DatGrid::load_vol(byte* data, vu1112112 &r)
00236 {
00237 if (!data) return false;
00238 maxX = r.m_Dim1Size;
00239 maxY = r.m_Dim2Size;
00240 maxZ = r.m_Dim3Size;
00241
00242 init(maxX,maxY,maxZ);
00243 int c;
00244 for(c=0;c<size;c++)
00245 {
00246 vol[c].data = data[c];
00247 }
00248
00249 return true;
00250 }
00251
00252 void DatGrid::shade(vu1112112 &r)
00253 {
00254 int c;
00255 for(c=0;c<size;c++)
00256 {
00257 vol[c].shade(r);
00258 }
00259 }
00260
00261 void DatGrid::classify(vu1112112 &r)
00262 {
00263
00264
00265
00266
00267 int c;
00268 for(c=0;c<size;c++)
00269 {
00270 vol[c].classify(r);
00271 }
00272
00273 #if defined (USE_VUTFUNC)
00274 for(c=0;c<size-layXY-maxX-1;c++)
00275 {
00276 if(vol[c].getFlag() == DatPnt::Invisible &&
00277 vol[c+1].getFlag() == DatPnt::Invisible &&
00278 vol[c+maxX].getFlag() == DatPnt::Invisible &&
00279 vol[c+1+maxX].getFlag() == DatPnt::Invisible &&
00280 vol[c+layXY].getFlag() == DatPnt::Invisible &&
00281 vol[c+1+layXY].getFlag() == DatPnt::Invisible &&
00282 vol[c+maxX+layXY].getFlag() == DatPnt::Invisible &&
00283 vol[c+1+maxX+layXY].getFlag() == DatPnt::Invisible)
00284 {
00285 vol[c].setFlag(DatPnt::SkipCell);
00286 }
00287 }
00288 #endif
00289 }
00290
00291
00292 void DatGrid::calculate_gradients()
00293 {
00294 int i,j,k;
00295 int offset=0;
00296 for(k=0;k<maxZ;k++)
00297 for(j=0;j<maxY;j++)
00298 for(i=0;i<maxX;i++)
00299 {
00300 DatPnt *cc = vol + offset;
00301 int g[3];
00302
00303 g[0]= (i ? (int)vol[offset-1].data:0) -
00304 ((i<maxX-1) ? (int)vol[offset+1].data:0);
00305 g[1]= (j ? (int)vol[offset-maxX].data:0)
00306 -((j<maxY-1) ? (int)vol[offset+maxX].data:0);
00307 g[2]= (k ? (int)vol[offset-layXY].data:0)
00308 -((k<maxZ-1) ? (int)vol[offset+layXY].data:0);
00309
00310 float len= (float)sqrt(
00311 (double)(g[0]*g[0] +
00312 g[1]*g[1] +
00313 g[2]*g[2]));
00314 if(len!=0.0f)
00315 {
00316 cc->grad[0] = (int)((g[0]<<7)/len);
00317 cc->grad[1] = (int)((g[1]<<7)/len);
00318 cc->grad[2] = (int)((g[2]<<7)/len);
00319 } else cc->grad[0] = cc->grad[1] = cc->grad[2] = 0;
00320 cc->length= len>255.0f ? 255 : (char)len;
00321
00322 offset++;
00323 }
00324 }
00325
00326 }