00001 00002 // 00003 // File: vuSampleRay.cpp 00004 // Author: Steve Kilthau 00005 // Date: August, 1999 00006 // Adapted to vuVolume by Steven Bergner, 2001 00011 #include <stddef.h> 00012 #include <math.h> 00013 #include "Util.h" 00014 #include "vuRay.h" 00015 #include "vuSampleRay.h" 00016 00017 namespace ns_vu1112112 { 00018 using namespace ns_vu1112112; 00019 00020 // Default constructor 00021 vuSampleRay::vuSampleRay() : vuRay() 00022 { 00023 steps = 0; 00024 m_Grid = NULL; 00025 m_SmpDist = 1.f; 00026 } 00027 00028 // Copy constructor 00029 vuSampleRay::vuSampleRay(const vuSampleRay &r) : vuRay(r) 00030 { 00031 steps = 0; 00032 m_Grid = r.m_Grid; 00033 m_SmpDist = 1.f; 00034 } 00035 00036 // Copy constructor 00037 vuSampleRay::vuSampleRay(const vuRay &r) : vuRay(r) 00038 { 00039 m_Grid = NULL; 00040 m_SmpDist = 1.f; 00041 } 00042 00043 // Destructor 00044 vuSampleRay::~vuSampleRay() 00045 { 00046 } 00047 00048 // Assignment operator 00049 vuSampleRay& vuSampleRay::operator=(vuSampleRay &rhs) 00050 { 00051 vuRay::operator=(rhs); 00052 m_Grid = rhs.m_Grid; 00053 steps = rhs.steps; 00054 //there is more to do now... 00055 return *this; 00056 } 00057 00058 float vuSampleRay::SamplingDistance() const 00059 { 00060 return m_SmpDist; 00061 } 00062 00063 void vuSampleRay::SamplingDistance(float sd) 00064 { 00065 m_Direction *= sd/m_Direction.norm(); 00066 m_SmpDist = sd; 00067 steps = 0; 00068 m_Grid = NULL; 00069 } 00070 00071 bool vuSampleRay::advanceRay() 00072 { 00073 if(!steps || !m_Grid) return false; 00074 steps--; 00075 00076 m_Position += m_Direction; 00077 //maintain cell indexing 00078 p[0]=(int)(m_Position[0]); 00079 if(p[0]>=m_Grid->maxX-1) return false; 00080 p[1]=(int)(m_Position[1]); 00081 if(p[1]>=m_Grid->maxY-1) return false; 00082 p[2]=(int)(m_Position[2]); 00083 if(p[2]>=m_Grid->maxZ-1) return false; 00084 cell[0] = m_Grid->vol+p[0]+p[1]*m_Grid->maxX+p[2]*m_Grid->layXY; 00085 if(cell[0]->getFlag() == DatPnt::SkipCell) 00086 { 00087 emptySample = true; 00088 return true; 00089 } else emptySample = false; 00090 cell[1] = cell[0]+1; 00091 cell[2] = cell[0]+m_Grid->maxX; 00092 cell[3] = cell[1]+m_Grid->maxX; 00093 cell[4] = cell[0]+m_Grid->layXY; 00094 cell[5] = cell[1]+m_Grid->layXY; 00095 cell[6] = cell[2]+m_Grid->layXY; 00096 cell[7] = cell[3]+m_Grid->layXY; 00097 00098 float s[3]; 00099 s[0] = m_Position[0]-(float)p[0]; 00100 s[1] = m_Position[1]-(float)p[1]; 00101 s[2] = m_Position[2]-(float)p[2]; 00102 t[0] = 1.f-s[0]; 00103 t[1] = 1.f-s[1]; 00104 t[2] = 1.f-s[2]; 00105 w[0] = w[4] = t[0]*t[1]; 00106 w[1] = w[5] = s[0]*t[1]; 00107 w[2] = w[6] = t[0]*s[1]; 00108 w[3] = w[7] = s[0]*s[1]; 00109 w[0] *= t[2]; 00110 w[1] *= t[2]; 00111 w[2] *= t[2]; 00112 w[3] *= t[2]; 00113 w[4] *= s[2]; 00114 w[5] *= s[2]; 00115 w[6] *= s[2]; 00116 w[7] *= s[2]; 00117 00118 return true; 00119 } 00120 00121 bool vuSampleRay::getSamplePoint(DatPnt &dat) const 00122 { 00123 if(!m_Grid) return false; 00124 dat.reset(); 00125 if(emptySample) { 00126 dat.data=0; 00127 return true; 00128 } 00129 int v; 00130 00131 float fdata=0; 00132 for(v=0;v<8;v++) 00133 { 00134 dat.illum += cell[v]->illum*w[v]; 00135 00136 #ifdef DO_POST_CLASSIFICATION 00137 fdata += cell[v]->data*w[v]; 00138 #else 00139 int m; 00140 for(m=0;m<MAT_NUM_MATERIALS;m++) 00141 dat.density[m] += cell[v]->density[m]*w[v]; 00142 #endif 00143 } 00144 dat.data = (int) fdata; 00145 00146 return true; 00147 } 00148 00149 bool vuSampleRay::getSamplePointWithGradient(DatPnt &dat) const 00150 { 00151 if(!m_Grid) return false; 00152 dat.reset(); 00153 if(emptySample) { 00154 dat.data=0; 00155 return true; 00156 } 00157 int v; 00158 dat.grad[0]=dat.grad[1]=dat.grad[2]=dat.length=0; 00159 00160 float fdata=0; 00161 for(v=0;v<8;v++) 00162 { 00163 if(cell[v]->length) 00164 { 00165 dat.grad[0] += (int)(cell[v]->grad[0]*w[v]); 00166 dat.grad[1] += (int)(cell[v]->grad[1]*w[v]); 00167 dat.grad[2] += (int)(cell[v]->grad[2]*w[v]); 00168 dat.length += (int)(cell[v]->length*w[v]); 00169 } 00170 00171 dat.illum += cell[v]->illum*w[v]; 00172 00173 #ifdef DO_POST_CLASSIFICATION 00174 fdata += cell[v]->data*w[v]; 00175 #else 00176 int m; 00177 for(m=0;m<MAT_NUM_MATERIALS;m++) 00178 dat.density[m] += cell[v]->density[m]*w[v]; 00179 #endif 00180 } 00181 dat.data = (int) fdata; 00182 00183 return true; 00184 } 00185 00186 bool vuSampleRay::attachToGrid(const DatGrid& grid) 00187 { 00188 int m_Side, m_InSide; 00189 steps = 0; 00190 00191 float t = grid.clipRay(*this,true,m_InSide); 00192 if ((t<=0.0) || (m_InSide==-1)) 00193 return false; 00194 00195 // Find the point 00196 m_Position += t*m_Direction; 00197 vuSampleRay r1(*this); 00198 r1.m_Position += r1.m_Direction; // one step into the volume 00199 t = grid.clipRay(r1,false,m_Side); // only look at sides in front of ray 00200 if(t <= 0 || m_Side==-1) 00201 { 00202 steps = 0; 00203 m_Grid = 0; 00204 return false; 00205 } else { 00206 steps = (int)t+1; 00207 m_Grid = &grid; 00208 return true; 00209 } 00210 } 00211 00212 } // end of namespace