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 "vuSampleRay.h" 00014 00015 using namespace ns_vu1112113; 00016 00017 // Default constructor 00018 vuSampleRay::vuSampleRay() : vuRay() 00019 { 00020 steps = 0; 00021 m_Grid = NULL; 00022 m_SmpDist = 1.f; 00023 } 00024 00025 // Copy constructor 00026 vuSampleRay::vuSampleRay(const vuSampleRay &r) : vuRay(r) 00027 { 00028 steps = 0; 00029 m_Grid = r.m_Grid; 00030 m_SmpDist = 1.f; 00031 } 00032 00033 // Copy constructor 00034 vuSampleRay::vuSampleRay(const vuRay &r) : vuRay(r) 00035 { 00036 m_Grid = NULL; 00037 m_SmpDist = 1.f; 00038 } 00039 00040 // Destructor 00041 vuSampleRay::~vuSampleRay() 00042 { 00043 } 00044 00045 // Assignment operator 00046 vuSampleRay& vuSampleRay::operator=(vuSampleRay &rhs) 00047 { 00048 vuRay::operator=(rhs); 00049 m_Grid = rhs.m_Grid; 00050 steps = rhs.steps; 00051 //there is more to do now... 00052 return *this; 00053 } 00054 00055 float vuSampleRay::SamplingDistance() const 00056 { 00057 return m_SmpDist; 00058 } 00059 00060 void vuSampleRay::SamplingDistance(float sd) 00061 { 00062 m_Direction *= sd/m_Direction.norm(); 00063 m_SmpDist = sd; 00064 steps = 0; 00065 m_Grid = NULL; 00066 } 00067 00068 bool vuSampleRay::advanceRay() 00069 { 00070 if(!steps || !m_Grid) return false; 00071 00072 m_Position += m_Direction; 00073 //maintain cell indexing 00074 p[0]=(int)(m_Position[0]); 00075 if(p[0]>=m_Grid->maxX-1) return false; 00076 p[1]=(int)(m_Position[1]); 00077 if(p[1]>=m_Grid->maxY-1) return false; 00078 p[2]=(int)(m_Position[2]); 00079 if(p[2]>=m_Grid->maxZ-1) return false; 00080 cell[0] = m_Grid->vol+p[0]+p[1]*m_Grid->maxX+p[2]*m_Grid->layXY; 00081 cell[1] = cell[0]+1; 00082 cell[2] = cell[0]+m_Grid->maxX; 00083 cell[3] = cell[1]+m_Grid->maxX; 00084 cell[4] = cell[0]+m_Grid->layXY; 00085 cell[5] = cell[1]+m_Grid->layXY; 00086 cell[6] = cell[2]+m_Grid->layXY; 00087 cell[7] = cell[3]+m_Grid->layXY; 00088 00089 float s[3]; 00090 s[0] = m_Position[0]-(float)p[0]; 00091 s[1] = m_Position[1]-(float)p[1]; 00092 s[2] = m_Position[2]-(float)p[2]; 00093 t[0] = 1.f-s[0]; 00094 t[1] = 1.f-s[1]; 00095 t[2] = 1.f-s[2]; 00096 w[0] = w[4] = t[0]*t[1]; 00097 w[1] = w[5] = s[0]*t[1]; 00098 w[2] = w[6] = t[0]*s[1]; 00099 w[3] = w[7] = s[0]*s[1]; 00100 w[0] *= t[2]; 00101 w[1] *= t[2]; 00102 w[2] *= t[2]; 00103 w[3] *= t[2]; 00104 w[4] *= s[2]; 00105 w[5] *= s[2]; 00106 w[6] *= s[2]; 00107 w[7] *= s[2]; 00108 00109 steps--; 00110 return true; 00111 } 00112 00113 float vuSampleRay::getSamplePoint(DatPnt &dat, bool getnormal) const 00114 { 00115 if(!m_Grid) return 0.0f; 00116 dat.reset(); 00117 int v; 00118 vuVector norm(0.0f); 00119 float fdata=0, flen=0; 00120 for(v=0;v<8;v++) 00121 { 00122 if( getnormal && cell[v]->len) 00123 { 00124 norm += cell[v]->normalVec()*w[v]; 00125 flen += cell[v]->len*w[v]; 00126 } 00127 00128 dat.illum += cell[v]->illum*w[v]; 00129 00130 fdata += cell[v]->data*w[v]; 00131 } 00132 dat.setNormalVec(norm); 00133 dat.data = byte(fdata); 00134 dat.len = byte(flen); 00135 return fdata; 00136 } 00137 00138 bool vuSampleRay::attachToGrid(const DatGrid& grid) 00139 { 00140 int m_Side, m_InSide; 00141 steps = 0; 00142 00143 float t = grid.clipRay(*this,true,m_InSide); 00144 00145 // if m_inside == 6, we are rendering from within the volume 00146 if ( m_InSide != 6 && ((t<=0.0) || (m_InSide==-1))) 00147 return false; 00148 00149 // Find the point 00150 m_Position += t*m_Direction; 00151 vuSampleRay r1(*this); 00152 r1.m_Position += r1.m_Direction; // one step into the volume 00153 t = grid.clipRay(r1,false,m_Side); // only look at sides in front of ray 00154 if(t <= 0 || m_Side==-1) 00155 { 00156 steps = 0; 00157 m_Grid = 0; 00158 return false; 00159 } else { 00160 steps = (int)t+1; 00161 m_Grid = &grid; 00162 return true; 00163 } 00164 }