00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace PolyVox
00025 {
00034 template< template<typename> class VolumeType, typename VoxelType>
00035 Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result)
00036 :m_result(result)
00037 ,m_volData(volData)
00038 ,m_sampVolume(volData)
00039 ,m_v3dStart(v3dStart)
00040 ,m_v3dDirection(v3dDirection)
00041 {
00042 }
00043
00047 template< template<typename> class VolumeType, typename VoxelType>
00048 void Raycast<VolumeType, VoxelType>::setStart(const Vector3DFloat& v3dStart)
00049 {
00050 m_v3dStart = v3dStart;
00051 }
00052
00057 template< template<typename> class VolumeType, typename VoxelType>
00058 void Raycast<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection)
00059 {
00060 m_v3dDirection = v3dDirection;
00061 }
00062
00066 template< template<typename> class VolumeType, typename VoxelType>
00067 void Raycast<VolumeType, VoxelType>::execute(void)
00068 {
00069
00070
00071
00072 Vector3DFloat v3dStart = m_v3dStart + Vector3DFloat(0.5f, 0.5f, 0.5f);
00073
00074
00075 Vector3DFloat v3dEnd = v3dStart + m_v3dDirection;
00076
00077
00078 doRaycast(v3dStart.getX(), v3dStart.getY(), v3dStart.getZ(), v3dEnd.getX(), v3dEnd.getY(), v3dEnd.getZ());
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 template< template<typename> class VolumeType, typename VoxelType>
00111 void Raycast<VolumeType, VoxelType>::doRaycast(float x1, float y1, float z1, float x2, float y2, float z2)
00112 {
00113 int i = (int)floorf(x1);
00114 int j = (int)floorf(y1);
00115 int k = (int)floorf(z1);
00116
00117 int iend = (int)floorf(x2);
00118 int jend = (int)floorf(y2);
00119 int kend = (int)floorf(z2);
00120
00121 int di = ((x1 < x2) ? 1 : ((x1 > x2) ? -1 : 0));
00122 int dj = ((y1 < y2) ? 1 : ((y1 > y2) ? -1 : 0));
00123 int dk = ((z1 < z2) ? 1 : ((z1 > z2) ? -1 : 0));
00124
00125 float minx = floorf(x1), maxx = minx + 1.0f;
00126 float tx = ((x1 > x2) ? (x1 - minx) : (maxx - x1)) / abs(x2 - x1);
00127 float miny = floorf(y1), maxy = miny + 1.0f;
00128 float ty = ((y1 > y2) ? (y1 - miny) : (maxy - y1)) / abs(y2 - y1);
00129 float minz = floorf(z1), maxz = minz + 1.0f;
00130 float tz = ((z1 > z2) ? (z1 - minz) : (maxz - z1)) / abs(z2 - z1);
00131
00132 float deltatx = 1.0f / abs(x2 - x1);
00133 float deltaty = 1.0f / abs(y2 - y1);
00134 float deltatz = 1.0f / abs(z2 - z1);
00135
00136 m_sampVolume.setPosition(i,j,k);
00137 m_result.previousVoxel = Vector3DInt32(i,j,k);
00138
00139 for(;;)
00140 {
00141 if(m_sampVolume.getVoxel().getDensity() > VoxelType::getThreshold())
00142 {
00143 m_result.foundIntersection = true;
00144 m_result.intersectionVoxel = Vector3DInt32(i,j,k);
00145 return;
00146 }
00147 m_result.previousVoxel = Vector3DInt32(i,j,k);
00148
00149 if(tx <= ty && tx <= tz)
00150 {
00151 if(i == iend) break;
00152 tx += deltatx;
00153 i += di;
00154
00155 if(di == 1) m_sampVolume.movePositiveX();
00156 if(di == -1) m_sampVolume.moveNegativeX();
00157 } else if (ty <= tz)
00158 {
00159 if(j == jend) break;
00160 ty += deltaty;
00161 j += dj;
00162
00163 if(dj == 1) m_sampVolume.movePositiveY();
00164 if(dj == -1) m_sampVolume.moveNegativeY();
00165 } else
00166 {
00167 if(k == kend) break;
00168 tz += deltatz;
00169 k += dk;
00170
00171 if(dk == 1) m_sampVolume.movePositiveZ();
00172 if(dk == -1) m_sampVolume.moveNegativeZ();
00173 }
00174 }
00175
00176
00177 m_result.foundIntersection = false;
00178 m_result.intersectionVoxel = Vector3DInt32(0,0,0);
00179 m_result.previousVoxel = Vector3DInt32(0,0,0);
00180 }
00181 }