00001 #include "CVolVoxels.h"
00002 #include "lifeVariables.h"
00003
00004
00005 void CVolVoxels::Init( unsigned short * pVoxelData, unsigned short dimX, unsigned short dimY, unsigned short dimZ )
00006 {
00007 if ( _pVoxelData || !pVoxelData )
00008 throw;
00009
00010 _pVoxelData = pVoxelData;
00011 _dimX = dimX;
00012 _dimY = dimY;
00013 _dimZ = dimZ;
00014 _size = _dimX * _dimY * _dimZ;
00015
00016 _boundingDim = (int)((float)sqrt( _dimX * _dimX + _dimY * _dimY + _dimZ * _dimZ ));
00017
00018 if ( _grad )
00019 throw;
00020
00021 _grad = new sGrad[_size];
00022 if ( !_grad)
00023 throw;
00024
00025 for ( int i = 0; i < _size; i++ )
00026 {
00027 _grad[i].x = 0;
00028 _grad[i].y = 0;
00029 _grad[i].z = 0;
00030 }
00031
00032 ComputeGradient();
00033
00034 }
00035
00036 unsigned short CVolVoxels::GetMaxValue()
00037 {
00038 unsigned uNewVal = 0;
00039
00040 if ( _MaxValue != 0 )
00041 return _MaxValue;
00042
00043 for ( int i = 0; i < _size; i++ )
00044 {
00045 if ( uNewVal < _pVoxelData[i] )
00046 {
00047 uNewVal = _pVoxelData[i];
00048 }
00049 }
00050
00051 _MaxValue = uNewVal;
00052
00053 if ( ! _MaxValue )
00054 throw;
00055
00056 return _MaxValue;
00057 }
00058
00059
00060
00061
00062
00063
00064 void CVolVoxels::ComputeGradient()
00065 {
00066 float gradX, gradY, gradZ;
00067
00068 for ( int k = 1; k < _dimZ-1; k++ )
00069 for ( int j = 1; j < _dimY-1; j++ )
00070 for ( int i = 1; i < _dimX-1; i++ )
00071 {
00072
00073 gradX = (float) ( GVolVoxels.GetVoxelValue(i+1,j,k) - GVolVoxels.GetVoxelValue(i-1,j,k) ) / 2;
00074 gradY = (float) ( GVolVoxels.GetVoxelValue(i,j+1,k) - GVolVoxels.GetVoxelValue(i,j-1,k) ) / 2;
00075 gradZ = (float) ( GVolVoxels.GetVoxelValue(i,j,k+1) - GVolVoxels.GetVoxelValue(i,j,k-1) ) / 2;
00076
00077 CVector3f tmpGrad(gradX, gradY,gradZ);
00078
00079 SetGradient(i,j,k, tmpGrad.GetNormalized());
00080
00081 sGrad outGrad;
00082
00083 GetGradientTriLinear(i,j,k, &outGrad);
00084
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 float CVolVoxels::GetDensityTriLinear(sPoint3f pos)
00095 {
00096
00097
00098
00099 unsigned x0,y0,z0, x1,y1,z1;
00100 float dx, dy, dz;
00101
00102 x0 = pos.x; y0 = pos.y; z0 = pos.z;
00103 x1 = x0+1; y1 = y0+1; z1 = z0+1;
00104
00105
00106
00107
00108 if ( x1 > _dimX || y1 > _dimY || z1 > _dimZ )
00109 return GVolVoxels.GetVoxelValue(x0,y0,z0);
00110
00111
00112
00113
00114 dx = pos.x - x0; dy = pos.y - y0; dz = pos.z - z0;
00115
00116
00117
00118
00119 float dx0, dx1, dy0, dy1, dz0, dz1, dxyz;
00120
00121 dx0 = GVolVoxels.GetVoxelValue(x0,y0,z0) * (1-dx) + GVolVoxels.GetVoxelValue(x1,y0,z0) * dx;
00122 dx1 = GVolVoxels.GetVoxelValue(x0,y1,z0) * (1-dx) + GVolVoxels.GetVoxelValue(x1,y1,z0) * dx;
00123 dy0 = GVolVoxels.GetVoxelValue(x0,y0,z1) * (1-dx) + GVolVoxels.GetVoxelValue(x1,y0,z1) * dx;
00124 dy1 = GVolVoxels.GetVoxelValue(x0,y1,z1) * (1-dx) + GVolVoxels.GetVoxelValue(x1,y1,z1) * dx;
00125
00126 dz0 = dx0 * (1-dy) + dx1 * dy;
00127 dz1 = dy0 * (1-dy) + dy1 * dy;
00128
00129 dxyz = dz0 * (1-dz) + dz1 * dz;
00130
00131 return dxyz;
00132 }
00133
00134
00135 void CVolVoxels::GetGradientTriLinear(float i, float j, float k, sGrad * pGrad)
00136 {
00137
00138
00139
00140 unsigned x0,y0,z0, x1,y1,z1;
00141 float dx, dy, dz;
00142
00143 x0 = i; y0 = j; z0 = k;
00144 x1 = x0+1; y1 = y0+1; z1 = z0+1;
00145
00146
00147
00148
00149 if ( x1 > _dimX || y1 > _dimY || z1 > _dimZ )
00150 {
00151 GVolVoxels.GetGradient(x0,y0,z0,pGrad);
00152 return;
00153 }
00154
00155
00156
00157
00158 dx = i - x0; dy = j - y0; dz = k - z0;
00159
00160
00161
00162
00163 sGrad grad_x0, grad_x1, grad_y0, grad_y1, grad_z0, grad_z1, grad_xyz;
00164
00165 grad_x0 = GVolVoxels.GetGradient(x0,y0,z0) * (1-dx) + GVolVoxels.GetGradient(x1,y0,z0) * dx;
00166 grad_x1 = GVolVoxels.GetGradient(x0,y1,z0) * (1-dx) + GVolVoxels.GetGradient(x1,y1,z0) * dx;
00167 grad_y0 = GVolVoxels.GetGradient(x0,y0,z1) * (1-dx) + GVolVoxels.GetGradient(x1,y0,z1) * dx;
00168 grad_y1 = GVolVoxels.GetGradient(x0,y1,z1) * (1-dx) + GVolVoxels.GetGradient(x1,y1,z1) * dx;
00169
00170 grad_z0 = grad_x0 * (1-dy) + grad_x1 * dy;
00171 grad_z1 = grad_y0 * (1-dy) + grad_y1 * dy;
00172
00173 grad_xyz = grad_z0 * (1-dz) + grad_z1 * dz;
00174
00175 pGrad->x = grad_xyz.x;
00176 pGrad->y = grad_xyz.y;
00177 pGrad->z = grad_xyz.z;
00178
00179 return;
00180 }