Applied default Visual Studio formatting to most files. This is a quick fix for the tabs vs spaces issue that messes up the formatting in any editor (esp. Linux) which handles tabs/spaces differently to Visual Studio. Some parts of the formatting look a bit worse but overall it should be better (or at least more consistent).

I didn't apply the changes to a few macro-heavy files as Visual Studio removes all indentation from macros, whereas the indentation can be handy to see nesting.
This commit is contained in:
David Williams 2015-12-26 23:11:27 +00:00
parent b3ca051878
commit e89a55d154
58 changed files with 1117 additions and 1114 deletions

View File

@ -47,14 +47,14 @@ void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
for (int x = 0; x < volData.getWidth(); x++) for (int x = 0; x < volData.getWidth(); x++)
{ {
//Store our current position as a vector... //Store our current position as a vector...
Vector3DFloat v3dCurrentPos(x,y,z); Vector3DFloat v3dCurrentPos(x, y, z);
//And compute how far the current position is from the center of the volume //And compute how far the current position is from the center of the volume
float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();
uint8_t uVoxelValue = 0; uint8_t uVoxelValue = 0;
//If the current voxel is less than 'radius' units from the center then we make it solid. //If the current voxel is less than 'radius' units from the center then we make it solid.
if(fDistToCenter <= fRadius) if (fDistToCenter <= fRadius)
{ {
//Our new voxel value //Our new voxel value
uVoxelValue = 255; uVoxelValue = 255;

View File

@ -47,14 +47,14 @@ void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
for (int x = 0; x < volData.getWidth(); x++) for (int x = 0; x < volData.getWidth(); x++)
{ {
//Store our current position as a vector... //Store our current position as a vector...
Vector3DFloat v3dCurrentPos(x,y,z); Vector3DFloat v3dCurrentPos(x, y, z);
//And compute how far the current position is from the center of the volume //And compute how far the current position is from the center of the volume
float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();
uint8_t uVoxelValue = 0; uint8_t uVoxelValue = 0;
//If the current voxel is less than 'radius' units from the center then we make it solid. //If the current voxel is less than 'radius' units from the center then we make it solid.
if(fDistToCenter <= fRadius) if (fDistToCenter <= fRadius)
{ {
//Our new voxel value //Our new voxel value
uVoxelValue = 255; uVoxelValue = 255;

View File

@ -41,15 +41,15 @@ void createSphereInVolume(RawVolume<MaterialDensityPair88>& volData, float fRadi
for (int x = 0; x < volData.getWidth(); x++) for (int x = 0; x < volData.getWidth(); x++)
{ {
//Store our current position as a vector... //Store our current position as a vector...
Vector3DInt32 v3dCurrentPos(x,y,z); Vector3DInt32 v3dCurrentPos(x, y, z);
//And compute how far the current position is from the center of the volume //And compute how far the current position is from the center of the volume
double fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); double fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();
//If the current voxel is less than 'radius' units from the center //If the current voxel is less than 'radius' units from the center
//then we make it solid, otherwise we make it empty space. //then we make it solid, otherwise we make it empty space.
if(fDistToCenter <= fRadius) if (fDistToCenter <= fRadius)
{ {
volData.setVoxel(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? MaterialDensityPair88::getMaxDensity() : MaterialDensityPair88::getMinDensity())); volData.setVoxel(x, y, z, MaterialDensityPair88(uValue, uValue > 0 ? MaterialDensityPair88::getMaxDensity() : MaterialDensityPair88::getMinDensity()));
} }
} }
} }
@ -65,9 +65,9 @@ void createCubeInVolume(RawVolume<MaterialDensityPair88>& volData, Vector3DInt32
{ {
for (int y = lowerCorner.getY(); y <= upperCorner.getY(); y++) for (int y = lowerCorner.getY(); y <= upperCorner.getY(); y++)
{ {
for (int x = lowerCorner.getX() ; x <= upperCorner.getX(); x++) for (int x = lowerCorner.getX(); x <= upperCorner.getX(); x++)
{ {
volData.setVoxel(x,y,z, MaterialDensityPair88(uValue, uValue > 0 ? maxDen : minDen)); volData.setVoxel(x, y, z, MaterialDensityPair88(uValue, uValue > 0 ? maxDen : minDen));
} }
} }
} }

View File

@ -36,18 +36,18 @@ float Perlin::noise1(float arg)
vec[0] = arg; vec[0] = arg;
if (mStart) if (mStart)
{ {
srand(mSeed); srand(mSeed);
mStart = false; mStart = false;
init(); init();
} }
setup(0, bx0,bx1, rx0,rx1); setup(0, bx0, bx1, rx0, rx1);
sx = s_curve(rx0); sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ]; u = rx0 * g1[p[bx0]];
v = rx1 * g1[ p[ bx1 ] ]; v = rx1 * g1[p[bx1]];
return lerp(sx, u, v); return lerp(sx, u, v);
} }
@ -59,14 +59,14 @@ float Perlin::noise2(float vec[2])
int i, j; int i, j;
if (mStart) if (mStart)
{ {
srand(mSeed); srand(mSeed);
mStart = false; mStart = false;
init(); init();
} }
setup(0,bx0,bx1,rx0,rx1); setup(0, bx0, bx1, rx0, rx1);
setup(1,by0,by1,ry0,ry1); setup(1, by0, by1, ry0, ry1);
i = p[bx0]; i = p[bx0];
j = p[bx1]; j = p[bx1];
@ -79,18 +79,18 @@ float Perlin::noise2(float vec[2])
sx = s_curve(rx0); sx = s_curve(rx0);
sy = s_curve(ry0); sy = s_curve(ry0);
#define at2(rx,ry) ( rx * q[0] + ry * q[1] ) #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
q = g2[b00]; q = g2[b00];
u = at2(rx0,ry0); u = at2(rx0, ry0);
q = g2[b10]; q = g2[b10];
v = at2(rx1,ry0); v = at2(rx1, ry0);
a = lerp(sx, u, v); a = lerp(sx, u, v);
q = g2[b01]; q = g2[b01];
u = at2(rx0,ry1); u = at2(rx0, ry1);
q = g2[b11]; q = g2[b11];
v = at2(rx1,ry1); v = at2(rx1, ry1);
b = lerp(sx, u, v); b = lerp(sx, u, v);
return lerp(sy, a, b); return lerp(sy, a, b);
@ -103,46 +103,46 @@ float Perlin::noise3(float vec[3])
int i, j; int i, j;
if (mStart) if (mStart)
{ {
srand(mSeed); srand(mSeed);
mStart = false; mStart = false;
init(); init();
} }
setup(0, bx0,bx1, rx0,rx1); setup(0, bx0, bx1, rx0, rx1);
setup(1, by0,by1, ry0,ry1); setup(1, by0, by1, ry0, ry1);
setup(2, bz0,bz1, rz0,rz1); setup(2, bz0, bz1, rz0, rz1);
i = p[ bx0 ]; i = p[bx0];
j = p[ bx1 ]; j = p[bx1];
b00 = p[ i + by0 ]; b00 = p[i + by0];
b10 = p[ j + by0 ]; b10 = p[j + by0];
b01 = p[ i + by1 ]; b01 = p[i + by1];
b11 = p[ j + by1 ]; b11 = p[j + by1];
t = s_curve(rx0); t = s_curve(rx0);
sy = s_curve(ry0); sy = s_curve(ry0);
sz = s_curve(rz0); sz = s_curve(rz0);
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0); q = g3[b00 + bz0]; u = at3(rx0, ry0, rz0);
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0); q = g3[b10 + bz0]; v = at3(rx1, ry0, rz0);
a = lerp(t, u, v); a = lerp(t, u, v);
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0); q = g3[b01 + bz0]; u = at3(rx0, ry1, rz0);
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0); q = g3[b11 + bz0]; v = at3(rx1, ry1, rz0);
b = lerp(t, u, v); b = lerp(t, u, v);
c = lerp(sy, a, b); c = lerp(sy, a, b);
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1); q = g3[b00 + bz1]; u = at3(rx0, ry0, rz1);
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1); q = g3[b10 + bz1]; v = at3(rx1, ry0, rz1);
a = lerp(t, u, v); a = lerp(t, u, v);
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1); q = g3[b01 + bz1]; u = at3(rx0, ry1, rz1);
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1); q = g3[b11 + bz1]; v = at3(rx1, ry1, rz1);
b = lerp(t, u, v); b = lerp(t, u, v);
d = lerp(sy, a, b); d = lerp(sy, a, b);
@ -155,7 +155,7 @@ void Perlin::normalize2(float v[2])
float s; float s;
s = (float)sqrt(v[0] * v[0] + v[1] * v[1]); s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
s = 1.0f/s; s = 1.0f / s;
v[0] = v[0] * s; v[0] = v[0] * s;
v[1] = v[1] * s; v[1] = v[1] * s;
} }
@ -165,7 +165,7 @@ void Perlin::normalize3(float v[3])
float s; float s;
s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
s = 1.0f/s; s = 1.0f / s;
v[0] = v[0] * s; v[0] = v[0] * s;
v[1] = v[1] * s; v[1] = v[1] * s;
@ -176,32 +176,32 @@ void Perlin::init(void)
{ {
int i, j, k; int i, j, k;
for (i = 0 ; i < B ; i++) for (i = 0; i < B; i++)
{ {
p[i] = i; p[i] = i;
g1[i] = (float)((rand() % (B + B)) - B) / B; g1[i] = (float)((rand() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++) for (j = 0; j < 2; j++)
g2[i][j] = (float)((rand() % (B + B)) - B) / B; g2[i][j] = (float)((rand() % (B + B)) - B) / B;
normalize2(g2[i]); normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++) for (j = 0; j < 3; j++)
g3[i][j] = (float)((rand() % (B + B)) - B) / B; g3[i][j] = (float)((rand() % (B + B)) - B) / B;
normalize3(g3[i]); normalize3(g3[i]);
} }
while (--i) while (--i)
{ {
k = p[i]; k = p[i];
p[i] = p[j = rand() % B]; p[i] = p[j = rand() % B];
p[j] = k; p[j] = k;
} }
for (i = 0 ; i < B + 2 ; i++) for (i = 0; i < B + 2; i++)
{ {
p[B + i] = p[i]; p[B + i] = p[i];
g1[B + i] = g1[i]; g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++) for (j = 0; j < 2; j++)
g2[B + i][j] = g2[i][j]; g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++) for (j = 0; j < 3; j++)
g3[B + i][j] = g3[i][j]; g3[B + i][j] = g3[i][j];
} }
@ -210,19 +210,19 @@ void Perlin::init(void)
float Perlin::perlin_noise_2D(float vec[2]) float Perlin::perlin_noise_2D(float vec[2])
{ {
int terms = mOctaves; int terms = mOctaves;
float result = 0.0f; float result = 0.0f;
float amp = mAmplitude; float amp = mAmplitude;
vec[0]*=mFrequency; vec[0] *= mFrequency;
vec[1]*=mFrequency; vec[1] *= mFrequency;
for( int i=0; i<terms; i++ ) for (int i = 0; i < terms; i++)
{ {
result += noise2(vec)*amp; result += noise2(vec)*amp;
vec[0] *= 2.0f; vec[0] *= 2.0f;
vec[1] *= 2.0f; vec[1] *= 2.0f;
amp*=0.5f; amp *= 0.5f;
} }
@ -231,21 +231,21 @@ float Perlin::perlin_noise_2D(float vec[2])
float Perlin::perlin_noise_3D(float vec[3]) float Perlin::perlin_noise_3D(float vec[3])
{ {
int terms = mOctaves; int terms = mOctaves;
float result = 0.0f; float result = 0.0f;
float amp = mAmplitude; float amp = mAmplitude;
vec[0]*=mFrequency; vec[0] *= mFrequency;
vec[1]*=mFrequency; vec[1] *= mFrequency;
vec[2]*=mFrequency; vec[2] *= mFrequency;
for( int i=0; i<terms; i++ ) for (int i = 0; i < terms; i++)
{ {
result += noise3(vec)*amp; result += noise3(vec)*amp;
vec[0] *= 2.0f; vec[0] *= 2.0f;
vec[1] *= 2.0f; vec[1] *= 2.0f;
vec[2] *= 2.0f; vec[2] *= 2.0f;
amp*=0.5f; amp *= 0.5f;
} }
@ -254,12 +254,12 @@ float Perlin::perlin_noise_3D(float vec[3])
Perlin::Perlin(int octaves,float freq,float amp,int seed) Perlin::Perlin(int octaves, float freq, float amp, int seed)
{ {
mOctaves = octaves; mOctaves = octaves;
mFrequency = freq; mFrequency = freq;
mAmplitude = amp; mAmplitude = amp;
mSeed = seed; mSeed = seed;
mStart = true; mStart = true;
} }

View File

@ -53,29 +53,30 @@ public:
virtual void pageIn(const PolyVox::Region& region, PagedVolume<MaterialDensityPair44>::Chunk* pChunk) virtual void pageIn(const PolyVox::Region& region, PagedVolume<MaterialDensityPair44>::Chunk* pChunk)
{ {
Perlin perlin(2,2,1,234); Perlin perlin(2, 2, 1, 234);
for(int x = region.getLowerX(); x <= region.getUpperX(); x++) for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
{ {
for(int y = region.getLowerY(); y <= region.getUpperY(); y++) for (int y = region.getLowerY(); y <= region.getUpperY(); y++)
{ {
float perlinVal = perlin.Get(x / static_cast<float>(255-1), y / static_cast<float>(255-1)); float perlinVal = perlin.Get(x / static_cast<float>(255 - 1), y / static_cast<float>(255 - 1));
perlinVal += 1.0f; perlinVal += 1.0f;
perlinVal *= 0.5f; perlinVal *= 0.5f;
perlinVal *= 255; perlinVal *= 255;
for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++) for (int z = region.getLowerZ(); z <= region.getUpperZ(); z++)
{ {
MaterialDensityPair44 voxel; MaterialDensityPair44 voxel;
if(z < perlinVal) if (z < perlinVal)
{ {
const int xpos = 50; const int xpos = 50;
const int zpos = 100; const int zpos = 100;
if((x-xpos)*(x-xpos) + (z-zpos)*(z-zpos) < 200) if ((x - xpos)*(x - xpos) + (z - zpos)*(z - zpos) < 200)
{ {
// tunnel // tunnel
voxel.setMaterial(0); voxel.setMaterial(0);
voxel.setDensity(MaterialDensityPair44::getMinDensity()); voxel.setDensity(MaterialDensityPair44::getMinDensity());
} else }
else
{ {
// solid // solid
voxel.setMaterial(245); voxel.setMaterial(245);
@ -150,4 +151,4 @@ int main(int argc, char *argv[])
// Run the message pump. // Run the message pump.
return app.exec(); return app.exec();
} }

View File

@ -48,11 +48,11 @@ void createSphereInVolume(RawVolume<uint8_t>& volData, float fRadius)
for (int x = 0; x < volData.getWidth(); x++) for (int x = 0; x < volData.getWidth(); x++)
{ {
//Store our current position as a vector... //Store our current position as a vector...
Vector3DFloat v3dCurrentPos(x,y,z); Vector3DFloat v3dCurrentPos(x, y, z);
//And compute how far the current position is from the center of the volume //And compute how far the current position is from the center of the volume
float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();
if(fDistToCenter <= fRadius) if (fDistToCenter <= fRadius)
{ {
//Our new density value //Our new density value
uint8_t uDensity = std::numeric_limits<uint8_t>::max(); uint8_t uDensity = std::numeric_limits<uint8_t>::max();

View File

@ -10,13 +10,13 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename QOpenGLFunctionsType> template <typename QOpenGLFunctionsType>
OpenGLWidget<QOpenGLFunctionsType>::OpenGLWidget(QWidget *parent) OpenGLWidget<QOpenGLFunctionsType>::OpenGLWidget(QWidget *parent)
:QGLWidget(parent) :QGLWidget(parent)
{ {
} }
template <typename QOpenGLFunctionsType> template <typename QOpenGLFunctionsType>
const QMatrix4x4& OpenGLWidget<QOpenGLFunctionsType>::viewMatrix() const QMatrix4x4& OpenGLWidget<QOpenGLFunctionsType>::viewMatrix()
{ {
return mViewMatrix; return mViewMatrix;
} }
@ -45,22 +45,22 @@ void OpenGLWidget<QOpenGLFunctionsType>::initializeGL()
std::cerr << "Could not initialize OpenGL functions" << std::endl; std::cerr << "Could not initialize OpenGL functions" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
//Print out some information about the OpenGL implementation. //Print out some information about the OpenGL implementation.
std::cout << "OpenGL Implementation Details:" << std::endl; std::cout << "OpenGL Implementation Details:" << std::endl;
if(this->glGetString(GL_VENDOR)) if (this->glGetString(GL_VENDOR))
std::cout << "\tGL_VENDOR: " << this->glGetString(GL_VENDOR) << std::endl; std::cout << "\tGL_VENDOR: " << this->glGetString(GL_VENDOR) << std::endl;
if(this->glGetString(GL_RENDERER)) if (this->glGetString(GL_RENDERER))
std::cout << "\tGL_RENDERER: " << this->glGetString(GL_RENDERER) << std::endl; std::cout << "\tGL_RENDERER: " << this->glGetString(GL_RENDERER) << std::endl;
if(this->glGetString(GL_VERSION)) if (this->glGetString(GL_VERSION))
std::cout << "\tGL_VERSION: " << this->glGetString(GL_VERSION) << std::endl; std::cout << "\tGL_VERSION: " << this->glGetString(GL_VERSION) << std::endl;
if(this->glGetString(GL_SHADING_LANGUAGE_VERSION)) if (this->glGetString(GL_SHADING_LANGUAGE_VERSION))
std::cout << "\tGL_SHADING_LANGUAGE_VERSION: " << this->glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; std::cout << "\tGL_SHADING_LANGUAGE_VERSION: " << this->glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
//Set up the clear colour //Set up the clear colour
this->glClearColor(0.0f, 0.0f, 0.0f, 0.0f); this->glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
this->glClearDepth(1.0f); this->glClearDepth(1.0f);
this->glEnable(GL_DEPTH_TEST); this->glEnable(GL_DEPTH_TEST);
this->glDepthMask(GL_TRUE); this->glDepthMask(GL_TRUE);
this->glDepthFunc(GL_LEQUAL); this->glDepthFunc(GL_LEQUAL);
@ -81,11 +81,11 @@ void OpenGLWidget<QOpenGLFunctionsType>::resizeGL(int w, int h)
{ {
//Setup the viewport //Setup the viewport
this->glViewport(0, 0, w, h); this->glViewport(0, 0, w, h);
auto aspectRatio = w / (float)h; auto aspectRatio = w / (float)h;
float zNear = 1.0; float zNear = 1.0;
float zFar = 1000.0; float zFar = 1000.0;
mProjectionMatrix.setToIdentity(); mProjectionMatrix.setToIdentity();
mProjectionMatrix.perspective(mCameraFOV, aspectRatio, zNear, zFar); mProjectionMatrix.perspective(mCameraFOV, aspectRatio, zNear, zFar);
} }
@ -145,12 +145,12 @@ void OpenGLWidget<QOpenGLFunctionsType>::paintGL()
this->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); this->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderOneFrame(); renderOneFrame();
// Check for errors. // Check for errors.
GLenum errCode = this->glGetError(); GLenum errCode = this->glGetError();
if(errCode != GL_NO_ERROR) if (errCode != GL_NO_ERROR)
{ {
std::cerr << "OpenGL Error: " << errCode << std::endl; std::cerr << "OpenGL Error: " << errCode << std::endl;
} }
} }

View File

@ -97,7 +97,7 @@ namespace PolyVox
{ {
public: public:
AStarPathfinderParams AStarPathfinderParams
( (
VolumeType* volData, VolumeType* volData,
const Vector3DInt32& v3dStart, const Vector3DInt32& v3dStart,
const Vector3DInt32& v3dEnd, const Vector3DInt32& v3dEnd,
@ -105,18 +105,18 @@ namespace PolyVox
float fHBias = 1.0, float fHBias = 1.0,
uint32_t uMaxNoOfNodes = 10000, uint32_t uMaxNoOfNodes = 10000,
Connectivity requiredConnectivity = TwentySixConnected, Connectivity requiredConnectivity = TwentySixConnected,
std::function<bool (const VolumeType*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, std::function<bool(const VolumeType*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator,
std::function<void (float)> funcProgressCallback = nullptr std::function<void(float)> funcProgressCallback = nullptr
) )
:volume(volData) :volume(volData)
,start(v3dStart) , start(v3dStart)
,end(v3dEnd) , end(v3dEnd)
,result(listResult) , result(listResult)
,connectivity(requiredConnectivity) , connectivity(requiredConnectivity)
,hBias(fHBias) , hBias(fHBias)
,maxNumberOfNodes(uMaxNoOfNodes) , maxNumberOfNodes(uMaxNoOfNodes)
,isVoxelValidForPath(funcIsVoxelValidForPath) , isVoxelValidForPath(funcIsVoxelValidForPath)
,progressCallback(funcProgressCallback) , progressCallback(funcProgressCallback)
{ {
} }
@ -125,7 +125,7 @@ namespace PolyVox
/// The start point for the pathfinding algorithm. /// The start point for the pathfinding algorithm.
Vector3DInt32 start; Vector3DInt32 start;
/// The end point for the pathfinding algorithm. /// The end point for the pathfinding algorithm.
Vector3DInt32 end; Vector3DInt32 end;
@ -160,14 +160,14 @@ namespace PolyVox
/// you could check to ensure that the voxel above is empty and the voxel below is solid. /// you could check to ensure that the voxel above is empty and the voxel below is solid.
/// ///
/// \sa aStarDefaultVoxelValidator /// \sa aStarDefaultVoxelValidator
std::function<bool (const VolumeType*, const Vector3DInt32&)> isVoxelValidForPath; std::function<bool(const VolumeType*, const Vector3DInt32&)> isVoxelValidForPath;
/// This function is called by the AStarPathfinder to report on its progress in getting to /// This function is called by the AStarPathfinder to report on its progress in getting to
/// the goal. The progress is reported by computing the distance from the closest node found /// the goal. The progress is reported by computing the distance from the closest node found
/// so far to the end node, and comparing this with the distance from the start node to the /// so far to the end node, and comparing this with the distance from the start node to the
/// end node. This progress value is guarenteed to never decrease, but it may stop increasing /// end node. This progress value is guarenteed to never decrease, but it may stop increasing
///for short periods of time. It may even stop increasing altogether if a path cannot be found. ///for short periods of time. It may even stop increasing altogether if a path cannot be found.
std::function<void (float)> progressCallback; std::function<void(float)> progressCallback;
}; };
/// The AStarPathfinder compute a path from one point in the volume to another. /// The AStarPathfinder compute a path from one point in the volume to another.
@ -218,7 +218,7 @@ namespace PolyVox
//The current node //The current node
AllNodesContainer::iterator current; AllNodesContainer::iterator current;
float m_fProgress; float m_fProgress;
AStarPathfinderParams<VolumeType> m_params; AStarPathfinderParams<VolumeType> m_params;

View File

@ -35,7 +35,7 @@ namespace PolyVox
bool aStarDefaultVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos) bool aStarDefaultVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos)
{ {
//Voxels are considered valid candidates for the path if they are inside the volume... //Voxels are considered valid candidates for the path if they are inside the volume...
if(volData->getEnclosingRegion().containsPoint(v3dPos) == false) if (volData->getEnclosingRegion().containsPoint(v3dPos) == false)
{ {
return false; return false;
} }
@ -83,12 +83,12 @@ namespace PolyVox
float fDistStartToEnd = (endNode->position - startNode->position).length(); float fDistStartToEnd = (endNode->position - startNode->position).length();
m_fProgress = 0.0f; m_fProgress = 0.0f;
if(m_params.progressCallback) if (m_params.progressCallback)
{ {
m_params.progressCallback(m_fProgress); m_params.progressCallback(m_fProgress);
} }
while((openNodes.empty() == false) && (openNodes.getFirst() != endNode)) while ((openNodes.empty() == false) && (openNodes.getFirst() != endNode))
{ {
//Move the first node from open to closed. //Move the first node from open to closed.
current = openNodes.getFirst(); current = openNodes.getFirst();
@ -96,13 +96,13 @@ namespace PolyVox
closedNodes.insert(current); closedNodes.insert(current);
//Update the user on our progress //Update the user on our progress
if(m_params.progressCallback) if (m_params.progressCallback)
{ {
const float fMinProgresIncreament = 0.001f; const float fMinProgresIncreament = 0.001f;
float fDistCurrentToEnd = (endNode->position - current->position).length(); float fDistCurrentToEnd = (endNode->position - current->position).length();
float fDistNormalised = fDistCurrentToEnd / fDistStartToEnd; float fDistNormalised = fDistCurrentToEnd / fDistStartToEnd;
float fProgress = 1.0f - fDistNormalised; float fProgress = 1.0f - fDistNormalised;
if(fProgress >= m_fProgress + fMinProgresIncreament) if (fProgress >= m_fProgress + fMinProgresIncreament)
{ {
m_fProgress = fProgress; m_fProgress = fProgress;
m_params.progressCallback(m_fProgress); m_params.progressCallback(m_fProgress);
@ -116,7 +116,7 @@ namespace PolyVox
//Process the neighbours. Note the deliberate lack of 'break' //Process the neighbours. Note the deliberate lack of 'break'
//statements, larger connectivities include smaller ones. //statements, larger connectivities include smaller ones.
switch(m_params.connectivity) switch (m_params.connectivity)
{ {
case TwentySixConnected: case TwentySixConnected:
processNeighbour(current->position + arrayPathfinderCorners[0], current->gVal + fCornerCost); processNeighbour(current->position + arrayPathfinderCorners[0], current->gVal + fCornerCost);
@ -129,16 +129,16 @@ namespace PolyVox
processNeighbour(current->position + arrayPathfinderCorners[7], current->gVal + fCornerCost); processNeighbour(current->position + arrayPathfinderCorners[7], current->gVal + fCornerCost);
case EighteenConnected: case EighteenConnected:
processNeighbour(current->position + arrayPathfinderEdges[ 0], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[0], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 1], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[1], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 2], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[2], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 3], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[3], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 4], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[4], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 5], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[5], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 6], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[6], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 7], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[7], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 8], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[8], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[ 9], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[9], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[10], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[10], current->gVal + fEdgeCost);
processNeighbour(current->position + arrayPathfinderEdges[11], current->gVal + fEdgeCost); processNeighbour(current->position + arrayPathfinderEdges[11], current->gVal + fEdgeCost);
@ -151,7 +151,7 @@ namespace PolyVox
processNeighbour(current->position + arrayPathfinderFaces[5], current->gVal + fFaceCost); processNeighbour(current->position + arrayPathfinderFaces[5], current->gVal + fFaceCost);
} }
if(allNodes.size() > m_params.maxNumberOfNodes) if (allNodes.size() > m_params.maxNumberOfNodes)
{ {
//We've reached the specified maximum number //We've reached the specified maximum number
//of nodes. Just give up on the search. //of nodes. Just give up on the search.
@ -159,7 +159,7 @@ namespace PolyVox
} }
} }
if((openNodes.empty()) || (openNodes.getFirst() != endNode)) if ((openNodes.empty()) || (openNodes.getFirst() != endNode))
{ {
//In this case we failed to find a valid path. //In this case we failed to find a valid path.
POLYVOX_THROW(std::runtime_error, "No path found"); POLYVOX_THROW(std::runtime_error, "No path found");
@ -172,14 +172,14 @@ namespace PolyVox
//custom sort operator for the set which we know only uses the position to sort. Hence we can safely //custom sort operator for the set which we know only uses the position to sort. Hence we can safely
//modify other properties of the object while it is in the set. //modify other properties of the object while it is in the set.
Node* n = const_cast<Node*>(&(*endNode)); Node* n = const_cast<Node*>(&(*endNode));
while(n != 0) while (n != 0)
{ {
m_params.result->push_front(n->position); m_params.result->push_front(n->position);
n = n->parent; n = n->parent;
} }
} }
if(m_params.progressCallback) if (m_params.progressCallback)
{ {
m_params.progressCallback(1.0f); m_params.progressCallback(1.0f);
} }
@ -189,7 +189,7 @@ namespace PolyVox
void AStarPathfinder<VolumeType>::processNeighbour(const Vector3DInt32& neighbourPos, float neighbourGVal) void AStarPathfinder<VolumeType>::processNeighbour(const Vector3DInt32& neighbourPos, float neighbourGVal)
{ {
bool bIsVoxelValidForPath = m_params.isVoxelValidForPath(m_params.volume, neighbourPos); bool bIsVoxelValidForPath = m_params.isVoxelValidForPath(m_params.volume, neighbourPos);
if(!bIsVoxelValidForPath) if (!bIsVoxelValidForPath)
{ {
return; return;
} }
@ -199,16 +199,16 @@ namespace PolyVox
std::pair<AllNodesContainer::iterator, bool> insertResult = allNodes.insert(Node(neighbourPos.getX(), neighbourPos.getY(), neighbourPos.getZ())); std::pair<AllNodesContainer::iterator, bool> insertResult = allNodes.insert(Node(neighbourPos.getX(), neighbourPos.getY(), neighbourPos.getZ()));
AllNodesContainer::iterator neighbour = insertResult.first; AllNodesContainer::iterator neighbour = insertResult.first;
if(insertResult.second == true) //New node, compute h. if (insertResult.second == true) //New node, compute h.
{ {
Node* tempNeighbour = const_cast<Node*>(&(*neighbour)); Node* tempNeighbour = const_cast<Node*>(&(*neighbour));
tempNeighbour -> hVal = computeH(neighbour->position, m_params.end); tempNeighbour->hVal = computeH(neighbour->position, m_params.end);
} }
OpenNodesContainer::iterator openIter = openNodes.find(neighbour); OpenNodesContainer::iterator openIter = openNodes.find(neighbour);
if(openIter != openNodes.end()) if (openIter != openNodes.end())
{ {
if(cost < neighbour->gVal) if (cost < neighbour->gVal)
{ {
openNodes.remove(openIter); openNodes.remove(openIter);
openIter = openNodes.end(); openIter = openNodes.end();
@ -217,9 +217,9 @@ namespace PolyVox
//TODO - Nodes could keep track of if they are in open or closed? And a pointer to where they are? //TODO - Nodes could keep track of if they are in open or closed? And a pointer to where they are?
ClosedNodesContainer::iterator closedIter = closedNodes.find(neighbour); ClosedNodesContainer::iterator closedIter = closedNodes.find(neighbour);
if(closedIter != closedNodes.end()) if (closedIter != closedNodes.end())
{ {
if(cost < neighbour->gVal) if (cost < neighbour->gVal)
{ {
//Probably shouldn't happen? //Probably shouldn't happen?
closedNodes.remove(closedIter); closedNodes.remove(closedIter);
@ -227,7 +227,7 @@ namespace PolyVox
} }
} }
if((openIter == openNodes.end()) && (closedIter == closedNodes.end())) if ((openIter == openNodes.end()) && (closedIter == closedNodes.end()))
{ {
//Regarding the const_cast - normally you should not modify an object which is in an sdt::set. //Regarding the const_cast - normally you should not modify an object which is in an sdt::set.
//The reason is that objects in a set are stored sorted in a tree so they can be accessed quickly, //The reason is that objects in a set are stored sorted in a tree so they can be accessed quickly,
@ -245,7 +245,7 @@ namespace PolyVox
float AStarPathfinder<VolumeType>::SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b) float AStarPathfinder<VolumeType>::SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b)
{ {
//This is the only heuristic I'm sure of - just use the manhatten distance for the 6-connected case. //This is the only heuristic I'm sure of - just use the manhatten distance for the 6-connected case.
uint32_t faceSteps = std::abs(a.getX()-b.getX()) + std::abs(a.getY()-b.getY()) + std::abs(a.getZ()-b.getZ()); uint32_t faceSteps = std::abs(a.getX() - b.getX()) + std::abs(a.getY() - b.getY()) + std::abs(a.getZ() - b.getZ());
return faceSteps * 1.0f; return faceSteps * 1.0f;
} }
@ -257,7 +257,7 @@ namespace PolyVox
//6-connected case. This means 'h' will be bigger than it should be, resulting in a faster path which may not //6-connected case. This means 'h' will be bigger than it should be, resulting in a faster path which may not
//actually be the shortest one. If you have a correct heuristic for the 18-connected case then please let me know. //actually be the shortest one. If you have a correct heuristic for the 18-connected case then please let me know.
return SixConnectedCost(a,b); return SixConnectedCost(a, b);
} }
template<typename VolumeType> template<typename VolumeType>
@ -269,7 +269,7 @@ namespace PolyVox
array[0] = std::abs(a.getX() - b.getX()); array[0] = std::abs(a.getX() - b.getX());
array[1] = std::abs(a.getY() - b.getY()); array[1] = std::abs(a.getY() - b.getY());
array[2] = std::abs(a.getZ() - b.getZ()); array[2] = std::abs(a.getZ() - b.getZ());
//Maybe this is better implemented directly //Maybe this is better implemented directly
//using three compares and two swaps... but not //using three compares and two swaps... but not
//until the profiler says so. //until the profiler says so.
@ -286,8 +286,8 @@ namespace PolyVox
float AStarPathfinder<VolumeType>::computeH(const Vector3DInt32& a, const Vector3DInt32& b) float AStarPathfinder<VolumeType>::computeH(const Vector3DInt32& a, const Vector3DInt32& b)
{ {
float hVal; float hVal;
switch(m_params.connectivity) switch (m_params.connectivity)
{ {
case TwentySixConnected: case TwentySixConnected:
hVal = TwentySixConnectedCost(a, b); hVal = TwentySixConnectedCost(a, b);
@ -295,7 +295,7 @@ namespace PolyVox
case EighteenConnected: case EighteenConnected:
hVal = EighteenConnectedCost(a, b); hVal = EighteenConnectedCost(a, b);
break; break;
case SixConnected: case SixConnected:
hVal = SixConnectedCost(a, b); hVal = SixConnectedCost(a, b);
break; break;
default: default:
@ -304,9 +304,9 @@ namespace PolyVox
//Sanity checks in debug mode. These can come out eventually, but I //Sanity checks in debug mode. These can come out eventually, but I
//want to make sure that the heuristics I've come up with make sense. //want to make sure that the heuristics I've come up with make sense.
POLYVOX_ASSERT((a-b).length() <= TwentySixConnectedCost(a,b), "A* heuristic error."); POLYVOX_ASSERT((a - b).length() <= TwentySixConnectedCost(a, b), "A* heuristic error.");
POLYVOX_ASSERT(TwentySixConnectedCost(a,b) <= EighteenConnectedCost(a,b), "A* heuristic error."); POLYVOX_ASSERT(TwentySixConnectedCost(a, b) <= EighteenConnectedCost(a, b), "A* heuristic error.");
POLYVOX_ASSERT(EighteenConnectedCost(a,b) <= SixConnectedCost(a,b), "A* heuristic error."); POLYVOX_ASSERT(EighteenConnectedCost(a, b) <= SixConnectedCost(a, b), "A* heuristic error.");
//Apply the bias to the computed h value; //Apply the bias to the computed h value;
hVal *= m_params.hBias; hVal *= m_params.hBias;
@ -323,8 +323,8 @@ namespace PolyVox
//while the other one doesn't - both approaches are valid). For the same reason we want //while the other one doesn't - both approaches are valid). For the same reason we want
//to make sure that position (x,y,z) has a differnt hash from e.g. position (x,z,y). //to make sure that position (x,y,z) has a differnt hash from e.g. position (x,z,y).
uint32_t aX = (a.getX() << 16) & 0x00FF0000; uint32_t aX = (a.getX() << 16) & 0x00FF0000;
uint32_t aY = (a.getY() << 8) & 0x0000FF00; uint32_t aY = (a.getY() << 8) & 0x0000FF00;
uint32_t aZ = (a.getZ() ) & 0x000000FF; uint32_t aZ = (a.getZ()) & 0x000000FF;
uint32_t hashVal = hash(aX | aY | aZ); uint32_t hashVal = hash(aX | aY | aZ);
//Stop hashVal going over 65535, and divide by 1000000 to make sure it is small. //Stop hashVal going over 65535, and divide by 1000000 to make sure it is small.
@ -339,14 +339,14 @@ namespace PolyVox
// Robert Jenkins' 32 bit integer hash function // Robert Jenkins' 32 bit integer hash function
// http://www.burtleburtle.net/bob/hash/integer.html // http://www.burtleburtle.net/bob/hash/integer.html
template<typename VolumeType> template<typename VolumeType>
uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a) uint32_t AStarPathfinder<VolumeType>::hash(uint32_t a)
{ {
a = (a+0x7ed55d16) + (a<<12); a = (a + 0x7ed55d16) + (a << 12);
a = (a^0xc761c23c) ^ (a>>19); a = (a ^ 0xc761c23c) ^ (a >> 19);
a = (a+0x165667b1) + (a<<5); a = (a + 0x165667b1) + (a << 5);
a = (a+0xd3a2646c) ^ (a<<9); a = (a + 0xd3a2646c) ^ (a << 9);
a = (a+0xfd7046c5) + (a<<3); a = (a + 0xfd7046c5) + (a << 3);
a = (a^0xb55a4f09) ^ (a>>16); a = (a ^ 0xb55a4f09) ^ (a >> 16);
return a; return a;
} }
} }

View File

@ -42,10 +42,10 @@ namespace PolyVox
{ {
/** /**
* \file * \file
* *
* Ambient occlusion * Ambient occlusion
*/ */
template<typename VolumeType, typename IsVoxelTransparentCallback> template<typename VolumeType, typename IsVoxelTransparentCallback>
class AmbientOcclusionCalculatorRaycastCallback class AmbientOcclusionCalculatorRaycastCallback
{ {
@ -72,7 +72,7 @@ namespace PolyVox
// This will be 'perfect forwarding' using 'universal references' // This will be 'perfect forwarding' using 'universal references'
// This will require C++11 rvalue references which is why I haven't made the // This will require C++11 rvalue references which is why I haven't made the
// change yet. // change yet.
/// Calculate the ambient occlusion for the volume /// Calculate the ambient occlusion for the volume
template<typename VolumeType, typename IsVoxelTransparentCallback> template<typename VolumeType, typename IsVoxelTransparentCallback>
void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, const Region& region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback); void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, const Region& region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback);

View File

@ -76,14 +76,14 @@ namespace PolyVox
const float fHalfRatioZ = fRatioZ * 0.5f; const float fHalfRatioZ = fRatioZ * 0.5f;
const Vector3DFloat v3dHalfRatio(fHalfRatioX, fHalfRatioY, fHalfRatioZ); const Vector3DFloat v3dHalfRatio(fHalfRatioX, fHalfRatioY, fHalfRatioZ);
const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f); const Vector3DFloat v3dOffset(0.5f, 0.5f, 0.5f);
//This loop iterates over the bottom-lower-left voxel in each of the cells in the output array //This loop iterates over the bottom-lower-left voxel in each of the cells in the output array
for(uint16_t z = region.getLowerZ(); z <= region.getUpperZ(); z += iRatioZ) for (uint16_t z = region.getLowerZ(); z <= region.getUpperZ(); z += iRatioZ)
{ {
for(uint16_t y = region.getLowerY(); y <= region.getUpperY(); y += iRatioY) for (uint16_t y = region.getLowerY(); y <= region.getUpperY(); y += iRatioY)
{ {
for(uint16_t x = region.getLowerX(); x <= region.getUpperX(); x += iRatioX) for (uint16_t x = region.getLowerX(); x <= region.getUpperX(); x += iRatioX)
{ {
//Compute a start position corresponding to //Compute a start position corresponding to
//the centre of the cell in the output array. //the centre of the cell in the output array.
@ -94,8 +94,8 @@ namespace PolyVox
//Keep track of how many rays did not hit anything //Keep track of how many rays did not hit anything
uint8_t uVisibleDirections = 0; uint8_t uVisibleDirections = 0;
for(int ct = 0; ct < uNoOfSamplesPerOutputElement; ct++) for (int ct = 0; ct < uNoOfSamplesPerOutputElement; ct++)
{ {
//We take a random vector with components going from -1 to 1 and scale it to go from -halfRatio to +halfRatio. //We take a random vector with components going from -1 to 1 and scale it to go from -halfRatio to +halfRatio.
//This jitter value moves our sample point from the centre of the array cell to somewhere else in the array cell //This jitter value moves our sample point from the centre of the array cell to somewhere else in the array cell
Vector3DFloat v3dJitter = randomVectors[(uRandomVectorIndex += (++uIndexIncreament)) % 1019]; //Prime number helps avoid repetition on successive loops. Vector3DFloat v3dJitter = randomVectors[(uRandomVectorIndex += (++uIndexIncreament)) % 1019]; //Prime number helps avoid repetition on successive loops.
@ -104,20 +104,20 @@ namespace PolyVox
Vector3DFloat v3dRayDirection = randomUnitVectors[(uRandomUnitVectorIndex += (++uIndexIncreament)) % 1021]; //Different prime number. Vector3DFloat v3dRayDirection = randomUnitVectors[(uRandomUnitVectorIndex += (++uIndexIncreament)) % 1021]; //Different prime number.
v3dRayDirection *= fRayLength; v3dRayDirection *= fRayLength;
AmbientOcclusionCalculatorRaycastCallback<VolumeType, IsVoxelTransparentCallback> ambientOcclusionCalculatorRaycastCallback(isVoxelTransparentCallback); AmbientOcclusionCalculatorRaycastCallback<VolumeType, IsVoxelTransparentCallback> ambientOcclusionCalculatorRaycastCallback(isVoxelTransparentCallback);
RaycastResult result = raycastWithDirection(volInput, v3dRayStart, v3dRayDirection, ambientOcclusionCalculatorRaycastCallback); RaycastResult result = raycastWithDirection(volInput, v3dRayStart, v3dRayDirection, ambientOcclusionCalculatorRaycastCallback);
// Note - The performance of this could actually be improved it we exited as soon // Note - The performance of this could actually be improved it we exited as soon
// as the ray left the volume. The raycast test has an example of how to do this. // as the ray left the volume. The raycast test has an example of how to do this.
if(result == RaycastResults::Completed) if (result == RaycastResults::Completed)
{ {
++uVisibleDirections; ++uVisibleDirections;
} }
} }
float fVisibility; float fVisibility;
if(uNoOfSamplesPerOutputElement == 0) if (uNoOfSamplesPerOutputElement == 0)
{ {
//The user might request zero samples (I've done this in the past while debugging - I don't want to //The user might request zero samples (I've done this in the past while debugging - I don't want to
//wait for ambient occlusion but I do want as valid result for rendering). Avoid the divide by zero. //wait for ambient occlusion but I do want as valid result for rendering). Avoid the divide by zero.

View File

@ -43,7 +43,7 @@ namespace PolyVox
public: public:
typedef _VoxelType VoxelType; typedef _VoxelType VoxelType;
#ifndef SWIG #ifndef SWIG
template <typename DerivedVolumeType> template <typename DerivedVolumeType>
class Sampler class Sampler
{ {
@ -52,7 +52,7 @@ namespace PolyVox
~Sampler(); ~Sampler();
Vector3DInt32 getPosition(void) const; Vector3DInt32 getPosition(void) const;
inline VoxelType getVoxel(void) const; inline VoxelType getVoxel(void) const;
void setPosition(const Vector3DInt32& v3dNewPos); void setPosition(const Vector3DInt32& v3dNewPos);
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
@ -105,7 +105,7 @@ namespace PolyVox
int32_t mYPosInVolume; int32_t mYPosInVolume;
int32_t mZPosInVolume; int32_t mZPosInVolume;
}; };
#endif // SWIG #endif // SWIG
public: public:
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates /// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
@ -121,7 +121,7 @@ namespace PolyVox
/// Calculates approximatly how many bytes of memory the volume is currently using. /// Calculates approximatly how many bytes of memory the volume is currently using.
uint32_t calculateSizeInBytes(void); uint32_t calculateSizeInBytes(void);
protected: protected:
/// Constructor for creating a volume. /// Constructor for creating a volume.
BaseVolume(); BaseVolume();

View File

@ -125,6 +125,6 @@ namespace PolyVox
uint32_t BaseVolume<VoxelType>::calculateSizeInBytes(void) uint32_t BaseVolume<VoxelType>::calculateSizeInBytes(void)
{ {
return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType); return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType);
} }
} }

View File

@ -30,9 +30,9 @@ namespace PolyVox
template <typename DerivedVolumeType> template <typename DerivedVolumeType>
BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::Sampler(DerivedVolumeType* volume) BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::Sampler(DerivedVolumeType* volume)
:mVolume(volume) :mVolume(volume)
,mXPosInVolume(0) , mXPosInVolume(0)
,mYPosInVolume(0) , mYPosInVolume(0)
,mZPosInVolume(0) , mZPosInVolume(0)
{ {
} }

View File

@ -215,17 +215,17 @@ namespace PolyVox
POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox"); POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox");
return -1; //Should never happen. return -1; //Should never happen.
} }
/// Do not use this class directly. Use the 'extractCubicSurface' function instead (see examples). /// Do not use this class directly. Use the 'extractCubicSurface' function instead (see examples).
template<typename VolumeType, typename MeshType, typename IsQuadNeeded> template<typename VolumeType, typename MeshType, typename IsQuadNeeded>
class CubicSurfaceExtractor class CubicSurfaceExtractor
{ {
public: public:
CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true); CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true);
private: private:
}; };
// This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically. // This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically.

View File

@ -37,7 +37,7 @@ namespace PolyVox
public: public:
bool operator()(VoxelType back, VoxelType front, VoxelType& materialToUse) bool operator()(VoxelType back, VoxelType front, VoxelType& materialToUse)
{ {
if((back > 0) && (front == 0)) if ((back > 0) && (front == 0))
{ {
materialToUse = static_cast<VoxelType>(back); materialToUse = static_cast<VoxelType>(back);
return true; return true;

View File

@ -39,25 +39,25 @@ namespace PolyVox
* type to be used. However, the Marching Cubes algorithm does have some requirents about the underlying data in that conceptually it operates * type to be used. However, the Marching Cubes algorithm does have some requirents about the underlying data in that conceptually it operates
* on a <i>density field</i>. In addition, the PolyVox implementation of the Marching Cubes algorithm also understands the idea of each voxel * on a <i>density field</i>. In addition, the PolyVox implementation of the Marching Cubes algorithm also understands the idea of each voxel
* having a material which is copied into the vertex data. * having a material which is copied into the vertex data.
* *
* Because we want the MarchingCubesSurfaceExtractor to work on <i>any</i> voxel type, we use a <i>Marching Cubes controller</i> (passed as * Because we want the MarchingCubesSurfaceExtractor to work on <i>any</i> voxel type, we use a <i>Marching Cubes controller</i> (passed as
* a parameter of the MarchingCubesSurfaceExtractor) to expose the required properties. This parameter defaults to the DefaultMarchingCubesController. * a parameter of the MarchingCubesSurfaceExtractor) to expose the required properties. This parameter defaults to the DefaultMarchingCubesController.
* The main implementation of this class is designed to work with primitives data types, and the class is also specialised for the Material, * The main implementation of this class is designed to work with primitives data types, and the class is also specialised for the Material,
* Density and MaterialdensityPair classes. * Density and MaterialdensityPair classes.
* *
* If you create a custom class for your voxel data then you probably want to include a specialisation of DefaultMarchingCubesController, * If you create a custom class for your voxel data then you probably want to include a specialisation of DefaultMarchingCubesController,
* though you don't have to if you don't want to use the Marching Cubes algorithm or if you prefer to define a seperate Marching Cubes controller * though you don't have to if you don't want to use the Marching Cubes algorithm or if you prefer to define a seperate Marching Cubes controller
* and pass it as an explicit parameter (rather than relying on the default). * and pass it as an explicit parameter (rather than relying on the default).
* *
* For primitive types, the DefaultMarchingCubesController considers the value of the voxel to represent it's density and just returns a constant * For primitive types, the DefaultMarchingCubesController considers the value of the voxel to represent it's density and just returns a constant
* for the material. So you can, for example, run the MarchingCubesSurfaceExtractor on a volume of floats or ints. * for the material. So you can, for example, run the MarchingCubesSurfaceExtractor on a volume of floats or ints.
* *
* It is possible to customise the behaviour of the controller by providing a threshold value through the constructor. The extracted surface * It is possible to customise the behaviour of the controller by providing a threshold value through the constructor. The extracted surface
* will pass through the density value specified by the threshold, and so you should make sure that the threshold value you choose is between * will pass through the density value specified by the threshold, and so you should make sure that the threshold value you choose is between
* the minimum and maximum values found in your volume data. By default it is in the middle of the representable range of the underlying type. * the minimum and maximum values found in your volume data. By default it is in the middle of the representable range of the underlying type.
* *
* \sa MarchingCubesSurfaceExtractor * \sa MarchingCubesSurfaceExtractor
* *
*/ */
template<typename VoxelType> template<typename VoxelType>
class DefaultMarchingCubesController class DefaultMarchingCubesController
@ -76,7 +76,7 @@ namespace PolyVox
* if the voxel type is 'float' then the representable range is -FLT_MAX to FLT_MAX and the threshold will be set to zero. * if the voxel type is 'float' then the representable range is -FLT_MAX to FLT_MAX and the threshold will be set to zero.
*/ */
DefaultMarchingCubesController(void) DefaultMarchingCubesController(void)
{ {
if (std::is_signed<DensityType>()) if (std::is_signed<DensityType>())
{ {
m_tThreshold = DensityType(0); m_tThreshold = DensityType(0);
@ -119,7 +119,7 @@ namespace PolyVox
*/ */
MaterialType blendMaterials(VoxelType a, VoxelType b, float /*weight*/) MaterialType blendMaterials(VoxelType a, VoxelType b, float /*weight*/)
{ {
if(convertToDensity(a) > convertToDensity(b)) if (convertToDensity(a) > convertToDensity(b))
{ {
return convertToMaterial(a); return convertToMaterial(a);
} }

View File

@ -93,13 +93,13 @@ namespace PolyVox
Type getDensity() const { return m_uDensity; } Type getDensity() const { return m_uDensity; }
/** /**
* Set the density of the voxel * Set the density of the voxel
* *
* \param uDensity The density to set to * \param uDensity The density to set to
*/ */
void setDensity(Type uDensity) { m_uDensity = uDensity; } void setDensity(Type uDensity) { m_uDensity = uDensity; }
/// \return The maximum allowed density of the voxel /// \return The maximum allowed density of the voxel
static Type getMaxDensity() { return (std::numeric_limits<Type>::max)(); } static Type getMaxDensity() { return (std::numeric_limits<Type>::max)(); }
/// \return The minimum allowed density of the voxel /// \return The minimum allowed density of the voxel
static Type getMinDensity() { return (std::numeric_limits<Type>::min)(); } static Type getMinDensity() { return (std::numeric_limits<Type>::min)(); }
@ -175,7 +175,7 @@ namespace PolyVox
} }
DensityType getThreshold(void) DensityType getThreshold(void)
{ {
return m_tThreshold; return m_tThreshold;
} }

View File

@ -49,26 +49,26 @@ namespace PolyVox
/// Constructor /// Constructor
FilePager(const std::string& strFolderName = ".") FilePager(const std::string& strFolderName = ".")
:PagedVolume<VoxelType>::Pager() :PagedVolume<VoxelType>::Pager()
,m_strFolderName(strFolderName) , m_strFolderName(strFolderName)
{ {
// Add the trailing slash, assuming the user dind't already do it. // Add the trailing slash, assuming the user dind't already do it.
if ((m_strFolderName.back() != '/') && (m_strFolderName.back() != '\\')) if ((m_strFolderName.back() != '/') && (m_strFolderName.back() != '\\'))
{ {
m_strFolderName.append("/"); m_strFolderName.append("/");
} }
// Build a unique postfix to avoid filename conflicts between multiple pagers/runs. // Build a unique postfix to avoid filename conflicts between multiple pagers/runs.
// Not a very robust solution but this class is meant as an example for testing really. // Not a very robust solution but this class is meant as an example for testing really.
std::stringstream ss; std::stringstream ss;
ss << time(0) << "--"; // Avoid multiple runs using the same filenames. ss << time(0) << "--"; // Avoid multiple runs using the same filenames.
ss << this; // Avoid multiple FilePagers using the same filenames. ss << this; // Avoid multiple FilePagers using the same filenames.
m_strPostfix = ss.str(); m_strPostfix = ss.str();
} }
/// Destructor /// Destructor
virtual ~FilePager() virtual ~FilePager()
{ {
for(std::vector<std::string>::iterator iter = m_vecCreatedFiles.begin(); iter < m_vecCreatedFiles.end(); iter++) for (std::vector<std::string>::iterator iter = m_vecCreatedFiles.begin(); iter < m_vecCreatedFiles.end(); iter++)
{ {
POLYVOX_LOG_WARNING_IF(std::remove(iter->c_str()) != 0, "Failed to delete '", *iter, "' when destroying FilePager"); POLYVOX_LOG_WARNING_IF(std::remove(iter->c_str()) != 0, "Failed to delete '", *iter, "' when destroying FilePager");
} }
@ -84,8 +84,8 @@ namespace PolyVox
std::stringstream ssFilename; std::stringstream ssFilename;
ssFilename << m_strFolderName << "/" ssFilename << m_strFolderName << "/"
<< region.getLowerX() << "_" << region.getLowerY() << "_" << region.getLowerZ() << "_" << region.getLowerX() << "_" << region.getLowerY() << "_" << region.getLowerZ() << "_"
<< region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ() << region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ()
<< "--" << m_strPostfix; << "--" << m_strPostfix;
std::string filename = ssFilename.str(); std::string filename = ssFilename.str();
@ -93,14 +93,14 @@ namespace PolyVox
// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919 // the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919
FILE* pFile = fopen(filename.c_str(), "rb"); FILE* pFile = fopen(filename.c_str(), "rb");
if(pFile) if (pFile)
{ {
POLYVOX_LOG_TRACE("Paging in data for ", region); POLYVOX_LOG_TRACE("Paging in data for ", region);
/*fseek(pFile, 0L, SEEK_END); /*fseek(pFile, 0L, SEEK_END);
size_t fileSizeInBytes = ftell(pFile); size_t fileSizeInBytes = ftell(pFile);
fseek(pFile, 0L, SEEK_SET); fseek(pFile, 0L, SEEK_SET);
uint8_t* buffer = new uint8_t[fileSizeInBytes]; uint8_t* buffer = new uint8_t[fileSizeInBytes];
fread(buffer, sizeof(uint8_t), fileSizeInBytes, pFile); fread(buffer, sizeof(uint8_t), fileSizeInBytes, pFile);
pChunk->setData(buffer, fileSizeInBytes); pChunk->setData(buffer, fileSizeInBytes);
@ -108,7 +108,7 @@ namespace PolyVox
fread(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile); fread(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile);
if(ferror(pFile)) if (ferror(pFile))
{ {
POLYVOX_THROW(std::runtime_error, "Error reading in chunk data, even though a file exists."); POLYVOX_THROW(std::runtime_error, "Error reading in chunk data, even though a file exists.");
} }
@ -145,7 +145,7 @@ namespace PolyVox
// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919 // the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919
FILE* pFile = fopen(filename.c_str(), "wb"); FILE* pFile = fopen(filename.c_str(), "wb");
if(!pFile) if (!pFile)
{ {
POLYVOX_THROW(std::runtime_error, "Unable to open file to write out chunk data."); POLYVOX_THROW(std::runtime_error, "Unable to open file to write out chunk data.");
} }
@ -155,7 +155,7 @@ namespace PolyVox
fwrite(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile); fwrite(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile);
if(ferror(pFile)) if (ferror(pFile))
{ {
POLYVOX_THROW(std::runtime_error, "Error writing out chunk data."); POLYVOX_THROW(std::runtime_error, "Error writing out chunk data.");
} }

View File

@ -53,8 +53,8 @@ namespace PolyVox
{ {
Node(int x, int y, int z) Node(int x, int y, int z)
:gVal(std::numeric_limits<float>::quiet_NaN()) //Initilise with NaNs so that we will :gVal(std::numeric_limits<float>::quiet_NaN()) //Initilise with NaNs so that we will
,hVal(std::numeric_limits<float>::quiet_NaN()) //know if we forget to set these properly. , hVal(std::numeric_limits<float>::quiet_NaN()) //know if we forget to set these properly.
,parent(0) , parent(0)
{ {
position.setX(x); position.setX(x);
position.setY(y); position.setY(y);

View File

@ -141,19 +141,19 @@ namespace PolyVox
/*inline uint32_t convertCoordinates(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) /*inline uint32_t convertCoordinates(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos)
{ {
uint64_t answer = 0; uint64_t answer = 0;
answer = morton256_z[(uZPos >> 16) & 0xFF] | // we start by shifting the third byte, since we only look at the first 21 bits answer = morton256_z[(uZPos >> 16) & 0xFF] | // we start by shifting the third byte, since we only look at the first 21 bits
morton256_y[(uYPos >> 16) & 0xFF] | morton256_y[(uYPos >> 16) & 0xFF] |
morton256_x[(uXPos >> 16) & 0xFF]; morton256_x[(uXPos >> 16) & 0xFF];
answer = answer << 48 | answer = answer << 48 |
morton256_z[(uZPos >> 8) & 0xFF] | // shifting second byte morton256_z[(uZPos >> 8) & 0xFF] | // shifting second byte
morton256_y[(uYPos >> 8) & 0xFF] | morton256_y[(uYPos >> 8) & 0xFF] |
morton256_x[(uXPos >> 8) & 0xFF]; morton256_x[(uXPos >> 8) & 0xFF];
answer = answer << 24 | answer = answer << 24 |
morton256_z[(uZPos)& 0xFF] | // first byte morton256_z[(uZPos)& 0xFF] | // first byte
morton256_y[(uYPos)& 0xFF] | morton256_y[(uYPos)& 0xFF] |
morton256_x[(uXPos)& 0xFF]; morton256_x[(uXPos)& 0xFF];
return answer; return answer;
}*/ }*/
} }

View File

@ -30,7 +30,7 @@
#include "PolyVox/Vector.h" #include "PolyVox/Vector.h"
namespace PolyVox namespace PolyVox
{ {
const Vector3DFloat randomUnitVectors[1024] = const Vector3DFloat randomUnitVectors[1024] =
{ {
Vector3DFloat(+0.339922f, +0.827727f, -0.446454f), Vector3DFloat(+0.339922f, +0.827727f, -0.446454f),

View File

@ -30,7 +30,7 @@
#include "PolyVox/Vector.h" #include "PolyVox/Vector.h"
namespace PolyVox namespace PolyVox
{ {
const Vector3DFloat randomVectors[1024] = const Vector3DFloat randomVectors[1024] =
{ {
Vector3DFloat(+0.348918f, -0.385662f, +0.650197f), Vector3DFloat(+0.348918f, -0.385662f, +0.650197f),

View File

@ -41,12 +41,12 @@ namespace PolyVox
start(); start();
} }
} }
void start(void) void start(void)
{ {
m_start = clock::now(); m_start = clock::now();
} }
float elapsedTimeInSeconds(void) float elapsedTimeInSeconds(void)
{ {
std::chrono::duration<float> elapsed_seconds = clock::now() - m_start; std::chrono::duration<float> elapsed_seconds = clock::now() - m_start;
@ -64,7 +64,7 @@ namespace PolyVox
std::chrono::duration<float, std::micro> elapsed_microseconds = clock::now() - m_start; std::chrono::duration<float, std::micro> elapsed_microseconds = clock::now() - m_start;
return elapsed_microseconds.count(); return elapsed_microseconds.count();
} }
private: private:
typedef std::chrono::system_clock clock; typedef std::chrono::system_clock clock;
std::chrono::time_point<clock> m_start; std::chrono::time_point<clock> m_start;

View File

@ -29,20 +29,20 @@ namespace PolyVox
{ {
template <typename Type> template <typename Type>
Type lerp( Type lerp(
const Type& v0,const Type& v1, const Type& v0, const Type& v1,
const float x) const float x)
{ {
//Interpolate along X //Interpolate along X
Type v0_1 = (v1 - v0) * x + v0; Type v0_1 = (v1 - v0) * x + v0;
return v0_1; return v0_1;
} }
template <typename Type> template <typename Type>
Type bilerp( Type bilerp(
const Type& v00,const Type& v10,const Type& v01,const Type& v11, const Type& v00, const Type& v10, const Type& v01, const Type& v11,
const float x, const float y) const float x, const float y)
{ {
// Linearly interpolate along x // Linearly interpolate along x
Type v00_10 = lerp(v00, v10, x); Type v00_10 = lerp(v00, v10, x);
Type v01_11 = lerp(v01, v11, x); Type v01_11 = lerp(v01, v11, x);
@ -51,23 +51,23 @@ namespace PolyVox
Type v00_10__v01_11 = lerp(v00_10, v01_11, y); Type v00_10__v01_11 = lerp(v00_10, v01_11, y);
return v00_10__v01_11; return v00_10__v01_11;
} }
template <typename Type> template <typename Type>
Type trilerp( Type trilerp(
const Type& v000,const Type& v100,const Type& v010,const Type& v110, const Type& v000, const Type& v100, const Type& v010, const Type& v110,
const Type& v001,const Type& v101,const Type& v011,const Type& v111, const Type& v001, const Type& v101, const Type& v011, const Type& v111,
const float x, const float y, const float z) const float x, const float y, const float z)
{ {
// Bilinearly interpolate along Y // Bilinearly interpolate along Y
Type v000_v100__v010_v110 = bilerp(v000, v100, v010, v110, x, y); Type v000_v100__v010_v110 = bilerp(v000, v100, v010, v110, x, y);
Type v001_v101__v011_v111 = bilerp(v001, v101, v011, v111, x, y); Type v001_v101__v011_v111 = bilerp(v001, v101, v011, v111, x, y);
// And linearly interpolate the results along z // And linearly interpolate the results along z
Type v000_v100__v010_v110____v001_v101__v011_v111 = lerp(v000_v100__v010_v110, v001_v101__v011_v111, z); Type v000_v100__v010_v110____v001_v101__v011_v111 = lerp(v000_v100__v010_v110, v001_v101__v011_v111, z);
return v000_v100__v010_v110____v001_v101__v011_v111; return v000_v100__v010_v110____v001_v101__v011_v111;
} }
} }
#endif //__PolyVox_Interpolation_H__ #endif //__PolyVox_Interpolation_H__

View File

@ -35,7 +35,7 @@ namespace PolyVox
{ {
Vector3DInt32 v3dInitialPosition(m_Iter->getPosition().getX(), m_Iter->getPosition().getY(), m_Iter->getPosition().getZ()); Vector3DInt32 v3dInitialPosition(m_Iter->getPosition().getX(), m_Iter->getPosition().getY(), m_Iter->getPosition().getZ());
if(v3dInitialPosition.getX() < m_regValid.getUpperX()) if (v3dInitialPosition.getX() < m_regValid.getUpperX())
{ {
m_Iter->movePositiveX(); m_Iter->movePositiveX();
return true; return true;
@ -43,7 +43,7 @@ namespace PolyVox
v3dInitialPosition.setX(m_regValid.getLowerX()); v3dInitialPosition.setX(m_regValid.getLowerX());
if(v3dInitialPosition.getY() < m_regValid.getUpperY()) if (v3dInitialPosition.getY() < m_regValid.getUpperY())
{ {
v3dInitialPosition.setY(v3dInitialPosition.getY() + 1); v3dInitialPosition.setY(v3dInitialPosition.getY() + 1);
m_Iter->setPosition(v3dInitialPosition); m_Iter->setPosition(v3dInitialPosition);
@ -52,7 +52,7 @@ namespace PolyVox
v3dInitialPosition.setY(m_regValid.getLowerY()); v3dInitialPosition.setY(m_regValid.getLowerY());
if(v3dInitialPosition.getZ() < m_regValid.getUpperZ()) if (v3dInitialPosition.getZ() < m_regValid.getUpperZ())
{ {
v3dInitialPosition.setZ(v3dInitialPosition.getZ() + 1); v3dInitialPosition.setZ(v3dInitialPosition.getZ() + 1);
m_Iter->setPosition(v3dInitialPosition); m_Iter->setPosition(v3dInitialPosition);

View File

@ -34,19 +34,19 @@ namespace PolyVox
template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType>
LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::LowPassFilter(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst, uint32_t uKernelSize) LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::LowPassFilter(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst, uint32_t uKernelSize)
:m_pVolSrc(pVolSrc) :m_pVolSrc(pVolSrc)
,m_regSrc(regSrc) , m_regSrc(regSrc)
,m_pVolDst(pVolDst) , m_pVolDst(pVolDst)
,m_regDst(regDst) , m_regDst(regDst)
,m_uKernelSize(uKernelSize) , m_uKernelSize(uKernelSize)
{ {
//Kernel size must be at least three //Kernel size must be at least three
if(m_uKernelSize < 3) if (m_uKernelSize < 3)
{ {
POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three"); POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three");
} }
//Kernel size must be odd //Kernel size must be odd
if(m_uKernelSize % 2 == 0) if (m_uKernelSize % 2 == 0)
{ {
POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd"); POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd");
} }
@ -73,11 +73,11 @@ namespace PolyVox
typename SrcVolumeType::Sampler srcSampler(m_pVolSrc); typename SrcVolumeType::Sampler srcSampler(m_pVolSrc);
for(int32_t iSrcZ = iSrcMinZ, iDstZ = iDstMinZ; iSrcZ <= iSrcMaxZ; iSrcZ++, iDstZ++) for (int32_t iSrcZ = iSrcMinZ, iDstZ = iDstMinZ; iSrcZ <= iSrcMaxZ; iSrcZ++, iDstZ++)
{ {
for(int32_t iSrcY = iSrcMinY, iDstY = iDstMinY; iSrcY <= iSrcMaxY; iSrcY++, iDstY++) for (int32_t iSrcY = iSrcMinY, iDstY = iDstMinY; iSrcY <= iSrcMaxY; iSrcY++, iDstY++)
{ {
for(int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++) for (int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++)
{ {
AccumulationType tSrcVoxel(0); AccumulationType tSrcVoxel(0);
srcSampler.setPosition(iSrcX, iSrcY, iSrcZ); srcSampler.setPosition(iSrcX, iSrcY, iSrcZ);
@ -136,13 +136,13 @@ namespace PolyVox
//Clear to zeros (necessary?) //Clear to zeros (necessary?)
//FIXME - use Volume::fill() method. Implemented in base class as below //FIXME - use Volume::fill() method. Implemented in base class as below
//but with optimised implementations in subclasses? //but with optimised implementations in subclasses?
for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
{ {
for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
{ {
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{ {
satVolume.setVoxel(x,y,z,0); satVolume.setVoxel(x, y, z, 0);
} }
} }
} }
@ -170,47 +170,47 @@ namespace PolyVox
srcIterCont.moveForward(); srcIterCont.moveForward();
}while(satIterCont.moveForward()); } while (satIterCont.moveForward());
//Build SAT in three passes //Build SAT in three passes
/*for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) /*for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
{ {
for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
{ {
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{ {
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x-1,y,z)); AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x-1,y,z));
AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxel(x,y,z)); AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxel(x,y,z));
satVolume.setVoxel(x,y,z,previousSum + currentVal); satVolume.setVoxel(x,y,z,previousSum + currentVal);
} }
} }
}*/ }*/
for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
{ {
for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
{ {
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{ {
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z)); AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y - 1, z));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z)); AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z));
satVolume.setVoxel(x,y,z,previousSum + currentSum); satVolume.setVoxel(x, y, z, previousSum + currentSum);
} }
} }
} }
for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
{ {
for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
{ {
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
{ {
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1)); AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z - 1));
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z)); AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z));
satVolume.setVoxel(x,y,z,previousSum + currentSum); satVolume.setVoxel(x, y, z, previousSum + currentSum);
} }
} }
} }
@ -221,11 +221,11 @@ namespace PolyVox
const Vector3DInt32& v3dSrcLowerCorner = m_regSrc.getLowerCorner(); const Vector3DInt32& v3dSrcLowerCorner = m_regSrc.getLowerCorner();
for(int32_t iDstZ = v3dDstLowerCorner.getZ(), iSrcZ = v3dSrcLowerCorner.getZ(); iDstZ <= v3dDstUpperCorner.getZ(); iDstZ++, iSrcZ++) for (int32_t iDstZ = v3dDstLowerCorner.getZ(), iSrcZ = v3dSrcLowerCorner.getZ(); iDstZ <= v3dDstUpperCorner.getZ(); iDstZ++, iSrcZ++)
{ {
for(int32_t iDstY = v3dDstLowerCorner.getY(), iSrcY = v3dSrcLowerCorner.getY(); iDstY <= v3dDstUpperCorner.getY(); iDstY++, iSrcY++) for (int32_t iDstY = v3dDstLowerCorner.getY(), iSrcY = v3dSrcLowerCorner.getY(); iDstY <= v3dDstUpperCorner.getY(); iDstY++, iSrcY++)
{ {
for(int32_t iDstX = v3dDstLowerCorner.getX(), iSrcX = v3dSrcLowerCorner.getX(); iDstX <= v3dDstUpperCorner.getX(); iDstX++, iSrcX++) for (int32_t iDstX = v3dDstLowerCorner.getX(), iSrcX = v3dSrcLowerCorner.getX(); iDstX <= v3dDstUpperCorner.getX(); iDstX++, iSrcX++)
{ {
int32_t satLowerX = iSrcX - border - 1; int32_t satLowerX = iSrcX - border - 1;
int32_t satLowerY = iSrcY - border - 1; int32_t satLowerY = iSrcY - border - 1;
@ -235,16 +235,16 @@ namespace PolyVox
int32_t satUpperY = iSrcY + border; int32_t satUpperY = iSrcY + border;
int32_t satUpperZ = iSrcZ + border; int32_t satUpperZ = iSrcZ + border;
AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ); AccumulationType a = satVolume.getVoxel(satLowerX, satLowerY, satLowerZ);
AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ); AccumulationType b = satVolume.getVoxel(satUpperX, satLowerY, satLowerZ);
AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ); AccumulationType c = satVolume.getVoxel(satLowerX, satUpperY, satLowerZ);
AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ); AccumulationType d = satVolume.getVoxel(satUpperX, satUpperY, satLowerZ);
AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ); AccumulationType e = satVolume.getVoxel(satLowerX, satLowerY, satUpperZ);
AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ); AccumulationType f = satVolume.getVoxel(satUpperX, satLowerY, satUpperZ);
AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ); AccumulationType g = satVolume.getVoxel(satLowerX, satUpperY, satUpperZ);
AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ); AccumulationType h = satVolume.getVoxel(satUpperX, satUpperY, satUpperZ);
AccumulationType sum = h+c-d-g-f-a+b+e; AccumulationType sum = h + c - d - g - f - a + b + e;
uint32_t sideLength = border * 2 + 1; uint32_t sideLength = border * 2 + 1;
AccumulationType average = sum / (sideLength*sideLength*sideLength); AccumulationType average = sum / (sideLength*sideLength*sideLength);

View File

@ -112,7 +112,7 @@ namespace PolyVox
{ {
// Extract the two bytes from the uint16_t. // Extract the two bytes from the uint16_t.
uint16_t ux = (encodedNormal >> 8) & 0xFF; uint16_t ux = (encodedNormal >> 8) & 0xFF;
uint16_t uy = (encodedNormal ) & 0xFF; uint16_t uy = (encodedNormal)& 0xFF;
// Convert to floats in the range [-1.0f, +1.0f]. // Convert to floats in the range [-1.0f, +1.0f].
float ex = ux / 127.5f - 1.0f; float ex = ux / 127.5f - 1.0f;

View File

@ -142,7 +142,7 @@ namespace PolyVox
template< typename VolumeType, typename MeshType, typename ControllerType > template< typename VolumeType, typename MeshType, typename ControllerType >
void extractMarchingCubesMeshCustom(VolumeType* volData, Region region, MeshType* result, ControllerType controller) void extractMarchingCubesMeshCustom(VolumeType* volData, Region region, MeshType* result, ControllerType controller)
{ {
// Validate parameters // Validate parameters
POLYVOX_THROW_IF(volData == nullptr, std::invalid_argument, "Provided volume cannot be null"); POLYVOX_THROW_IF(volData == nullptr, std::invalid_argument, "Provided volume cannot be null");
POLYVOX_THROW_IF(result == nullptr, std::invalid_argument, "Provided mesh cannot be null"); POLYVOX_THROW_IF(result == nullptr, std::invalid_argument, "Provided mesh cannot be null");
@ -161,7 +161,7 @@ namespace PolyVox
const uint32_t uRegionHeightInVoxels = region.getHeightInVoxels(); const uint32_t uRegionHeightInVoxels = region.getHeightInVoxels();
const uint32_t uRegionDepthInVoxels = region.getDepthInVoxels(); const uint32_t uRegionDepthInVoxels = region.getDepthInVoxels();
typename ControllerType::DensityType tThreshold = controller.getThreshold(); typename ControllerType::DensityType tThreshold = controller.getThreshold();
// A naive implemetation of Marching Cubes might sample the eight corner voxels of every cell to determine the cell index. // A naive implemetation of Marching Cubes might sample the eight corner voxels of every cell to determine the cell index.
// However, when processing the cells sequentially we cn observe that many of the voxels are shared with previous adjacent // However, when processing the cells sequentially we cn observe that many of the voxels are shared with previous adjacent
@ -456,5 +456,5 @@ namespace PolyVox
POLYVOX_LOG_TRACE("Marching cubes surface extraction took ", timer.elapsedTimeInMilliSeconds(), POLYVOX_LOG_TRACE("Marching cubes surface extraction took ", timer.elapsedTimeInMilliSeconds(),
"ms (Region size = ", region.getWidthInVoxels(), "x", region.getHeightInVoxels(), "ms (Region size = ", region.getWidthInVoxels(), "x", region.getHeightInVoxels(),
"x", region.getDepthInVoxels(), ")"); "x", region.getDepthInVoxels(), ")");
} }
} }

View File

@ -58,7 +58,7 @@ namespace PolyVox
Type getMaterial() const { return m_uMaterial; } Type getMaterial() const { return m_uMaterial; }
/** /**
* Set the material value of the voxel * Set the material value of the voxel
* *
* \param uMaterial The material to set to * \param uMaterial The material to set to
*/ */
void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; } void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; }
@ -76,7 +76,7 @@ namespace PolyVox
public: public:
bool operator()(Material<Type> back, Material<Type> front, Material<Type>& materialToUse) bool operator()(Material<Type> back, Material<Type> front, Material<Type>& materialToUse)
{ {
if((back.getMaterial() > 0) && (front.getMaterial() == 0)) if ((back.getMaterial() > 0) && (front.getMaterial() == 0))
{ {
materialToUse = back; materialToUse = back;
return true; return true;

View File

@ -93,7 +93,7 @@ namespace PolyVox
public: public:
bool operator()(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> back, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> front, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits>& materialToUse) bool operator()(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> back, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> front, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits>& materialToUse)
{ {
if((back.getMaterial() > 0) && (front.getMaterial() == 0)) if ((back.getMaterial() > 0) && (front.getMaterial() == 0))
{ {
materialToUse = back; materialToUse = back;
return true; return true;
@ -135,7 +135,7 @@ namespace PolyVox
MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> blendMaterials(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> a, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> b, float /*weight*/) MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> blendMaterials(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> a, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> b, float /*weight*/)
{ {
if(convertToDensity(a) > convertToDensity(b)) if (convertToDensity(a) > convertToDensity(b))
{ {
return a; return a;
} }
@ -146,7 +146,7 @@ namespace PolyVox
} }
DensityType getThreshold(void) DensityType getThreshold(void)
{ {
return m_tThreshold; return m_tThreshold;
} }

View File

@ -49,7 +49,7 @@ namespace PolyVox
typedef _IndexType IndexType; typedef _IndexType IndexType;
Mesh(); Mesh();
~Mesh(); ~Mesh();
IndexType getNoOfVertices(void) const; IndexType getNoOfVertices(void) const;
const VertexType& getVertex(IndexType index) const; const VertexType& getVertex(IndexType index) const;
@ -69,9 +69,9 @@ namespace PolyVox
void clear(void); void clear(void);
bool isEmpty(void) const; bool isEmpty(void) const;
void removeUnusedVertices(void); void removeUnusedVertices(void);
private: private:
std::vector<IndexType> m_vecIndices; std::vector<IndexType> m_vecIndices;
std::vector<VertexType> m_vecVertices; std::vector<VertexType> m_vecVertices;
Vector3DInt32 m_offset; Vector3DInt32 m_offset;

View File

@ -30,7 +30,7 @@ namespace PolyVox
} }
template <typename VertexType, typename IndexType> template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>::~Mesh() Mesh<VertexType, IndexType>::~Mesh()
{ {
} }
@ -136,7 +136,7 @@ namespace PolyVox
std::vector<bool> isVertexUsed(m_vecVertices.size()); std::vector<bool> isVertexUsed(m_vecVertices.size());
std::fill(isVertexUsed.begin(), isVertexUsed.end(), false); std::fill(isVertexUsed.begin(), isVertexUsed.end(), false);
for(uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) for (uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++)
{ {
int v = m_vecIndices[triCt]; int v = m_vecIndices[triCt];
isVertexUsed[v] = true; isVertexUsed[v] = true;
@ -144,9 +144,9 @@ namespace PolyVox
int noOfUsedVertices = 0; int noOfUsedVertices = 0;
std::vector<uint32_t> newPos(m_vecVertices.size()); std::vector<uint32_t> newPos(m_vecVertices.size());
for(IndexType vertCt = 0; vertCt < m_vecVertices.size(); vertCt++) for (IndexType vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
{ {
if(isVertexUsed[vertCt]) if (isVertexUsed[vertCt])
{ {
m_vecVertices[noOfUsedVertices] = m_vecVertices[vertCt]; m_vecVertices[noOfUsedVertices] = m_vecVertices[vertCt];
newPos[vertCt] = noOfUsedVertices; newPos[vertCt] = noOfUsedVertices;
@ -156,7 +156,7 @@ namespace PolyVox
m_vecVertices.resize(noOfUsedVertices); m_vecVertices.resize(noOfUsedVertices);
for(uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) for (uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++)
{ {
m_vecIndices[triCt] = newPos[m_vecIndices[triCt]]; m_vecIndices[triCt] = newPos[m_vecIndices[triCt]];
} }

View File

@ -187,7 +187,7 @@ namespace PolyVox
//in the future //in the future
//typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. //typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences.
//class Sampler : public VolumeOfVoxelType::template Sampler< PagedVolume<VoxelType> > //class Sampler : public VolumeOfVoxelType::template Sampler< PagedVolume<VoxelType> >
#ifndef SWIG #ifndef SWIG
#if defined(_MSC_VER) #if defined(_MSC_VER)
class Sampler : public BaseVolume<VoxelType>::Sampler< PagedVolume<VoxelType> > //This line works on VS2010 class Sampler : public BaseVolume<VoxelType>::Sampler< PagedVolume<VoxelType> > //This line works on VS2010
#else #else
@ -198,7 +198,7 @@ namespace PolyVox
Sampler(PagedVolume<VoxelType>* volume); Sampler(PagedVolume<VoxelType>* volume);
~Sampler(); ~Sampler();
inline VoxelType getVoxel(void) const; inline VoxelType getVoxel(void) const;
void setPosition(const Vector3DInt32& v3dNewPos); void setPosition(const Vector3DInt32& v3dNewPos);
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
@ -256,7 +256,7 @@ namespace PolyVox
uint16_t m_uChunkSideLengthMinusOne; uint16_t m_uChunkSideLengthMinusOne;
}; };
#endif // SWIG #endif // SWIG
public: public:
/// Constructor for creating a fixed size volume. /// Constructor for creating a fixed size volume.

View File

@ -36,38 +36,38 @@ namespace PolyVox
/// \param uChunkSideLength The size of the chunks making up the volume. Small chunks will compress/decompress faster, but there will also be more of them meaning voxel access could be slower. /// \param uChunkSideLength The size of the chunks making up the volume. Small chunks will compress/decompress faster, but there will also be more of them meaning voxel access could be slower.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> template <typename VoxelType>
PagedVolume<VoxelType>::PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes, uint16_t uChunkSideLength) PagedVolume<VoxelType>::PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes, uint16_t uChunkSideLength)
:BaseVolume<VoxelType>() :BaseVolume<VoxelType>()
, m_uChunkSideLength(uChunkSideLength) , m_uChunkSideLength(uChunkSideLength)
, m_pPager(pPager) , m_pPager(pPager)
{ {
// Validation of parameters // Validation of parameters
POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume"); POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume");
POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical"); POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical");
POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero."); POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero.");
POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical."); POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical.");
POLYVOX_THROW_IF(!isPowerOf2(m_uChunkSideLength), std::invalid_argument, "Chunk side length must be a power of two."); POLYVOX_THROW_IF(!isPowerOf2(m_uChunkSideLength), std::invalid_argument, "Chunk side length must be a power of two.");
// Used to perform multiplications and divisions by bit shifting. // Used to perform multiplications and divisions by bit shifting.
m_uChunkSideLengthPower = logBase2(m_uChunkSideLength); m_uChunkSideLengthPower = logBase2(m_uChunkSideLength);
// Use to perform modulo by bit operations // Use to perform modulo by bit operations
m_iChunkMask = m_uChunkSideLength - 1; m_iChunkMask = m_uChunkSideLength - 1;
// Calculate the number of chunks based on the memory limit and the size of each chunk. // Calculate the number of chunks based on the memory limit and the size of each chunk.
uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength); uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength);
m_uChunkCountLimit = uTargetMemoryUsageInBytes / uChunkSizeInBytes; m_uChunkCountLimit = uTargetMemoryUsageInBytes / uChunkSizeInBytes;
// Enforce sensible limits on the number of chunks. // Enforce sensible limits on the number of chunks.
const uint32_t uMinPracticalNoOfChunks = 32; // Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare. const uint32_t uMinPracticalNoOfChunks = 32; // Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare.
const uint32_t uMaxPracticalNoOfChunks = uChunkArraySize / 2; // A hash table should only become half-full to avoid too many clashes. const uint32_t uMaxPracticalNoOfChunks = uChunkArraySize / 2; // A hash table should only become half-full to avoid too many clashes.
POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of ", POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of ",
uTargetMemoryUsageInBytes / (1024 * 1024), "Mb is too low and cannot be adhered to."); uTargetMemoryUsageInBytes / (1024 * 1024), "Mb is too low and cannot be adhered to.");
m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks); m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks);
m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks); m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks);
// Inform the user about the chosen memory configuration. // Inform the user about the chosen memory configuration.
POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to ", (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024), POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to ", (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024),
"Mb (", m_uChunkCountLimit, " chunks of ", uChunkSizeInBytes / 1024, "Kb each)."); "Mb (", m_uChunkCountLimit, " chunks of ", uChunkSizeInBytes / 1024, "Kb each).");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -181,13 +181,13 @@ namespace PolyVox
{ {
// Convert the start and end positions into chunk space coordinates // Convert the start and end positions into chunk space coordinates
Vector3DInt32 v3dStart; Vector3DInt32 v3dStart;
for(int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
v3dStart.setElement(i, regPrefetch.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower); v3dStart.setElement(i, regPrefetch.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower);
} }
Vector3DInt32 v3dEnd; Vector3DInt32 v3dEnd;
for(int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower); v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower);
} }
@ -199,13 +199,13 @@ namespace PolyVox
uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit); uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit);
// Loops over the specified positions and touch the corresponding chunks. // Loops over the specified positions and touch the corresponding chunks.
for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) for (int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++)
{ {
for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) for (int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++)
{ {
for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) for (int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++)
{ {
getChunk(x,y,z); getChunk(x, y, z);
} }
} }
} }
@ -233,33 +233,33 @@ namespace PolyVox
/*template <typename VoxelType> /*template <typename VoxelType>
void PagedVolume<VoxelType>::flush(Region regFlush) void PagedVolume<VoxelType>::flush(Region regFlush)
{ {
// Clear this pointer in case the chunk it points at is flushed. // Clear this pointer in case the chunk it points at is flushed.
m_pLastAccessedChunk = nullptr; m_pLastAccessedChunk = nullptr;
// Convert the start and end positions into chunk space coordinates // Convert the start and end positions into chunk space coordinates
Vector3DInt32 v3dStart; Vector3DInt32 v3dStart;
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
v3dStart.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower); v3dStart.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower);
} }
Vector3DInt32 v3dEnd; Vector3DInt32 v3dEnd;
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
v3dEnd.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower); v3dEnd.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower);
} }
// Loops over the specified positions and delete the corresponding chunks. // Loops over the specified positions and delete the corresponding chunks.
for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++)
{ {
for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++)
{ {
for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++)
{ {
m_mapChunks.erase(Vector3DInt32(x, y, z)); m_mapChunks.erase(Vector3DInt32(x, y, z));
} }
} }
} }
}*/ }*/
template <typename VoxelType> template <typename VoxelType>
@ -365,13 +365,13 @@ namespace PolyVox
m_arrayChunks[uOldestChunkIndex] = nullptr; m_arrayChunks[uOldestChunkIndex] = nullptr;
} }
} }
m_pLastAccessedChunk = pChunk; m_pLastAccessedChunk = pChunk;
m_v3dLastAccessedChunkX = uChunkX; m_v3dLastAccessedChunkX = uChunkX;
m_v3dLastAccessedChunkY = uChunkY; m_v3dLastAccessedChunkY = uChunkY;
m_v3dLastAccessedChunkZ = uChunkZ; m_v3dLastAccessedChunkZ = uChunkZ;
return pChunk; return pChunk;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -30,12 +30,12 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
PagedVolume<VoxelType>::Chunk::Chunk(Vector3DInt32 v3dPosition, uint16_t uSideLength, Pager* pPager) PagedVolume<VoxelType>::Chunk::Chunk(Vector3DInt32 v3dPosition, uint16_t uSideLength, Pager* pPager)
:m_uChunkLastAccessed(0) :m_uChunkLastAccessed(0)
,m_bDataModified(true) , m_bDataModified(true)
,m_tData(0) , m_tData(0)
,m_uSideLength(0) , m_uSideLength(0)
,m_uSideLengthPower(0) , m_uSideLengthPower(0)
,m_pPager(pPager) , m_pPager(pPager)
,m_v3dChunkSpacePosition(v3dPosition) , m_v3dChunkSpacePosition(v3dPosition)
{ {
POLYVOX_ASSERT(m_pPager, "No valid pager supplied to chunk constructor."); POLYVOX_ASSERT(m_pPager, "No valid pager supplied to chunk constructor.");
POLYVOX_ASSERT(uSideLength <= 256, "Chunk side length cannot be greater than 256."); POLYVOX_ASSERT(uSideLength <= 256, "Chunk side length cannot be greater than 256.");
@ -46,7 +46,7 @@ namespace PolyVox
// Allocate the data // Allocate the data
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
m_tData = new VoxelType[uNoOfVoxels]; m_tData = new VoxelType[uNoOfVoxels];
// Pass the chunk to the Pager to give it a chance to initialise it with any data // Pass the chunk to the Pager to give it a chance to initialise it with any data
// From the coordinates of the chunk we deduce the coordinates of the contained voxels. // From the coordinates of the chunk we deduce the coordinates of the contained voxels.
@ -134,9 +134,9 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void PagedVolume<VoxelType>::Chunk::setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue) void PagedVolume<VoxelType>::Chunk::setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue)
{ {
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
} }
template <typename VoxelType> template <typename VoxelType>
uint32_t PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(void) uint32_t PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(void)
@ -160,7 +160,7 @@ namespace PolyVox
// then the ordering is automatically handled correctly. // then the ordering is automatically handled correctly.
template <typename VoxelType> template <typename VoxelType>
void PagedVolume<VoxelType>::Chunk::changeLinearOrderingToMorton(void) void PagedVolume<VoxelType>::Chunk::changeLinearOrderingToMorton(void)
{ {
VoxelType* pTempBuffer = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; VoxelType* pTempBuffer = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
// We should prehaps restructure this loop. From: https://fgiesen.wordpress.com/2011/01/17/texture-tiling-and-swizzling/ // We should prehaps restructure this loop. From: https://fgiesen.wordpress.com/2011/01/17/texture-tiling-and-swizzling/

View File

@ -107,7 +107,7 @@ namespace PolyVox
BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveX(); BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveX();
// Then we update the voxel pointer // Then we update the voxel pointer
if(CAN_GO_POS_X(this->m_uXPosInChunk)) if (CAN_GO_POS_X(this->m_uXPosInChunk))
{ {
//No need to compute new chunk. //No need to compute new chunk.
mCurrentVoxel += POS_X_DELTA; mCurrentVoxel += POS_X_DELTA;
@ -227,7 +227,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -237,7 +237,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -247,7 +247,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -257,7 +257,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -267,7 +267,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA); return *(mCurrentVoxel + NEG_X_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -277,7 +277,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -287,7 +287,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -297,7 +297,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -307,7 +307,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -319,7 +319,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + NEG_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -329,7 +329,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_Y_DELTA); return *(mCurrentVoxel + NEG_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -339,7 +339,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + NEG_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -349,7 +349,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + NEG_Z_DELTA); return *(mCurrentVoxel + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -365,7 +365,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_Z_DELTA); return *(mCurrentVoxel + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -375,7 +375,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + POS_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -385,7 +385,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_Y_DELTA); return *(mCurrentVoxel + POS_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -395,7 +395,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + POS_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -407,7 +407,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -417,7 +417,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA); return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -427,7 +427,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -437,7 +437,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -447,7 +447,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA); return *(mCurrentVoxel + POS_X_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -457,7 +457,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -467,7 +467,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
@ -477,7 +477,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA); return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -487,7 +487,7 @@ namespace PolyVox
{ {
return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + POS_Z_DELTA); return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + POS_Z_DELTA);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
} }

View File

@ -39,7 +39,7 @@ namespace PolyVox
Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit
Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit
}; };
/// Pick the first solid voxel along a vector /// Pick the first solid voxel along a vector
template<typename VolumeType> template<typename VolumeType>
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample); PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample);

View File

@ -26,13 +26,13 @@
namespace PolyVox namespace PolyVox
{ {
namespace namespace
{ {
/** /**
* This is just an implementation class for the pickVoxel function * This is just an implementation class for the pickVoxel function
* *
* It makes note of the sort of empty voxel you're looking for in the constructor. * It makes note of the sort of empty voxel you're looking for in the constructor.
* *
* Each time the operator() is called: * Each time the operator() is called:
* * if it's hit a voxel it sets up the result and returns false * * if it's hit a voxel it sets up the result and returns false
* * otherwise it preps the result for the next iteration and returns true * * otherwise it preps the result for the next iteration and returns true
@ -43,43 +43,43 @@ namespace PolyVox
public: public:
RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample) RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample)
:m_emptyVoxelExample(emptyVoxelExample) :m_emptyVoxelExample(emptyVoxelExample)
,m_result() , m_result()
{ {
} }
bool operator()(const typename VolumeType::Sampler& sampler) bool operator()(const typename VolumeType::Sampler& sampler)
{ {
if(sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something if (sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something
{ {
m_result.didHit = true; m_result.didHit = true;
m_result.hitVoxel = sampler.getPosition(); m_result.hitVoxel = sampler.getPosition();
return false; return false;
} }
m_result.previousVoxel = sampler.getPosition(); m_result.previousVoxel = sampler.getPosition();
return true; return true;
} }
const typename VolumeType::VoxelType& m_emptyVoxelExample; const typename VolumeType::VoxelType& m_emptyVoxelExample;
PickResult m_result; PickResult m_result;
}; };
} }
/** /**
* \param volData The volume to pass the ray though * \param volData The volume to pass the ray though
* \param v3dStart The start position in the volume * \param v3dStart The start position in the volume
* \param v3dDirectionAndLength The direction and length of the ray * \param v3dDirectionAndLength The direction and length of the ray
* \param emptyVoxelExample The value used to represent empty voxels in your volume * \param emptyVoxelExample The value used to represent empty voxels in your volume
* *
* \return A PickResult containing the hit information * \return A PickResult containing the hit information
*/ */
template<typename VolumeType> template<typename VolumeType>
PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample) PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample)
{ {
RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample); RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample);
raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor); raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor);
return functor.m_result; return functor.m_result;
} }
} }

View File

@ -40,7 +40,7 @@ namespace PolyVox
class RawVolume : public BaseVolume<VoxelType> class RawVolume : public BaseVolume<VoxelType>
{ {
public: public:
#ifndef SWIG #ifndef SWIG
//There seems to be some descrepency between Visual Studio and GCC about how the following class should be declared. //There seems to be some descrepency between Visual Studio and GCC about how the following class should be declared.
//There is a work around (see also See http://goo.gl/qu1wn) given below which appears to work on VS2010 and GCC, but //There is a work around (see also See http://goo.gl/qu1wn) given below which appears to work on VS2010 and GCC, but
//which seems to cause internal compiler errors on VS2008 when building with the /Gm 'Enable Minimal Rebuild' compiler //which seems to cause internal compiler errors on VS2008 when building with the /Gm 'Enable Minimal Rebuild' compiler
@ -51,7 +51,7 @@ namespace PolyVox
#if defined(_MSC_VER) #if defined(_MSC_VER)
class Sampler : public BaseVolume<VoxelType>::Sampler< RawVolume<VoxelType> > //This line works on VS2010 class Sampler : public BaseVolume<VoxelType>::Sampler< RawVolume<VoxelType> > //This line works on VS2010
#else #else
class Sampler : public BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> > //This line works on GCC class Sampler : public BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> > //This line works on GCC
#endif #endif
{ {
public: public:
@ -115,7 +115,7 @@ namespace PolyVox
bool m_bIsCurrentPositionValidInY; bool m_bIsCurrentPositionValidInY;
bool m_bIsCurrentPositionValidInZ; bool m_bIsCurrentPositionValidInZ;
}; };
#endif // SWIG #endif // SWIG
public: public:
/// Constructor for creating a fixed size volume. /// Constructor for creating a fixed size volume.

View File

@ -34,10 +34,10 @@ namespace PolyVox
, m_regValidRegion(regValid) , m_regValidRegion(regValid)
, m_tBorderValue() , m_tBorderValue()
{ {
this->setBorderValue(VoxelType()); this->setBorderValue(VoxelType());
//Create a volume of the right size. //Create a volume of the right size.
initialise(regValid); initialise(regValid);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -145,11 +145,11 @@ namespace PolyVox
int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ(); int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ();
return m_pData return m_pData
[ [
iLocalXPos + iLocalXPos +
iLocalYPos * this->getWidth() + iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight() iLocalZPos * this->getWidth() * this->getHeight()
]; ];
} }
else else
{ {
@ -198,11 +198,11 @@ namespace PolyVox
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
m_pData m_pData
[ [
iLocalXPos + iLocalXPos +
iLocalYPos * this->getWidth() + iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight() iLocalZPos * this->getWidth() * this->getHeight()
] = tValue; ] = tValue;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -223,15 +223,15 @@ namespace PolyVox
{ {
this->m_regValidRegion = regValidRegion; this->m_regValidRegion = regValidRegion;
if(this->getWidth() <= 0) if (this->getWidth() <= 0)
{ {
POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero."); POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero.");
} }
if(this->getHeight() <= 0) if (this->getHeight() <= 0)
{ {
POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero."); POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero.");
} }
if(this->getDepth() <= 0) if (this->getDepth() <= 0)
{ {
POLYVOX_THROW(std::invalid_argument, "Volume depth must be greater than zero."); POLYVOX_THROW(std::invalid_argument, "Volume depth must be greater than zero.");
} }

View File

@ -34,7 +34,7 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume) RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume)
:BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume) :BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume)
,mCurrentVoxel(0) , mCurrentVoxel(0)
, m_bIsCurrentPositionValidInX(false) , m_bIsCurrentPositionValidInX(false)
, m_bIsCurrentPositionValidInY(false) , m_bIsCurrentPositionValidInY(false)
, m_bIsCurrentPositionValidInZ(false) , m_bIsCurrentPositionValidInZ(false)
@ -49,7 +49,7 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::getVoxel(void) const VoxelType RawVolume<VoxelType>::Sampler::getVoxel(void) const
{ {
if(this->isCurrentPositionValid()) if (this->isCurrentPositionValid())
{ {
return *mCurrentVoxel; return *mCurrentVoxel;
} }
@ -82,16 +82,16 @@ namespace PolyVox
m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(zPos); m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(zPos);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid()) if (this->isCurrentPositionValid())
{ {
const Vector3DInt32& v3dLowerCorner = this->mVolume->m_regValidRegion.getLowerCorner(); const Vector3DInt32& v3dLowerCorner = this->mVolume->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = xPos - v3dLowerCorner.getX(); int32_t iLocalXPos = xPos - v3dLowerCorner.getX();
int32_t iLocalYPos = yPos - v3dLowerCorner.getY(); int32_t iLocalYPos = yPos - v3dLowerCorner.getY();
int32_t iLocalZPos = zPos - v3dLowerCorner.getZ(); int32_t iLocalZPos = zPos - v3dLowerCorner.getZ();
const int32_t uVoxelIndex = iLocalXPos + const int32_t uVoxelIndex = iLocalXPos +
iLocalYPos * this->mVolume->getWidth() + iLocalYPos * this->mVolume->getWidth() +
iLocalZPos * this->mVolume->getWidth() * this->mVolume->getHeight(); iLocalZPos * this->mVolume->getWidth() * this->mVolume->getHeight();
mCurrentVoxel = this->mVolume->m_pData + uVoxelIndex; mCurrentVoxel = this->mVolume->m_pData + uVoxelIndex;
} }
@ -105,7 +105,7 @@ namespace PolyVox
bool RawVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue) bool RawVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue)
{ {
//return m_bIsCurrentPositionValid ? *mCurrentVoxel : this->mVolume->getBorderValue(); //return m_bIsCurrentPositionValid ? *mCurrentVoxel : this->mVolume->getBorderValue();
if(this->m_bIsCurrentPositionValidInX && this->m_bIsCurrentPositionValidInY && this->m_bIsCurrentPositionValidInZ) if (this->m_bIsCurrentPositionValidInX && this->m_bIsCurrentPositionValidInY && this->m_bIsCurrentPositionValidInZ)
{ {
*mCurrentVoxel = tValue; *mCurrentVoxel = tValue;
return true; return true;
@ -128,7 +128,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume); m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
++mCurrentVoxel; ++mCurrentVoxel;
} }
@ -150,7 +150,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume); m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
mCurrentVoxel += this->mVolume->getWidth(); mCurrentVoxel += this->mVolume->getWidth();
} }
@ -172,7 +172,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume); m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
mCurrentVoxel += this->mVolume->getWidth() * this->mVolume->getHeight(); mCurrentVoxel += this->mVolume->getWidth() * this->mVolume->getHeight();
} }
@ -194,7 +194,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume); m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
--mCurrentVoxel; --mCurrentVoxel;
} }
@ -216,7 +216,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume); m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
mCurrentVoxel -= this->mVolume->getWidth(); mCurrentVoxel -= this->mVolume->getWidth();
} }
@ -238,7 +238,7 @@ namespace PolyVox
m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume); m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if (this->isCurrentPositionValid() && bIsOldPositionValid)
{ {
mCurrentVoxel -= this->mVolume->getWidth() * this->mVolume->getHeight(); mCurrentVoxel -= this->mVolume->getWidth() * this->mVolume->getHeight();
} }
@ -251,91 +251,91 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel - 1 - this->mVolume->getWidth()); return *(mCurrentVoxel - 1 - this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume))
{ {
return *(mCurrentVoxel - 1); return *(mCurrentVoxel - 1);
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel - 1 + this->mVolume->getWidth()); return *(mCurrentVoxel - 1 + this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -343,47 +343,47 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel - this->mVolume->getWidth()); return *(mCurrentVoxel - this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py0pz(void) const
{ {
if((this->isCurrentPositionValid())) if ((this->isCurrentPositionValid()))
{ {
return *mCurrentVoxel; return *mCurrentVoxel;
} }
@ -393,41 +393,41 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel + this->mVolume->getWidth()); return *(mCurrentVoxel + this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -435,91 +435,91 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel + 1 - this->mVolume->getWidth()); return *(mCurrentVoxel + 1 - this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume))
{ {
return *(mCurrentVoxel + 1); return *(mCurrentVoxel + 1);
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume + 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1nz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1nz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py0pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py0pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume))
{ {
return *(mCurrentVoxel + 1 + this->mVolume->getWidth()); return *(mCurrentVoxel + 1 + this->mVolume->getWidth());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1pz(void) const VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1pz(void) const
{ {
if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume))
{ {
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
} }
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1);
} }
} }

View File

@ -53,20 +53,20 @@ namespace PolyVox
// It should simply read "if (ty <= tz)". // It should simply read "if (ty <= tz)".
// //
// This error was reported by Joey Hammer (PixelActive). // This error was reported by Joey Hammer (PixelActive).
/** /**
* Cast a ray through a volume by specifying the start and end positions * Cast a ray through a volume by specifying the start and end positions
* *
* The ray will move from \a v3dStart to \a v3dEnd, calling \a callback for each * The ray will move from \a v3dStart to \a v3dEnd, calling \a callback for each
* voxel it passes through until \a callback returns \a false. In this case it * voxel it passes through until \a callback returns \a false. In this case it
* returns a RaycastResults::Interupted. If it passes from start to end * returns a RaycastResults::Interupted. If it passes from start to end
* without \a callback returning \a false, it returns RaycastResults::Completed. * without \a callback returning \a false, it returns RaycastResults::Completed.
* *
* \param volData The volume to pass the ray though * \param volData The volume to pass the ray though
* \param v3dStart The start position in the volume * \param v3dStart The start position in the volume
* \param v3dEnd The end position in the volume * \param v3dEnd The end position in the volume
* \param callback The callback to call for each voxel * \param callback The callback to call for each voxel
* *
* \return A RaycastResults designating whether the ray hit anything or not * \return A RaycastResults designating whether the ray hit anything or not
*/ */
template<typename VolumeType, typename Callback> template<typename VolumeType, typename Callback>
@ -83,7 +83,7 @@ namespace PolyVox
const float x2 = v3dEnd.getX() + 0.5f; const float x2 = v3dEnd.getX() + 0.5f;
const float y2 = v3dEnd.getY() + 0.5f; const float y2 = v3dEnd.getY() + 0.5f;
const float z2 = v3dEnd.getZ() + 0.5f; const float z2 = v3dEnd.getZ() + 0.5f;
int i = (int)floorf(x1); int i = (int)floorf(x1);
int j = (int)floorf(y1); int j = (int)floorf(y1);
int k = (int)floorf(z1); int k = (int)floorf(z1);
@ -107,39 +107,41 @@ namespace PolyVox
const float minz = floorf(z1), maxz = minz + 1.0f; const float minz = floorf(z1), maxz = minz + 1.0f;
float tz = ((z1 > z2) ? (z1 - minz) : (maxz - z1)) * deltatz; float tz = ((z1 > z2) ? (z1 - minz) : (maxz - z1)) * deltatz;
sampler.setPosition(i,j,k); sampler.setPosition(i, j, k);
for(;;) for (;;)
{ {
if(!callback(sampler)) if (!callback(sampler))
{ {
return RaycastResults::Interupted; return RaycastResults::Interupted;
} }
if(tx <= ty && tx <= tz) if (tx <= ty && tx <= tz)
{ {
if(i == iend) break; if (i == iend) break;
tx += deltatx; tx += deltatx;
i += di; i += di;
if(di == 1) sampler.movePositiveX(); if (di == 1) sampler.movePositiveX();
if(di == -1) sampler.moveNegativeX(); if (di == -1) sampler.moveNegativeX();
} else if (ty <= tz) }
else if (ty <= tz)
{ {
if(j == jend) break; if (j == jend) break;
ty += deltaty; ty += deltaty;
j += dj; j += dj;
if(dj == 1) sampler.movePositiveY(); if (dj == 1) sampler.movePositiveY();
if(dj == -1) sampler.moveNegativeY(); if (dj == -1) sampler.moveNegativeY();
} else }
else
{ {
if(k == kend) break; if (k == kend) break;
tz += deltatz; tz += deltatz;
k += dk; k += dk;
if(dk == 1) sampler.movePositiveZ(); if (dk == 1) sampler.movePositiveZ();
if(dk == -1) sampler.moveNegativeZ(); if (dk == -1) sampler.moveNegativeZ();
} }
} }
@ -148,13 +150,13 @@ namespace PolyVox
/** /**
* Cast a ray through a volume by specifying the start and a direction * Cast a ray through a volume by specifying the start and a direction
* *
* The ray will move from \a v3dStart along \a v3dDirectionAndLength, calling * The ray will move from \a v3dStart along \a v3dDirectionAndLength, calling
* \a callback for each voxel it passes through until \a callback returns * \a callback for each voxel it passes through until \a callback returns
* \a false. In this case it returns a RaycastResults::Interupted. If it * \a false. In this case it returns a RaycastResults::Interupted. If it
* passes from start to end without \a callback returning \a false, it * passes from start to end without \a callback returning \a false, it
* returns RaycastResults::Completed. * returns RaycastResults::Completed.
* *
* \note These has been confusion in the past with people not realising * \note These has been confusion in the past with people not realising
* that the length of the direction vector is important. Most graphics API can provide * that the length of the direction vector is important. Most graphics API can provide
* a camera position and view direction for picking purposes, but the view direction is * a camera position and view direction for picking purposes, but the view direction is
@ -162,12 +164,12 @@ namespace PolyVox
* will only iterate over a single voxel and won't find what you are looking for. Instead * will only iterate over a single voxel and won't find what you are looking for. Instead
* you must scale the direction vector so that it's length represents the maximum distance * you must scale the direction vector so that it's length represents the maximum distance
* over which you want the ray to be cast. * over which you want the ray to be cast.
* *
* \param volData The volume to pass the ray though * \param volData The volume to pass the ray though
* \param v3dStart The start position in the volume * \param v3dStart The start position in the volume
* \param v3dDirectionAndLength The direction and length of the ray * \param v3dDirectionAndLength The direction and length of the ray
* \param callback The callback to call for each voxel * \param callback The callback to call for each voxel
* *
* \return A RaycastResults designating whether the ray hit anything or not * \return A RaycastResults designating whether the ray hit anything or not
*/ */
template<typename VolumeType, typename Callback> template<typename VolumeType, typename Callback>

View File

@ -32,23 +32,23 @@
namespace PolyVox namespace PolyVox
{ {
/** Represents a part of a Volume. /** Represents a part of a Volume.
* *
* Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors * Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors
* it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may * it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may
* be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts * be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts
* of the volume, there by giving a number of meshes which can be culled and rendered seperately. * of the volume, there by giving a number of meshes which can be culled and rendered seperately.
* *
* The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower * The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower
* bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are * bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are
* <em>inclusive</em>. * <em>inclusive</em>.
* *
* As well as the expected set of getters and setters, this class also provide utility functions for increasing and decresing * As well as the expected set of getters and setters, this class also provide utility functions for increasing and decresing
* the size of the Region, shifting the Region in 3D space, testing whether it contains a given position, enlarging it so that * the size of the Region, shifting the Region in 3D space, testing whether it contains a given position, enlarging it so that
* it does contain a given position, croppng it to another Region, and various other utility functions. * it does contain a given position, croppng it to another Region, and various other utility functions.
* *
* \Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information * \Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information
* about these definitions. * about these definitions.
* *
*/ */
class Region class Region
{ {
@ -67,9 +67,9 @@ namespace PolyVox
Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ); Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ);
/// Equality Operator. /// Equality Operator.
bool operator==(const Region& rhs) const; bool operator==(const Region& rhs) const;
/// Inequality Operator. /// Inequality Operator.
bool operator!=(const Region& rhs) const; bool operator!=(const Region& rhs) const;
/// Gets the 'x' position of the centre. /// Gets the 'x' position of the centre.
int32_t getCentreX(void) const; int32_t getCentreX(void) const;
@ -189,7 +189,7 @@ namespace PolyVox
/// Moves the upper corner of the Region by the amount specified. /// Moves the upper corner of the Region by the amount specified.
void shiftUpperCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ); void shiftUpperCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
/// Moves the upper corner of the Region by the amount specified. /// Moves the upper corner of the Region by the amount specified.
void shiftUpperCorner(const Vector3DInt32& v3dAmount); void shiftUpperCorner(const Vector3DInt32& v3dAmount);
/// Shrinks this region by the amount specified. /// Shrinks this region by the amount specified.
void shrink(int32_t iAmount); void shrink(int32_t iAmount);

View File

@ -80,10 +80,10 @@ namespace PolyVox
*/ */
inline void Region::accumulate(const Region& reg) inline void Region::accumulate(const Region& reg)
{ {
if(!reg.isValid()) if (!reg.isValid())
{ {
POLYVOX_THROW(invalid_operation, "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined. POLYVOX_THROW(invalid_operation, "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined.
} }
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX())); m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY())); m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));
@ -98,11 +98,11 @@ namespace PolyVox
*/ */
inline Region::Region() inline Region::Region()
:m_iLowerX(0) :m_iLowerX(0)
,m_iLowerY(0) , m_iLowerY(0)
,m_iLowerZ(0) , m_iLowerZ(0)
,m_iUpperX(0) , m_iUpperX(0)
,m_iUpperY(0) , m_iUpperY(0)
,m_iUpperZ(0) , m_iUpperZ(0)
{ {
} }
@ -113,11 +113,11 @@ namespace PolyVox
*/ */
inline Region::Region(const Vector3DInt32& v3dLowerCorner, const Vector3DInt32& v3dUpperCorner) inline Region::Region(const Vector3DInt32& v3dLowerCorner, const Vector3DInt32& v3dUpperCorner)
:m_iLowerX(v3dLowerCorner.getX()) :m_iLowerX(v3dLowerCorner.getX())
,m_iLowerY(v3dLowerCorner.getY()) , m_iLowerY(v3dLowerCorner.getY())
,m_iLowerZ(v3dLowerCorner.getZ()) , m_iLowerZ(v3dLowerCorner.getZ())
,m_iUpperX(v3dUpperCorner.getX()) , m_iUpperX(v3dUpperCorner.getX())
,m_iUpperY(v3dUpperCorner.getY()) , m_iUpperY(v3dUpperCorner.getY())
,m_iUpperZ(v3dUpperCorner.getZ()) , m_iUpperZ(v3dUpperCorner.getZ())
{ {
} }
@ -132,11 +132,11 @@ namespace PolyVox
*/ */
inline Region::Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ) inline Region::Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ)
:m_iLowerX(iLowerX) :m_iLowerX(iLowerX)
,m_iLowerY(iLowerY) , m_iLowerY(iLowerY)
,m_iLowerZ(iLowerZ) , m_iLowerZ(iLowerZ)
,m_iUpperX(iUpperX) , m_iUpperX(iUpperX)
,m_iUpperY(iUpperY) , m_iUpperY(iUpperY)
,m_iUpperZ(iUpperZ) , m_iUpperZ(iUpperZ)
{ {
} }
@ -147,25 +147,25 @@ namespace PolyVox
* \sa operator!= * \sa operator!=
*/ */
inline bool Region::operator==(const Region& rhs) const inline bool Region::operator==(const Region& rhs) const
{ {
return ((m_iLowerX == rhs.m_iLowerX) && (m_iLowerY == rhs.m_iLowerY) && (m_iLowerZ == rhs.m_iLowerZ) return ((m_iLowerX == rhs.m_iLowerX) && (m_iLowerY == rhs.m_iLowerY) && (m_iLowerZ == rhs.m_iLowerZ)
&& (m_iUpperX == rhs.m_iUpperX) && (m_iUpperY == rhs.m_iUpperY) && (m_iUpperZ == rhs.m_iUpperZ)); && (m_iUpperX == rhs.m_iUpperX) && (m_iUpperY == rhs.m_iUpperY) && (m_iUpperZ == rhs.m_iUpperZ));
} }
/** /**
* Two regions are considered different if any of their extents differ. * Two regions are considered different if any of their extents differ.
* \param rhs The Region to compare to. * \param rhs The Region to compare to.
* \return true if the Regions are different. * \return true if the Regions are different.
* \sa operator== * \sa operator==
*/ */
inline bool Region::operator!=(const Region& rhs) const inline bool Region::operator!=(const Region& rhs) const
{ {
return !(*this == rhs); return !(*this == rhs);
} }
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in all directions. Also, the test is inclusive such * the Region if it is that far in in all directions. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param fX The 'x' position of the point to test. * \param fX The 'x' position of the point to test.
* \param fY The 'y' position of the point to test. * \param fY The 'y' position of the point to test.
@ -184,7 +184,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in all directions. Also, the test is inclusive such * the Region if it is that far in in all directions. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -196,7 +196,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in all directions. Also, the test is inclusive such * the Region if it is that far in in all directions. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param iX The 'x' position of the point to test. * \param iX The 'x' position of the point to test.
* \param iY The 'y' position of the point to test. * \param iY The 'y' position of the point to test.
@ -206,7 +206,7 @@ namespace PolyVox
inline bool Region::containsPoint(int32_t iX, int32_t iY, int32_t iZ, uint8_t boundary) const inline bool Region::containsPoint(int32_t iX, int32_t iY, int32_t iZ, uint8_t boundary) const
{ {
return (iX <= m_iUpperX - boundary) return (iX <= m_iUpperX - boundary)
&& (iY <= m_iUpperY - boundary) && (iY <= m_iUpperY - boundary)
&& (iZ <= m_iUpperZ - boundary) && (iZ <= m_iUpperZ - boundary)
&& (iX >= m_iLowerX + boundary) && (iX >= m_iLowerX + boundary)
&& (iY >= m_iLowerY + boundary) && (iY >= m_iLowerY + boundary)
@ -215,7 +215,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in all directions. Also, the test is inclusive such * the Region if it is that far in in all directions. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -227,7 +227,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'x' direction. Also, the test is inclusive such * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -240,7 +240,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'x' direction. Also, the test is inclusive such * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -253,7 +253,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'y' direction. Also, the test is inclusive such * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -266,20 +266,20 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'y' direction. Also, the test is inclusive such * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
*/ */
inline bool Region::containsPointInY(int32_t pos, uint8_t boundary) const inline bool Region::containsPointInY(int32_t pos, uint8_t boundary) const
{ {
return (pos <= m_iUpperY - boundary) return (pos <= m_iUpperY - boundary)
&& (pos >= m_iLowerY + boundary); && (pos >= m_iLowerY + boundary);
} }
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'z' direction. Also, the test is inclusive such * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -292,7 +292,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a position is only considered to be inside * The boundary value can be used to ensure a position is only considered to be inside
* the Region if it is that far in in the 'z' direction. Also, the test is inclusive such * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such
* that positions lying exactly on the edge of the Region are considered to be inside it. * that positions lying exactly on the edge of the Region are considered to be inside it.
* \param pos The position to test. * \param pos The position to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -305,7 +305,7 @@ namespace PolyVox
/** /**
* The boundary value can be used to ensure a region is only considered to be inside * The boundary value can be used to ensure a region is only considered to be inside
* another Region if it is that far in in all directions. Also, the test is inclusive such * another Region if it is that far in in all directions. Also, the test is inclusive such
* that a region is considered to be inside of itself. * that a region is considered to be inside of itself.
* \param reg The region to test. * \param reg The region to test.
* \param boundary The desired boundary value. * \param boundary The desired boundary value.
@ -313,7 +313,7 @@ namespace PolyVox
inline bool Region::containsRegion(const Region& reg, uint8_t boundary) const inline bool Region::containsRegion(const Region& reg, uint8_t boundary) const
{ {
return (reg.m_iUpperX <= m_iUpperX - boundary) return (reg.m_iUpperX <= m_iUpperX - boundary)
&& (reg.m_iUpperY <= m_iUpperY - boundary) && (reg.m_iUpperY <= m_iUpperY - boundary)
&& (reg.m_iUpperZ <= m_iUpperZ - boundary) && (reg.m_iUpperZ <= m_iUpperZ - boundary)
&& (reg.m_iLowerX >= m_iLowerX + boundary) && (reg.m_iLowerX >= m_iLowerX + boundary)
&& (reg.m_iLowerY >= m_iLowerY + boundary) && (reg.m_iLowerY >= m_iLowerY + boundary)
@ -496,24 +496,24 @@ namespace PolyVox
inline bool intersects(const Region& a, const Region& b) inline bool intersects(const Region& a, const Region& b)
{ {
// No intersection if seperated along an axis. // No intersection if seperated along an axis.
if(a.getUpperX() < b.getLowerX() || a.getLowerX() > b.getUpperX()) return false; if (a.getUpperX() < b.getLowerX() || a.getLowerX() > b.getUpperX()) return false;
if(a.getUpperY() < b.getLowerY() || a.getLowerY() > b.getUpperY()) return false; if (a.getUpperY() < b.getLowerY() || a.getLowerY() > b.getUpperY()) return false;
if(a.getUpperZ() < b.getLowerZ() || a.getLowerZ() > b.getUpperZ()) return false; if (a.getUpperZ() < b.getLowerZ() || a.getLowerZ() > b.getUpperZ()) return false;
// Overlapping on all axes means Regions are intersecting. // Overlapping on all axes means Regions are intersecting.
return true; return true;
} }
/** /**
* Enables the Region to be used intuitively with output streams such as cout. * Enables the Region to be used intuitively with output streams such as cout.
* \param os The output stream to write to. * \param os The output stream to write to.
* \param region The Region to write to the stream. * \param region The Region to write to the stream.
* \return A reference to the output stream to allow chaining. * \return A reference to the output stream to allow chaining.
*/ */
inline std::ostream& operator<<(std::ostream& os, const Region& region) inline std::ostream& operator<<(std::ostream& os, const Region& region)
{ {
os << "(" << region.getLowerX() << "," << region.getLowerY() << "," << region.getLowerZ() << os << "(" << region.getLowerX() << "," << region.getLowerY() << "," << region.getLowerZ() <<
") to (" << region.getUpperX() << "," << region.getUpperY() << "," << region.getUpperZ() << ")"; ") to (" << region.getUpperX() << "," << region.getUpperY() << "," << region.getUpperZ() << ")";
return os; return os;
} }
} }

View File

@ -39,7 +39,7 @@ namespace PolyVox
{ {
/** /**
* Represents a vector in space. * Represents a vector in space.
* *
* This is a generl purpose vector class designed to represent both positions and directions. It is templatised * This is a generl purpose vector class designed to represent both positions and directions. It is templatised
* on both size and data type but note that some of the operations do not make sense with integer types. For * on both size and data type but note that some of the operations do not make sense with integer types. For
* example it does not make conceptual sense to try and normalise an integer Vector. * example it does not make conceptual sense to try and normalise an integer Vector.
@ -48,7 +48,7 @@ namespace PolyVox
* X, Y, Z and W elements. Note that W is last even though it comes before X in the alphabet. These elements can * X, Y, Z and W elements. Note that W is last even though it comes before X in the alphabet. These elements can
* be accessed through getX(), setX(), getY(), setY(), getZ(), setZ(), getW() and setW(), while other elements * be accessed through getX(), setX(), getY(), setY(), getZ(), setZ(), getW() and setW(), while other elements
* can be accessed through getElemen() and setElement(). * can be accessed through getElemen() and setElement().
* *
* This class includes a number of common mathematical operations (addition, subtraction, etc) as well as vector * This class includes a number of common mathematical operations (addition, subtraction, etc) as well as vector
* specific operations such as the dot and cross products. Note that this class is also templatised on an * specific operations such as the dot and cross products. Note that this class is also templatised on an
* OperationType which is used for many internal calculations and some results. For example, the square of a * OperationType which is used for many internal calculations and some results. For example, the square of a
@ -58,66 +58,66 @@ namespace PolyVox
* *
* Typedefs are provided for 2, 3 and 4 dimensional vector with int8_t, uint8_t, int16_t, uint6_t, int32_t, * Typedefs are provided for 2, 3 and 4 dimensional vector with int8_t, uint8_t, int16_t, uint6_t, int32_t,
* uint32_t, float and double types. These typedefs are used as follows: * uint32_t, float and double types. These typedefs are used as follows:
* *
* \code * \code
* Vector2DInt32 test(1,2); //Declares a 2 dimensional Vector of type int32_t. * Vector2DInt32 test(1,2); //Declares a 2 dimensional Vector of type int32_t.
* \endcode * \endcode
*/ */
template <uint32_t Size, typename StorageType, typename OperationType = StorageType> template <uint32_t Size, typename StorageType, typename OperationType = StorageType>
class Vector class Vector
{ {
public: public:
/// Constructor /// Constructor
Vector(void); Vector(void);
/// Constructor. /// Constructor.
Vector(StorageType tFillValue); Vector(StorageType tFillValue);
/// Constructor. /// Constructor.
Vector(StorageType x, StorageType y); Vector(StorageType x, StorageType y);
/// Constructor. /// Constructor.
Vector(StorageType x, StorageType y, StorageType z); Vector(StorageType x, StorageType y, StorageType z);
/// Constructor. /// Constructor.
Vector(StorageType x, StorageType y, StorageType z, StorageType w); Vector(StorageType x, StorageType y, StorageType z, StorageType w);
/// Copy Constructor. /// Copy Constructor.
Vector(const Vector<Size,StorageType,OperationType>& vector); Vector(const Vector<Size, StorageType, OperationType>& vector);
/// Copy Constructor which performs casting. /// Copy Constructor which performs casting.
template <typename CastType> explicit Vector(const Vector<Size,CastType>& vector); template <typename CastType> explicit Vector(const Vector<Size, CastType>& vector);
/// Destructor. /// Destructor.
~Vector(void); ~Vector(void);
/// Assignment Operator. /// Assignment Operator.
Vector<Size,StorageType,OperationType>& operator=(const Vector<Size,StorageType,OperationType>& rhs); Vector<Size, StorageType, OperationType>& operator=(const Vector<Size, StorageType, OperationType>& rhs);
/// Equality Operator. /// Equality Operator.
bool operator==(const Vector<Size,StorageType,OperationType>& rhs) const; bool operator==(const Vector<Size, StorageType, OperationType>& rhs) const;
/// Inequality Operator. /// Inequality Operator.
bool operator!=(const Vector<Size,StorageType,OperationType>& rhs) const; bool operator!=(const Vector<Size, StorageType, OperationType>& rhs) const;
/// Addition and Assignment Operator. /// Addition and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator+=(const Vector<Size,StorageType,OperationType> &rhs); Vector<Size, StorageType, OperationType>& operator+=(const Vector<Size, StorageType, OperationType> &rhs);
/// Subtraction and Assignment Operator. /// Subtraction and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator-=(const Vector<Size,StorageType,OperationType> &rhs); Vector<Size, StorageType, OperationType>& operator-=(const Vector<Size, StorageType, OperationType> &rhs);
/// Multiplication and Assignment Operator. /// Multiplication and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator*=(const Vector<Size,StorageType,OperationType> &rhs); Vector<Size, StorageType, OperationType>& operator*=(const Vector<Size, StorageType, OperationType> &rhs);
/// Division and Assignment Operator. /// Division and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator/=(const Vector<Size,StorageType,OperationType> &rhs); Vector<Size, StorageType, OperationType>& operator/=(const Vector<Size, StorageType, OperationType> &rhs);
/// Multiplication and Assignment Operator. /// Multiplication and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator*=(const StorageType& rhs); Vector<Size, StorageType, OperationType>& operator*=(const StorageType& rhs);
/// Division and Assignment Operator. /// Division and Assignment Operator.
Vector<Size,StorageType,OperationType>& operator/=(const StorageType& rhs); Vector<Size, StorageType, OperationType>& operator/=(const StorageType& rhs);
/// Element Access. /// Element Access.
StorageType getElement(uint32_t index) const; StorageType getElement(uint32_t index) const;
/// Get the x component of the vector. /// Get the x component of the vector.
StorageType getX(void) const; StorageType getX(void) const;
/// Get the y component of the vector. /// Get the y component of the vector.
StorageType getY(void) const; StorageType getY(void) const;
/// Get the z component of the vector. /// Get the z component of the vector.
StorageType getZ(void) const; StorageType getZ(void) const;
/// Get the w component of the vector. /// Get the w component of the vector.
StorageType getW(void) const; StorageType getW(void) const;
/// Element Access. /// Element Access.
void setElement(uint32_t index, StorageType tValue); void setElement(uint32_t index, StorageType tValue);
/// Element Access. /// Element Access.
void setElements(StorageType x, StorageType y); void setElements(StorageType x, StorageType y);
/// Element Access. /// Element Access.
void setElements(StorageType x, StorageType y, StorageType z); void setElements(StorageType x, StorageType y, StorageType z);
/// Element Access. /// Element Access.
@ -131,99 +131,99 @@ namespace PolyVox
/// Set the w component of the vector. /// Set the w component of the vector.
void setW(StorageType tW); void setW(StorageType tW);
/// Get the length of the vector. /// Get the length of the vector.
float length(void) const; float length(void) const;
/// Get the squared length of the vector. /// Get the squared length of the vector.
OperationType lengthSquared(void) const; OperationType lengthSquared(void) const;
/// Find the angle between this vector and that which is passed as a parameter. /// Find the angle between this vector and that which is passed as a parameter.
float angleTo(const Vector<Size,StorageType,OperationType>& vector) const; float angleTo(const Vector<Size, StorageType, OperationType>& vector) const;
/// Find the cross product between this vector and the vector passed as a parameter. /// Find the cross product between this vector and the vector passed as a parameter.
Vector<Size,StorageType,OperationType> cross(const Vector<Size,StorageType,OperationType>& vector) const; Vector<Size, StorageType, OperationType> cross(const Vector<Size, StorageType, OperationType>& vector) const;
/// Find the dot product between this vector and the vector passed as a parameter. /// Find the dot product between this vector and the vector passed as a parameter.
OperationType dot(const Vector<Size,StorageType,OperationType>& rhs) const; OperationType dot(const Vector<Size, StorageType, OperationType>& rhs) const;
/// Normalise the vector. /// Normalise the vector.
void normalise(void); void normalise(void);
private: private:
// Values for the vector // Values for the vector
StorageType m_tElements[Size]; StorageType m_tElements[Size];
}; };
// Non-member overloaded operators. // Non-member overloaded operators.
/// Addition operator. /// Addition operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator+(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); Vector<Size, StorageType, OperationType> operator+(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs);
/// Subtraction operator. /// Subtraction operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator-(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); Vector<Size, StorageType, OperationType> operator-(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs);
/// Multiplication operator. /// Multiplication operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs);
/// Division operator. /// Division operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs);
/// Multiplication operator. /// Multiplication operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs); Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs);
/// Division operator. /// Division operator.
template <uint32_t Size,typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs); Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs);
/// Stream insertion operator. /// Stream insertion operator.
template <uint32_t Size, typename StorageType,typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
std::ostream& operator<<(std::ostream& os, const Vector<Size,StorageType,OperationType>& vector); std::ostream& operator<<(std::ostream& os, const Vector<Size, StorageType, OperationType>& vector);
//Some handy typedefs //Some handy typedefs
/// A 2D Vector of floats. /// A 2D Vector of floats.
typedef Vector<2,float,float> Vector2DFloat; typedef Vector<2, float, float> Vector2DFloat;
/// A 2D Vector of doubles. /// A 2D Vector of doubles.
typedef Vector<2,double,double> Vector2DDouble; typedef Vector<2, double, double> Vector2DDouble;
/// A 2D Vector of signed 8-bit values. /// A 2D Vector of signed 8-bit values.
typedef Vector<2,int8_t,int32_t> Vector2DInt8; typedef Vector<2, int8_t, int32_t> Vector2DInt8;
/// A 2D Vector of unsigned 8-bit values. /// A 2D Vector of unsigned 8-bit values.
typedef Vector<2,uint8_t,int32_t> Vector2DUint8; typedef Vector<2, uint8_t, int32_t> Vector2DUint8;
/// A 2D Vector of signed 16-bit values. /// A 2D Vector of signed 16-bit values.
typedef Vector<2,int16_t,int32_t> Vector2DInt16; typedef Vector<2, int16_t, int32_t> Vector2DInt16;
/// A 2D Vector of unsigned 16-bit values. /// A 2D Vector of unsigned 16-bit values.
typedef Vector<2,uint16_t,int32_t> Vector2DUint16; typedef Vector<2, uint16_t, int32_t> Vector2DUint16;
/// A 2D Vector of signed 32-bit values. /// A 2D Vector of signed 32-bit values.
typedef Vector<2,int32_t,int32_t> Vector2DInt32; typedef Vector<2, int32_t, int32_t> Vector2DInt32;
/// A 2D Vector of unsigned 32-bit values. /// A 2D Vector of unsigned 32-bit values.
typedef Vector<2,uint32_t,int32_t> Vector2DUint32; typedef Vector<2, uint32_t, int32_t> Vector2DUint32;
/// A 3D Vector of floats. /// A 3D Vector of floats.
typedef Vector<3,float,float> Vector3DFloat; typedef Vector<3, float, float> Vector3DFloat;
/// A 3D Vector of doubles. /// A 3D Vector of doubles.
typedef Vector<3,double,double> Vector3DDouble; typedef Vector<3, double, double> Vector3DDouble;
/// A 3D Vector of signed 8-bit values. /// A 3D Vector of signed 8-bit values.
typedef Vector<3,int8_t,int32_t> Vector3DInt8; typedef Vector<3, int8_t, int32_t> Vector3DInt8;
/// A 3D Vector of unsigned 8-bit values. /// A 3D Vector of unsigned 8-bit values.
typedef Vector<3,uint8_t,int32_t> Vector3DUint8; typedef Vector<3, uint8_t, int32_t> Vector3DUint8;
/// A 3D Vector of signed 16-bit values. /// A 3D Vector of signed 16-bit values.
typedef Vector<3,int16_t,int32_t> Vector3DInt16; typedef Vector<3, int16_t, int32_t> Vector3DInt16;
/// A 3D Vector of unsigned 16-bit values. /// A 3D Vector of unsigned 16-bit values.
typedef Vector<3,uint16_t,int32_t> Vector3DUint16; typedef Vector<3, uint16_t, int32_t> Vector3DUint16;
/// A 3D Vector of signed 32-bit values. /// A 3D Vector of signed 32-bit values.
typedef Vector<3,int32_t,int32_t> Vector3DInt32; typedef Vector<3, int32_t, int32_t> Vector3DInt32;
/// A 3D Vector of unsigned 32-bit values. /// A 3D Vector of unsigned 32-bit values.
typedef Vector<3,uint32_t,int32_t> Vector3DUint32; typedef Vector<3, uint32_t, int32_t> Vector3DUint32;
/// A 4D Vector of floats. /// A 4D Vector of floats.
typedef Vector<4,float,float> Vector4DFloat; typedef Vector<4, float, float> Vector4DFloat;
/// A 4D Vector of doubles. /// A 4D Vector of doubles.
typedef Vector<4,double,double> Vector4DDouble; typedef Vector<4, double, double> Vector4DDouble;
/// A 4D Vector of signed 8-bit values. /// A 4D Vector of signed 8-bit values.
typedef Vector<4,int8_t,int32_t> Vector4DInt8; typedef Vector<4, int8_t, int32_t> Vector4DInt8;
/// A 4D Vector of unsigned 8-bit values. /// A 4D Vector of unsigned 8-bit values.
typedef Vector<4,uint8_t,int32_t> Vector4DUint8; typedef Vector<4, uint8_t, int32_t> Vector4DUint8;
/// A 4D Vector of signed 16-bit values. /// A 4D Vector of signed 16-bit values.
typedef Vector<4,int16_t,int32_t> Vector4DInt16; typedef Vector<4, int16_t, int32_t> Vector4DInt16;
/// A 4D Vector of unsigned 16-bit values. /// A 4D Vector of unsigned 16-bit values.
typedef Vector<4,uint16_t,int32_t> Vector4DUint16; typedef Vector<4, uint16_t, int32_t> Vector4DUint16;
/// A 4D Vector of signed 32-bit values. /// A 4D Vector of signed 32-bit values.
typedef Vector<4,int32_t,int32_t> Vector4DInt32; typedef Vector<4, int32_t, int32_t> Vector4DInt32;
/// A 4D Vector of unsigned 32-bit values. /// A 4D Vector of unsigned 32-bit values.
typedef Vector<4,uint32_t,int32_t> Vector4DUint32; typedef Vector<4, uint32_t, int32_t> Vector4DUint32;
}//namespace PolyVox }//namespace PolyVox

View File

@ -24,7 +24,7 @@
namespace PolyVox namespace PolyVox
{ {
//-------------------------- Constructors, etc --------------------------------- //-------------------------- Constructors, etc ---------------------------------
/** /**
* Creates a Vector object but does not initialise it. * Creates a Vector object but does not initialise it.
*/ */
@ -34,28 +34,28 @@ namespace PolyVox
} }
/** /**
* Creates a Vector object and initialises all components with the given value. * Creates a Vector object and initialises all components with the given value.
* \param tFillValue The value to write to every component. * \param tFillValue The value to write to every component.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType>::Vector(StorageType tFillValue) Vector<Size, StorageType, OperationType>::Vector(StorageType tFillValue)
{ {
std::fill(m_tElements, m_tElements + Size, tFillValue); std::fill(m_tElements, m_tElements + Size, tFillValue);
} }
/** /**
* Creates a Vector object and initialises it with given values. * Creates a Vector object and initialises it with given values.
* \param x The X component to set. * \param x The X component to set.
* \param y The Y component to set. * \param y The Y component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y) Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y)
{ {
static_assert(Size == 2, "This constructor should only be used for vectors with two elements."); static_assert(Size == 2, "This constructor should only be used for vectors with two elements.");
m_tElements[0] = x; m_tElements[0] = x;
m_tElements[1] = y; m_tElements[1] = y;
} }
/** /**
* Creates a Vector3D object and initialises it with given values. * Creates a Vector3D object and initialises it with given values.
@ -63,8 +63,8 @@ namespace PolyVox
* \param y The Y component to set. * \param y The Y component to set.
* \param z the Z component to set. * \param z the Z component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y, StorageType z) Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y, StorageType z)
{ {
static_assert(Size == 3, "This constructor should only be used for vectors with three elements."); static_assert(Size == 3, "This constructor should only be used for vectors with three elements.");
@ -81,8 +81,8 @@ namespace PolyVox
* \param z The Z component to set. * \param z The Z component to set.
* \param w The W component to set. * \param w The W component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y, StorageType z, StorageType w) Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y, StorageType z, StorageType w)
{ {
static_assert(Size == 4, "This constructor should only be used for vectors with four elements."); static_assert(Size == 4, "This constructor should only be used for vectors with four elements.");
@ -92,41 +92,41 @@ namespace PolyVox
m_tElements[3] = w; m_tElements[3] = w;
} }
/** /**
* Copy constructor builds object based on object passed as parameter. * Copy constructor builds object based on object passed as parameter.
* \param vector A reference to the Vector to be copied. * \param vector A reference to the Vector to be copied.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, StorageType, OperationType>& vector) Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, StorageType, OperationType>& vector)
{ {
std::memcpy(m_tElements, vector.m_tElements, sizeof(StorageType) * Size); std::memcpy(m_tElements, vector.m_tElements, sizeof(StorageType)* Size);
} }
/** /**
* This copy constructor allows casting between vectors with different data types. * This copy constructor allows casting between vectors with different data types.
* It makes it possible to use code such as: * It makes it possible to use code such as:
* *
* Vector3DDouble v3dDouble(1.0,2.0,3.0); * Vector3DDouble v3dDouble(1.0,2.0,3.0);
* Vector3DFloat v3dFloat = static_cast<Vector3DFloat>(v3dDouble); //Casting * Vector3DFloat v3dFloat = static_cast<Vector3DFloat>(v3dDouble); //Casting
* *
* \param vector A reference to the Vector to be copied. * \param vector A reference to the Vector to be copied.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
template <typename CastType> template <typename CastType>
Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, CastType>& vector) Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, CastType>& vector)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] = static_cast<StorageType>(vector.getElement(ct)); m_tElements[ct] = static_cast<StorageType>(vector.getElement(ct));
} }
} }
/** /**
* Destroys the Vector. * Destroys the Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size, StorageType, OperationType>::~Vector(void) Vector<Size, StorageType, OperationType>::~Vector(void)
{ {
// We put the static asserts in the destructor because there is one one of these, // We put the static asserts in the destructor because there is one one of these,
// where as there are multiple constructors. // where as there are multiple constructors.
@ -135,213 +135,213 @@ namespace PolyVox
// behaviour of the constructor taking a single value, as this fills all elements // behaviour of the constructor taking a single value, as this fills all elements
// to that value rather than just the first one. // to that value rather than just the first one.
static_assert(Size > 1, "Vector must have a length greater than one."); static_assert(Size > 1, "Vector must have a length greater than one.");
} }
/** /**
* Assignment operator copies each element of first Vector to the second. * Assignment operator copies each element of first Vector to the second.
* \param rhs Vector to assign to. * \param rhs Vector to assign to.
* \return A reference to the result to allow chaining. * \return A reference to the result to allow chaining.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator=(const Vector<Size, StorageType, OperationType>& rhs) Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator=(const Vector<Size, StorageType, OperationType>& rhs)
{ {
if(this == &rhs) if (this == &rhs)
{ {
return *this; return *this;
} }
std::memcpy(m_tElements, rhs.m_tElements, sizeof(StorageType) * Size); std::memcpy(m_tElements, rhs.m_tElements, sizeof(StorageType)* Size);
return *this; return *this;
} }
/** /**
* Checks whether two Vectors are equal. * Checks whether two Vectors are equal.
* \param rhs The Vector to compare to. * \param rhs The Vector to compare to.
* \return true if the Vectors match. * \return true if the Vectors match.
* \see operator!= * \see operator!=
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline bool Vector<Size, StorageType, OperationType>::operator==(const Vector<Size, StorageType, OperationType> &rhs) const inline bool Vector<Size, StorageType, OperationType>::operator==(const Vector<Size, StorageType, OperationType> &rhs) const
{ {
bool equal = true; bool equal = true;
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
if(m_tElements[ct] != rhs.m_tElements[ct]) if (m_tElements[ct] != rhs.m_tElements[ct])
{ {
equal = false; equal = false;
break; break;
} }
} }
return equal; return equal;
} }
/** /**
* Checks whether two Vectors are not equal. * Checks whether two Vectors are not equal.
* \param rhs The Vector to compare to. * \param rhs The Vector to compare to.
* \return true if the Vectors do not match. * \return true if the Vectors do not match.
* \see operator== * \see operator==
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline bool Vector<Size, StorageType, OperationType>::operator!=(const Vector<Size, StorageType, OperationType> &rhs) const inline bool Vector<Size, StorageType, OperationType>::operator!=(const Vector<Size, StorageType, OperationType> &rhs) const
{ {
return !(*this == rhs); //Just call equality operator and invert the result. return !(*this == rhs); //Just call equality operator and invert the result.
} }
/** /**
* Addition operator adds corresponding elements of the two Vectors. * Addition operator adds corresponding elements of the two Vectors.
* \param rhs The Vector to add * \param rhs The Vector to add
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator+=(const Vector<Size, StorageType, OperationType>& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator+=(const Vector<Size, StorageType, OperationType>& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] += rhs.m_tElements[ct]; m_tElements[ct] += rhs.m_tElements[ct];
} }
return *this; return *this;
} }
/** /**
* Subtraction operator subtracts corresponding elements of one Vector from the other. * Subtraction operator subtracts corresponding elements of one Vector from the other.
* \param rhs The Vector to subtract * \param rhs The Vector to subtract
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator-=(const Vector<Size, StorageType, OperationType>& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator-=(const Vector<Size, StorageType, OperationType>& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] -= rhs.m_tElements[ct]; m_tElements[ct] -= rhs.m_tElements[ct];
} }
return *this; return *this;
} }
/** /**
* Multiplication operator multiplies corresponding elements of the two Vectors. * Multiplication operator multiplies corresponding elements of the two Vectors.
* \param rhs The Vector to multiply by * \param rhs The Vector to multiply by
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const Vector<Size, StorageType, OperationType>& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const Vector<Size, StorageType, OperationType>& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] *= rhs.m_tElements[ct]; m_tElements[ct] *= rhs.m_tElements[ct];
} }
return *this; return *this;
} }
/** /**
* Division operator divides corresponding elements of one Vector by the other. * Division operator divides corresponding elements of one Vector by the other.
* \param rhs The Vector to divide by * \param rhs The Vector to divide by
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const Vector<Size, StorageType, OperationType>& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const Vector<Size, StorageType, OperationType>& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] /= rhs.m_tElements[ct]; m_tElements[ct] /= rhs.m_tElements[ct];
} }
return *this; return *this;
} }
/** /**
* Multiplication operator multiplies each element of the Vector by a number. * Multiplication operator multiplies each element of the Vector by a number.
* \param rhs The number the Vector is multiplied by. * \param rhs The number the Vector is multiplied by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const StorageType& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const StorageType& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] *= rhs; m_tElements[ct] *= rhs;
} }
return *this; return *this;
} }
/** /**
* Division operator divides each element of the Vector by a number. * Division operator divides each element of the Vector by a number.
* \param rhs The number the Vector is divided by. * \param rhs The number the Vector is divided by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const StorageType& rhs) inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const StorageType& rhs)
{ {
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
m_tElements[ct] /= rhs; m_tElements[ct] /= rhs;
} }
return *this; return *this;
} }
/** /**
* Addition operator adds corresponding elements of the two Vectors. * Addition operator adds corresponding elements of the two Vectors.
* \param lhs The Vector to add to. * \param lhs The Vector to add to.
* \param rhs The Vector to add. * \param rhs The Vector to add.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator+(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) Vector<Size, StorageType, OperationType> operator+(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result += rhs; result += rhs;
return result; return result;
} }
/** /**
* Subtraction operator subtracts corresponding elements of one Vector from the other. * Subtraction operator subtracts corresponding elements of one Vector from the other.
* \param lhs The Vector to subtract from. * \param lhs The Vector to subtract from.
* \param rhs The Vector to subtract. * \param rhs The Vector to subtract.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator-(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) Vector<Size, StorageType, OperationType> operator-(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result -= rhs; result -= rhs;
return result; return result;
} }
/** /**
* Multiplication operator mulitplies corresponding elements of the two Vectors. * Multiplication operator mulitplies corresponding elements of the two Vectors.
* \param lhs The Vector to multiply. * \param lhs The Vector to multiply.
* \param rhs The Vector to multiply by. * \param rhs The Vector to multiply by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result *= rhs; result *= rhs;
return result; return result;
} }
/** /**
* Division operator divides corresponding elements of one Vector by the other. * Division operator divides corresponding elements of one Vector by the other.
* \param lhs The Vector to divide. * \param lhs The Vector to divide.
* \param rhs The Vector to divide by. * \param rhs The Vector to divide by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result /= rhs; result /= rhs;
return result; return result;
} }
/** /**
* Multiplication operator multiplies each element of the Vector by a number. * Multiplication operator multiplies each element of the Vector by a number.
* \param lhs The Vector to multiply. * \param lhs The Vector to multiply.
* \param rhs The number the Vector is multiplied by. * \param rhs The number the Vector is multiplied by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs) Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result *= rhs; result *= rhs;
return result; return result;
} }
@ -351,36 +351,36 @@ namespace PolyVox
* \param lhs The Vector to divide. * \param lhs The Vector to divide.
* \param rhs The number the Vector is divided by. * \param rhs The number the Vector is divided by.
* \return The resulting Vector. * \return The resulting Vector.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs) Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs)
{ {
Vector<Size,StorageType,OperationType> result = lhs; Vector<Size, StorageType, OperationType> result = lhs;
result /= rhs; result /= rhs;
return result; return result;
} }
/** /**
* Enables the Vector to be used intuitively with output streams such as cout. * Enables the Vector to be used intuitively with output streams such as cout.
* \param os The output stream to write to. * \param os The output stream to write to.
* \param vector The Vector to write to the stream. * \param vector The Vector to write to the stream.
* \return A reference to the output stream to allow chaining. * \return A reference to the output stream to allow chaining.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
std::ostream& operator<<(std::ostream& os, const Vector<Size, StorageType, OperationType>& vector) std::ostream& operator<<(std::ostream& os, const Vector<Size, StorageType, OperationType>& vector)
{ {
os << "("; os << "(";
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
os << vector.getElement(ct); os << vector.getElement(ct);
if(ct < (Size-1)) if (ct < (Size - 1))
{ {
os << ","; os << ",";
} }
} }
os << ")"; os << ")";
return os; return os;
} }
/** /**
* Returns the element at the given position. * Returns the element at the given position.
@ -390,7 +390,7 @@ namespace PolyVox
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const
{ {
if(index >= Size) if (index >= Size)
{ {
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element."); POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
} }
@ -398,34 +398,34 @@ namespace PolyVox
return m_tElements[index]; return m_tElements[index];
} }
/** /**
* \return A const reference to the X component of a 1, 2, 3, or 4 dimensional Vector. * \return A const reference to the X component of a 1, 2, 3, or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline StorageType Vector<Size, StorageType, OperationType>::getX(void) const inline StorageType Vector<Size, StorageType, OperationType>::getX(void) const
{ {
return m_tElements[0]; // This is fine, a Vector always contains at least two elements. return m_tElements[0]; // This is fine, a Vector always contains at least two elements.
} }
/** /**
* \return A const reference to the Y component of a 2, 3, or 4 dimensional Vector. * \return A const reference to the Y component of a 2, 3, or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline StorageType Vector<Size, StorageType, OperationType>::getY(void) const inline StorageType Vector<Size, StorageType, OperationType>::getY(void) const
{ {
return m_tElements[1]; // This is fine, a Vector always contains at least two elements. return m_tElements[1]; // This is fine, a Vector always contains at least two elements.
} }
/** /**
* \return A const reference to the Z component of a 3 or 4 dimensional Vector. * \return A const reference to the Z component of a 3 or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline StorageType Vector<Size, StorageType, OperationType>::getZ(void) const inline StorageType Vector<Size, StorageType, OperationType>::getZ(void) const
{ {
static_assert(Size >= 3, "You can only get the 'z' component from a vector with at least three elements."); static_assert(Size >= 3, "You can only get the 'z' component from a vector with at least three elements.");
return m_tElements[2]; return m_tElements[2];
} }
/** /**
* \return A const reference to the W component of a 4 dimensional Vector. * \return A const reference to the W component of a 4 dimensional Vector.
@ -436,7 +436,7 @@ namespace PolyVox
static_assert(Size >= 4, "You can only get the 'w' component from a vector with at least four elements."); static_assert(Size >= 4, "You can only get the 'w' component from a vector with at least four elements.");
return m_tElements[3]; return m_tElements[3];
} }
/** /**
* \param index The index of the element to set. * \param index The index of the element to set.
@ -445,7 +445,7 @@ namespace PolyVox
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue) inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue)
{ {
if(index >= Size) if (index >= Size)
{ {
POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element."); POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element.");
} }
@ -454,17 +454,17 @@ namespace PolyVox
} }
/** /**
* Sets several elements of a vector at once. * Sets several elements of a vector at once.
* \param x The X component to set. * \param x The X component to set.
* \param y The Y component to set. * \param y The Y component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y) inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y)
{ {
// This is fine, a Vector always contains at least two elements. // This is fine, a Vector always contains at least two elements.
m_tElements[0] = x; m_tElements[0] = x;
m_tElements[1] = y; m_tElements[1] = y;
} }
/** /**
* Sets several elements of a vector at once. * Sets several elements of a vector at once.
@ -472,8 +472,8 @@ namespace PolyVox
* \param y The Y component to set. * \param y The Y component to set.
* \param z The Z component to set. * \param z The Z component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y, StorageType z) inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y, StorageType z)
{ {
static_assert(Size >= 3, "You can only use this version of setElements() on a vector with at least three elements."); static_assert(Size >= 3, "You can only use this version of setElements() on a vector with at least three elements.");
@ -489,8 +489,8 @@ namespace PolyVox
* \param z The Z component to set. * \param z The Z component to set.
* \param w The W component to set. * \param w The W component to set.
*/ */
template <uint32_t Size,typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y, StorageType z, StorageType w) inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y, StorageType z, StorageType w)
{ {
static_assert(Size >= 4, "You can only use this version of setElements() on a vector with at least four elements."); static_assert(Size >= 4, "You can only use this version of setElements() on a vector with at least four elements.");
@ -503,141 +503,141 @@ namespace PolyVox
/** /**
* \param tX The new value for the X component of a 1, 2, 3, or 4 dimensional Vector. * \param tX The new value for the X component of a 1, 2, 3, or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setX(StorageType tX) inline void Vector<Size, StorageType, OperationType>::setX(StorageType tX)
{ {
m_tElements[0] = tX; // This is fine, a Vector always contains at least two elements. m_tElements[0] = tX; // This is fine, a Vector always contains at least two elements.
} }
/** /**
* \param tY The new value for the Y component of a 2, 3, or 4 dimensional Vector. * \param tY The new value for the Y component of a 2, 3, or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setY(StorageType tY) inline void Vector<Size, StorageType, OperationType>::setY(StorageType tY)
{ {
m_tElements[1] = tY; // This is fine, a Vector always contains at least two elements. m_tElements[1] = tY; // This is fine, a Vector always contains at least two elements.
} }
/** /**
* \param tZ The new value for the Z component of a 3 or 4 dimensional Vector. * \param tZ The new value for the Z component of a 3 or 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setZ(StorageType tZ) inline void Vector<Size, StorageType, OperationType>::setZ(StorageType tZ)
{ {
static_assert(Size >= 3, "You can only set the 'w' component from a vector with at least three elements."); static_assert(Size >= 3, "You can only set the 'w' component from a vector with at least three elements.");
m_tElements[2] = tZ; m_tElements[2] = tZ;
} }
/** /**
* \param tW The new value for the W component of a 4 dimensional Vector. * \param tW The new value for the W component of a 4 dimensional Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::setW(StorageType tW) inline void Vector<Size, StorageType, OperationType>::setW(StorageType tW)
{ {
static_assert(Size >= 4, "You can only set the 'w' component from a vector with at least four elements."); static_assert(Size >= 4, "You can only set the 'w' component from a vector with at least four elements.");
m_tElements[3] = tW; m_tElements[3] = tW;
} }
/** /**
* \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer. * \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer.
* \return The length of the Vector. * \return The length of the Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline float Vector<Size, StorageType, OperationType>::length(void) const inline float Vector<Size, StorageType, OperationType>::length(void) const
{ {
return sqrt(static_cast<float>(lengthSquared())); return sqrt(static_cast<float>(lengthSquared()));
} }
/** /**
* \return The squared length of the Vector. * \return The squared length of the Vector.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline OperationType Vector<Size, StorageType, OperationType>::lengthSquared(void) const inline OperationType Vector<Size, StorageType, OperationType>::lengthSquared(void) const
{ {
OperationType tLengthSquared = static_cast<OperationType>(0); OperationType tLengthSquared = static_cast<OperationType>(0);
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
tLengthSquared += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(m_tElements[ct]); tLengthSquared += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(m_tElements[ct]);
} }
return tLengthSquared; return tLengthSquared;
} }
/** /**
* This function is commutative, such that a.angleTo(b) == b.angleTo(a). The angle * This function is commutative, such that a.angleTo(b) == b.angleTo(a). The angle
* returned is in radians and varies between 0 and 3.14(pi). It is always positive. * returned is in radians and varies between 0 and 3.14(pi). It is always positive.
* *
* \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer. * \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer.
* *
* \param vector The Vector to find the angle to. * \param vector The Vector to find the angle to.
* \return The angle between them in radians. * \return The angle between them in radians.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline float Vector<Size, StorageType, OperationType>::angleTo(const Vector<Size, StorageType, OperationType>& vector) const inline float Vector<Size, StorageType, OperationType>::angleTo(const Vector<Size, StorageType, OperationType>& vector) const
{ {
return acos(static_cast<float>(dot(vector)) / (vector.length() * this->length())); return acos(static_cast<float>(dot(vector)) / (vector.length() * this->length()));
} }
/** /**
* This function is used to calculate the cross product of two Vectors. * This function is used to calculate the cross product of two Vectors.
* The cross product is the Vector which is perpendicular to the two * The cross product is the Vector which is perpendicular to the two
* given Vectors. It is worth remembering that, unlike the dot product, * given Vectors. It is worth remembering that, unlike the dot product,
* it is not commutative. E.g a.b != b.a. The cross product obeys the * it is not commutative. E.g a.b != b.a. The cross product obeys the
* right-hand rule such that if the two vectors are given by the index * right-hand rule such that if the two vectors are given by the index
* finger and middle finger respectively then the cross product is given * finger and middle finger respectively then the cross product is given
* by the thumb. * by the thumb.
* \param vector The vector to cross with this * \param vector The vector to cross with this
* \return The value of the cross product. * \return The value of the cross product.
* \see dot() * \see dot()
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline Vector<Size, StorageType, OperationType> Vector<Size, StorageType, OperationType>::cross(const Vector<Size, StorageType, OperationType>& vector) const inline Vector<Size, StorageType, OperationType> Vector<Size, StorageType, OperationType>::cross(const Vector<Size, StorageType, OperationType>& vector) const
{ {
StorageType i = vector.getZ() * this->getY() - vector.getY() * this->getZ(); StorageType i = vector.getZ() * this->getY() - vector.getY() * this->getZ();
StorageType j = vector.getX() * this->getZ() - vector.getZ() * this->getX(); StorageType j = vector.getX() * this->getZ() - vector.getZ() * this->getX();
StorageType k = vector.getY() * this->getX() - vector.getX() * this->getY(); StorageType k = vector.getY() * this->getX() - vector.getX() * this->getY();
return Vector<Size, StorageType, OperationType>(i,j,k); return Vector<Size, StorageType, OperationType>(i, j, k);
} }
/** /**
* Calculates the dot product of the Vector and the parameter. * Calculates the dot product of the Vector and the parameter.
* This function is commutative, such that a.dot(b) == b.dot(a). * This function is commutative, such that a.dot(b) == b.dot(a).
* \param rhs The Vector to find the dot product with. * \param rhs The Vector to find the dot product with.
* \return The value of the dot product. * \return The value of the dot product.
* \see cross() * \see cross()
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline OperationType Vector<Size, StorageType, OperationType>::dot(const Vector<Size, StorageType, OperationType>& rhs) const inline OperationType Vector<Size, StorageType, OperationType>::dot(const Vector<Size, StorageType, OperationType>& rhs) const
{ {
OperationType dotProduct = static_cast<OperationType>(0); OperationType dotProduct = static_cast<OperationType>(0);
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
dotProduct += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(rhs.m_tElements[ct]); dotProduct += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(rhs.m_tElements[ct]);
} }
return dotProduct; return dotProduct;
} }
/** /**
* Divides the i, j, and k components by the length to give a Vector of length 1.0. If the vector is * Divides the i, j, and k components by the length to give a Vector of length 1.0. If the vector is
* very short (or zero) then a divide by zero may cause elements to take on invalid values. You may * very short (or zero) then a divide by zero may cause elements to take on invalid values. You may
* want to check for this before normalising. * want to check for this before normalising.
* *
* \note You should not attempt to normalise a vector whose StorageType is an integer. * \note You should not attempt to normalise a vector whose StorageType is an integer.
*/ */
template <uint32_t Size, typename StorageType, typename OperationType> template <uint32_t Size, typename StorageType, typename OperationType>
inline void Vector<Size, StorageType, OperationType>::normalise(void) inline void Vector<Size, StorageType, OperationType>::normalise(void)
{ {
float fLength = this->length(); float fLength = this->length();
// We could wait until the NAN occurs before throwing, but then we'd have to add some roll-back code. // We could wait until the NAN occurs before throwing, but then we'd have to add some roll-back code.
// This seems like a lot of overhead for a common operation which should rarely go wrong. // This seems like a lot of overhead for a common operation which should rarely go wrong.
if(fLength <= 0.0001) if (fLength <= 0.0001)
{ {
POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero"); POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero");
} }
for(uint32_t ct = 0; ct < Size; ++ct) for (uint32_t ct = 0; ct < Size; ++ct)
{ {
// Standard float rules apply for divide-by-zero // Standard float rules apply for divide-by-zero
m_tElements[ct] /= fLength; m_tElements[ct] /= fLength;
@ -645,5 +645,5 @@ namespace PolyVox
//This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen. //This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen.
POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?"); POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?");
} }
} }
}//namespace PolyVox }//namespace PolyVox

View File

@ -37,9 +37,9 @@ namespace PolyVox
template< typename SrcVolumeType, typename DstVolumeType> template< typename SrcVolumeType, typename DstVolumeType>
VolumeResampler<SrcVolumeType, DstVolumeType>::VolumeResampler(SrcVolumeType* pVolSrc, const Region &regSrc, DstVolumeType* pVolDst, const Region& regDst) VolumeResampler<SrcVolumeType, DstVolumeType>::VolumeResampler(SrcVolumeType* pVolSrc, const Region &regSrc, DstVolumeType* pVolDst, const Region& regDst)
:m_pVolSrc(pVolSrc) :m_pVolSrc(pVolSrc)
,m_regSrc(regSrc) , m_regSrc(regSrc)
,m_pVolDst(pVolDst) , m_pVolDst(pVolDst)
,m_regDst(regDst) , m_regDst(regDst)
{ {
} }
@ -54,7 +54,7 @@ namespace PolyVox
int32_t uDstHeight = m_regDst.getUpperY() - m_regDst.getLowerY() + 1; int32_t uDstHeight = m_regDst.getUpperY() - m_regDst.getLowerY() + 1;
int32_t uDstDepth = m_regDst.getUpperZ() - m_regDst.getLowerZ() + 1; int32_t uDstDepth = m_regDst.getUpperZ() - m_regDst.getLowerZ() + 1;
if((uSrcWidth == uDstWidth) && (uSrcHeight == uDstHeight) && (uSrcDepth == uDstDepth)) if ((uSrcWidth == uDstWidth) && (uSrcHeight == uDstHeight) && (uSrcDepth == uDstDepth))
{ {
resampleSameSize(); resampleSameSize();
} }
@ -67,15 +67,15 @@ namespace PolyVox
template< typename SrcVolumeType, typename DstVolumeType> template< typename SrcVolumeType, typename DstVolumeType>
void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleSameSize() void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleSameSize()
{ {
for(int32_t sz = m_regSrc.getLowerZ(), dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); sz++, dz++) for (int32_t sz = m_regSrc.getLowerZ(), dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); sz++, dz++)
{ {
for(int32_t sy = m_regSrc.getLowerY(), dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); sy++, dy++) for (int32_t sy = m_regSrc.getLowerY(), dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); sy++, dy++)
{ {
for(int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++,dx++) for (int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++, dx++)
{ {
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz); const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx, sy, sz);
const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel); const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel);
m_pVolDst->setVoxel(dx,dy,dz,tDstVoxel); m_pVolDst->setVoxel(dx, dy, dz, tDstVoxel);
} }
} }
} }
@ -84,25 +84,25 @@ namespace PolyVox
template< typename SrcVolumeType, typename DstVolumeType> template< typename SrcVolumeType, typename DstVolumeType>
void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleArbitrary() void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleArbitrary()
{ {
float srcWidth = m_regSrc.getWidthInCells(); float srcWidth = m_regSrc.getWidthInCells();
float srcHeight = m_regSrc.getHeightInCells(); float srcHeight = m_regSrc.getHeightInCells();
float srcDepth = m_regSrc.getDepthInCells(); float srcDepth = m_regSrc.getDepthInCells();
float dstWidth = m_regDst.getWidthInCells(); float dstWidth = m_regDst.getWidthInCells();
float dstHeight = m_regDst.getHeightInCells(); float dstHeight = m_regDst.getHeightInCells();
float dstDepth = m_regDst.getDepthInCells(); float dstDepth = m_regDst.getDepthInCells();
float fScaleX = srcWidth / dstWidth; float fScaleX = srcWidth / dstWidth;
float fScaleY = srcHeight / dstHeight; float fScaleY = srcHeight / dstHeight;
float fScaleZ = srcDepth / dstDepth; float fScaleZ = srcDepth / dstDepth;
typename SrcVolumeType::Sampler sampler(m_pVolSrc); typename SrcVolumeType::Sampler sampler(m_pVolSrc);
for(int32_t dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); dz++) for (int32_t dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); dz++)
{ {
for(int32_t dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); dy++) for (int32_t dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); dy++)
{ {
for(int32_t dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); dx++) for (int32_t dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); dx++)
{ {
float sx = (dx - m_regDst.getLowerX()) * fScaleX; float sx = (dx - m_regDst.getLowerX()) * fScaleX;
float sy = (dy - m_regDst.getLowerY()) * fScaleY; float sy = (dy - m_regDst.getLowerY()) * fScaleY;
@ -112,7 +112,7 @@ namespace PolyVox
sy += m_regSrc.getLowerY(); sy += m_regSrc.getLowerY();
sz += m_regSrc.getLowerZ(); sz += m_regSrc.getLowerZ();
sampler.setPosition(sx,sy,sz); sampler.setPosition(sx, sy, sz);
const typename SrcVolumeType::VoxelType& voxel000 = sampler.peekVoxel0px0py0pz(); const typename SrcVolumeType::VoxelType& voxel000 = sampler.peekVoxel0px0py0pz();
const typename SrcVolumeType::VoxelType& voxel001 = sampler.peekVoxel0px0py1pz(); const typename SrcVolumeType::VoxelType& voxel001 = sampler.peekVoxel0px0py1pz();
const typename SrcVolumeType::VoxelType& voxel010 = sampler.peekVoxel0px1py0pz(); const typename SrcVolumeType::VoxelType& voxel010 = sampler.peekVoxel0px1py0pz();
@ -128,10 +128,10 @@ namespace PolyVox
sy = modf(sy, &dummy); sy = modf(sy, &dummy);
sz = modf(sz, &dummy); sz = modf(sz, &dummy);
typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000,voxel100,voxel010,voxel110,voxel001,voxel101,voxel011,voxel111,sx,sy,sz); typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000, voxel100, voxel010, voxel110, voxel001, voxel101, voxel011, voxel111, sx, sy, sz);
typename DstVolumeType::VoxelType result = static_cast<typename DstVolumeType::VoxelType>(tInterpolatedValue); typename DstVolumeType::VoxelType result = static_cast<typename DstVolumeType::VoxelType>(tInterpolatedValue);
m_pVolDst->setVoxel(dx,dy,dz,result); m_pVolDst->setVoxel(dx, dy, dz, result);
} }
} }
} }

View File

@ -36,13 +36,13 @@ template< typename VolumeType>
bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos) bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos)
{ {
//Voxels are considered valid candidates for the path if they are inside the volume... //Voxels are considered valid candidates for the path if they are inside the volume...
if(volData->getEnclosingRegion().containsPoint(v3dPos) == false) if (volData->getEnclosingRegion().containsPoint(v3dPos) == false)
{ {
return false; return false;
} }
typename VolumeType::VoxelType voxel = volData->getVoxel(v3dPos); typename VolumeType::VoxelType voxel = volData->getVoxel(v3dPos);
if(voxel != 0) if (voxel != 0)
{ {
return false; return false;
} }
@ -52,61 +52,61 @@ bool testVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos)
void TestAStarPathfinder::testExecute() void TestAStarPathfinder::testExecute()
{ {
const Vector3DInt32 expectedResult[] = const Vector3DInt32 expectedResult[] =
{ {
Vector3DInt32(0,0,0), Vector3DInt32(0, 0, 0),
Vector3DInt32(1,1,1), Vector3DInt32(1, 1, 1),
Vector3DInt32(2,1,2), Vector3DInt32(2, 1, 2),
Vector3DInt32(3,1,3), Vector3DInt32(3, 1, 3),
Vector3DInt32(3,1,4), Vector3DInt32(3, 1, 4),
Vector3DInt32(3,1,5), Vector3DInt32(3, 1, 5),
Vector3DInt32(3,1,6), Vector3DInt32(3, 1, 6),
Vector3DInt32(3,1,7), Vector3DInt32(3, 1, 7),
Vector3DInt32(4,2,8), Vector3DInt32(4, 2, 8),
Vector3DInt32(5,3,9), Vector3DInt32(5, 3, 9),
Vector3DInt32(5,3,10), Vector3DInt32(5, 3, 10),
Vector3DInt32(5,3,11), Vector3DInt32(5, 3, 11),
Vector3DInt32(6,4,12), Vector3DInt32(6, 4, 12),
Vector3DInt32(7,5,13), Vector3DInt32(7, 5, 13),
Vector3DInt32(8,6,13), Vector3DInt32(8, 6, 13),
Vector3DInt32(9,7,13), Vector3DInt32(9, 7, 13),
Vector3DInt32(9,8,13), Vector3DInt32(9, 8, 13),
Vector3DInt32(10,9,13), Vector3DInt32(10, 9, 13),
Vector3DInt32(11,10,14), Vector3DInt32(11, 10, 14),
Vector3DInt32(12,11,15), Vector3DInt32(12, 11, 15),
Vector3DInt32(13,12,15), Vector3DInt32(13, 12, 15),
Vector3DInt32(14,13,15), Vector3DInt32(14, 13, 15),
Vector3DInt32(14,14,15), Vector3DInt32(14, 14, 15),
Vector3DInt32(15,15,15) Vector3DInt32(15, 15, 15)
}; };
const int32_t uVolumeSideLength = 16; const int32_t uVolumeSideLength = 16;
//Create a volume //Create a volume
RawVolume<uint8_t> volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(uVolumeSideLength-1, uVolumeSideLength-1, uVolumeSideLength-1))); RawVolume<uint8_t> volData(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)));
//Clear the volume //Clear the volume
for(int z = 0; z < uVolumeSideLength; z++) for (int z = 0; z < uVolumeSideLength; z++)
{ {
for(int y = 0; y < uVolumeSideLength; y++) for (int y = 0; y < uVolumeSideLength; y++)
{ {
for(int x = 0; x < uVolumeSideLength; x++) for (int x = 0; x < uVolumeSideLength; x++)
{ {
uint8_t solidVoxel(0); uint8_t solidVoxel(0);
volData.setVoxel(x,y,z,solidVoxel); volData.setVoxel(x, y, z, solidVoxel);
} }
} }
} }
//Place a solid cube in the middle of it //Place a solid cube in the middle of it
for(int z = 4; z < 12; z++) for (int z = 4; z < 12; z++)
{ {
for(int y = 4; y < 12; y++) for (int y = 4; y < 12; y++)
{ {
for(int x = 4; x < 12; x++) for (int x = 4; x < 12; x++)
{ {
uint8_t solidVoxel(1); uint8_t solidVoxel(1);
volData.setVoxel(x,y,z,solidVoxel); volData.setVoxel(x, y, z, solidVoxel);
} }
} }
} }
@ -115,20 +115,20 @@ void TestAStarPathfinder::testExecute()
std::list<Vector3DInt32> result; std::list<Vector3DInt32> result;
//Create an AStarPathfinder //Create an AStarPathfinder
AStarPathfinderParams< RawVolume<uint8_t> > params(&volData, Vector3DInt32(0,0,0), Vector3DInt32(15,15,15), &result, 1.0f, 10000, TwentySixConnected, &testVoxelValidator<RawVolume<uint8_t> >); AStarPathfinderParams< RawVolume<uint8_t> > params(&volData, Vector3DInt32(0, 0, 0), Vector3DInt32(15, 15, 15), &result, 1.0f, 10000, TwentySixConnected, &testVoxelValidator<RawVolume<uint8_t> >);
AStarPathfinder< RawVolume<uint8_t> > pathfinder(params); AStarPathfinder< RawVolume<uint8_t> > pathfinder(params);
//Execute the pathfinder. //Execute the pathfinder.
QBENCHMARK { QBENCHMARK{
pathfinder.execute(); pathfinder.execute();
} }
//Make sure the right number of steps were created. //Make sure the right number of steps were created.
QCOMPARE(result.size(), static_cast<size_t>(24)); QCOMPARE(result.size(), static_cast<size_t>(24));
//Make sure that each step is correct. //Make sure that each step is correct.
uint32_t uExpectedIndex = 0; uint32_t uExpectedIndex = 0;
for(std::list<Vector3DInt32>::iterator iterResult = result.begin(); iterResult != result.end(); iterResult++) for (std::list<Vector3DInt32>::iterator iterResult = result.begin(); iterResult != result.end(); iterResult++)
{ {
Vector3DInt32 res = *iterResult; Vector3DInt32 res = *iterResult;
Vector3DInt32 exp = expectedResult[uExpectedIndex]; Vector3DInt32 exp = expectedResult[uExpectedIndex];

View File

@ -62,7 +62,7 @@ void TestAmbientOcclusionGenerator::testExecute()
//Create two solid walls at opposite sides of the volume //Create two solid walls at opposite sides of the volume
for (int32_t z = 0; z < g_uVolumeSideLength; z++) for (int32_t z = 0; z < g_uVolumeSideLength; z++)
{ {
if((z < 20) || (z > g_uVolumeSideLength - 20)) if ((z < 20) || (z > g_uVolumeSideLength - 20))
{ {
for (int32_t y = 0; y < g_uVolumeSideLength; y++) for (int32_t y = 0; y < g_uVolumeSideLength; y++)
{ {
@ -80,21 +80,21 @@ void TestAmbientOcclusionGenerator::testExecute()
// Calculate the ambient occlusion values // Calculate the ambient occlusion values
IsVoxelTransparent isVoxelTransparent; IsVoxelTransparent isVoxelTransparent;
QBENCHMARK { QBENCHMARK{
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 255, isVoxelTransparent); calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 255, isVoxelTransparent);
} }
//Check the results by sampling along a line though the centre of the volume. Because //Check the results by sampling along a line though the centre of the volume. Because
//of the two walls we added, samples in the middle are darker than those at the edge. //of the two walls we added, samples in the middle are darker than those at the edge.
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 0, 16)), 178); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 0, 16)), 178);
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 8, 16)), 109); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 8, 16)), 109);
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 16, 16)), 103); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 16, 16)), 103);
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 24, 16)), 123); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 24, 16)), 123);
QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 31, 16)), 173); QCOMPARE(static_cast<int>(ambientOcclusionResult(16, 31, 16)), 173);
//Just run a quick test to make sure that it compiles when taking a function pointer //Just run a quick test to make sure that it compiles when taking a function pointer
calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 8, &isVoxelTransparentFunction); calculateAmbientOcclusion(&volData, &ambientOcclusionResult, region, 32.0f, 8, &isVoxelTransparentFunction);
//Also test it using a lambda //Also test it using a lambda
//calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, [](uint8_t voxel){return voxel == 0;}); //calculateAmbientOcclusion(&volData, &ambientOcclusionResult, volData.getEnclosingRegion(), 32.0f, 8, [](uint8_t voxel){return voxel == 0;});
} }

View File

@ -94,11 +94,11 @@ void TestArray::testReadWrite()
int ct = 1; int ct = 1;
int expectedTotal = 0; int expectedTotal = 0;
for(int z = 0; z < depth; z++) for (int z = 0; z < depth; z++)
{ {
for(int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for(int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
myArray(x, y, z) = ct; myArray(x, y, z) = ct;
expectedTotal += myArray(x, y, z); expectedTotal += myArray(x, y, z);
@ -109,11 +109,11 @@ void TestArray::testReadWrite()
ct = 1; ct = 1;
int total = 0; int total = 0;
for(int z = 0; z < depth; z++) for (int z = 0; z < depth; z++)
{ {
for(int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for(int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
QCOMPARE(myArray(x, y, z), ct); QCOMPARE(myArray(x, y, z), ct);
total += myArray(x, y, z); total += myArray(x, y, z);

View File

@ -36,7 +36,7 @@ void TestLowPassFilter::testExecute()
{ {
const int32_t g_uVolumeSideLength = 8; const int32_t g_uVolumeSideLength = 8;
Region reg(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)); Region reg(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1));
//Create empty volume //Create empty volume
RawVolume<Density8> volData(reg); RawVolume<Density8> volData(reg);
@ -48,7 +48,7 @@ void TestLowPassFilter::testExecute()
{ {
for (int32_t x = 0; x < g_uVolumeSideLength; x++) for (int32_t x = 0; x < g_uVolumeSideLength; x++)
{ {
if(x % 2 == 0) if (x % 2 == 0)
{ {
Density8 voxel(32); Density8 voxel(32);
volData.setVoxel(x, y, z, voxel); volData.setVoxel(x, y, z, voxel);
@ -62,30 +62,30 @@ void TestLowPassFilter::testExecute()
LowPassFilter< RawVolume<Density8>, RawVolume<Density8>, Density16 > lowPassfilter(&volData, reg, &resultVolume, reg, 3); LowPassFilter< RawVolume<Density8>, RawVolume<Density8>, Density16 > lowPassfilter(&volData, reg, &resultVolume, reg, 3);
//Test the normal implementation //Test the normal implementation
QBENCHMARK { QBENCHMARK{
lowPassfilter.execute(); lowPassfilter.execute();
} }
QCOMPARE(resultVolume.getVoxel(0,0,0), Density8(4)); QCOMPARE(resultVolume.getVoxel(0, 0, 0), Density8(4));
QCOMPARE(resultVolume.getVoxel(1,1,1), Density8(21)); QCOMPARE(resultVolume.getVoxel(1, 1, 1), Density8(21));
QCOMPARE(resultVolume.getVoxel(2,2,2), Density8(10)); QCOMPARE(resultVolume.getVoxel(2, 2, 2), Density8(10));
QCOMPARE(resultVolume.getVoxel(3,3,3), Density8(21)); QCOMPARE(resultVolume.getVoxel(3, 3, 3), Density8(21));
QCOMPARE(resultVolume.getVoxel(4,4,4), Density8(10)); QCOMPARE(resultVolume.getVoxel(4, 4, 4), Density8(10));
QCOMPARE(resultVolume.getVoxel(5,5,5), Density8(21)); QCOMPARE(resultVolume.getVoxel(5, 5, 5), Density8(21));
QCOMPARE(resultVolume.getVoxel(6,6,6), Density8(10)); QCOMPARE(resultVolume.getVoxel(6, 6, 6), Density8(10));
QCOMPARE(resultVolume.getVoxel(7,7,7), Density8(4)); QCOMPARE(resultVolume.getVoxel(7, 7, 7), Density8(4));
//Test the SAT implmentation //Test the SAT implmentation
QBENCHMARK { QBENCHMARK{
lowPassfilter.executeSAT(); lowPassfilter.executeSAT();
} }
QCOMPARE(resultVolume.getVoxel(0,0,0), Density8(4)); QCOMPARE(resultVolume.getVoxel(0, 0, 0), Density8(4));
QCOMPARE(resultVolume.getVoxel(1,1,1), Density8(21)); QCOMPARE(resultVolume.getVoxel(1, 1, 1), Density8(21));
QCOMPARE(resultVolume.getVoxel(2,2,2), Density8(10)); QCOMPARE(resultVolume.getVoxel(2, 2, 2), Density8(10));
QCOMPARE(resultVolume.getVoxel(3,3,3), Density8(21)); QCOMPARE(resultVolume.getVoxel(3, 3, 3), Density8(21));
QCOMPARE(resultVolume.getVoxel(4,4,4), Density8(10)); QCOMPARE(resultVolume.getVoxel(4, 4, 4), Density8(10));
QCOMPARE(resultVolume.getVoxel(5,5,5), Density8(21)); QCOMPARE(resultVolume.getVoxel(5, 5, 5), Density8(21));
QCOMPARE(resultVolume.getVoxel(6,6,6), Density8(10)); QCOMPARE(resultVolume.getVoxel(6, 6, 6), Density8(10));
QCOMPARE(resultVolume.getVoxel(7,7,7), Density8(4)); QCOMPARE(resultVolume.getVoxel(7, 7, 7), Density8(4));
} }
QTEST_MAIN(TestLowPassFilter) QTEST_MAIN(TestLowPassFilter)

View File

@ -42,7 +42,7 @@ void TestPicking::testExecute()
{ {
for (int32_t x = 0; x < uVolumeSideLength; x++) for (int32_t x = 0; x < uVolumeSideLength; x++)
{ {
if((x > uVolumeSideLength/2)) //x > 16 is filled if ((x > uVolumeSideLength / 2)) //x > 16 is filled
{ {
volData.setVoxel(x, y, z, 100); volData.setVoxel(x, y, z, 100);
} }
@ -56,13 +56,13 @@ void TestPicking::testExecute()
const int8_t emptyVoxelExample = 0; //A voxel value of zero will represent empty space. const int8_t emptyVoxelExample = 0; //A voxel value of zero will represent empty space.
PickResult resultHit = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength, 0, 0), emptyVoxelExample); PickResult resultHit = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength, 0, 0), emptyVoxelExample);
QCOMPARE(resultHit.didHit, true); QCOMPARE(resultHit.didHit, true);
QCOMPARE(resultHit.hitVoxel, Vector3DInt32((uVolumeSideLength / 2) + 1, uVolumeSideLength / 2, uVolumeSideLength / 2)); QCOMPARE(resultHit.hitVoxel, Vector3DInt32((uVolumeSideLength / 2) + 1, uVolumeSideLength / 2, uVolumeSideLength / 2));
QCOMPARE(resultHit.previousVoxel, Vector3DInt32((uVolumeSideLength / 2), uVolumeSideLength / 2, uVolumeSideLength / 2)); QCOMPARE(resultHit.previousVoxel, Vector3DInt32((uVolumeSideLength / 2), uVolumeSideLength / 2, uVolumeSideLength / 2));
PickResult resultMiss = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength / 2, uVolumeSideLength, uVolumeSideLength), emptyVoxelExample); PickResult resultMiss = pickVoxel(&volData, Vector3DFloat(0, uVolumeSideLength / 2, uVolumeSideLength / 2), Vector3DFloat(uVolumeSideLength / 2, uVolumeSideLength, uVolumeSideLength), emptyVoxelExample);
QCOMPARE(resultMiss.didHit, false); QCOMPARE(resultMiss.didHit, false);
} }

View File

@ -44,7 +44,7 @@ class RaycastTestFunctor
public: public:
RaycastTestFunctor() RaycastTestFunctor()
:m_uVoxelsTouched(0) :m_uVoxelsTouched(0)
,m_bRayLeftVolume(false) , m_bRayLeftVolume(false)
{ {
} }
@ -55,7 +55,7 @@ public:
// For this particular test we know that we are always starting a ray inside the volume, // For this particular test we know that we are always starting a ray inside the volume,
// so if it ever leaves the volume we know it can't go back in and so we can terminate early. // so if it ever leaves the volume we know it can't go back in and so we can terminate early.
// This optimisation is worthwhile because samplers get slow once outside the volume. // This optimisation is worthwhile because samplers get slow once outside the volume.
if(!sampler.isCurrentPositionValid()) if (!sampler.isCurrentPositionValid())
{ {
m_bRayLeftVolume = true; m_bRayLeftVolume = true;
return false; return false;
@ -81,20 +81,20 @@ void TestRaycast::testExecute()
{ {
for (int32_t x = 0; x < uVolumeSideLength; x++) for (int32_t x = 0; x < uVolumeSideLength; x++)
{ {
if((x == 0) || (x == uVolumeSideLength-1) || (y == 0) || (y == uVolumeSideLength-1)) if ((x == 0) || (x == uVolumeSideLength - 1) || (y == 0) || (y == uVolumeSideLength - 1))
{ {
volData.setVoxel(x, y, z, 100); volData.setVoxel(x, y, z, 100);
} }
else else
{ {
volData.setVoxel(x, y, z, -100); volData.setVoxel(x, y, z, -100);
} }
} }
} }
} }
//Cast rays from the centre. Roughly 2/3 should escape. //Cast rays from the centre. Roughly 2/3 should escape.
Vector3DFloat start (uVolumeSideLength / 2, uVolumeSideLength / 2, uVolumeSideLength / 2); Vector3DFloat start(uVolumeSideLength / 2, uVolumeSideLength / 2, uVolumeSideLength / 2);
// We could have counted the total number of hits in the same way as the total number of voxels // We could have counted the total number of hits in the same way as the total number of voxels
// touched, but for demonstration and testing purposes we are making use of the raycast return value // touched, but for demonstration and testing purposes we are making use of the raycast return value
@ -103,7 +103,7 @@ void TestRaycast::testExecute()
uint32_t uTotalVoxelsTouched = 0; uint32_t uTotalVoxelsTouched = 0;
// Cast a large number of random rays // Cast a large number of random rays
for(int ct = 0; ct < 1000000; ct++) for (int ct = 0; ct < 1000000; ct++)
{ {
RaycastTestFunctor raycastTestFunctor; RaycastTestFunctor raycastTestFunctor;
RaycastResult result = raycastWithDirection(&volData, start, randomUnitVectors[ct % 1024] * 1000.0f, raycastTestFunctor); RaycastResult result = raycastWithDirection(&volData, start, randomUnitVectors[ct % 1024] * 1000.0f, raycastTestFunctor);
@ -112,11 +112,11 @@ void TestRaycast::testExecute()
// If the raycast completed then we know it did not hit anything.If it was interupted then it // If the raycast completed then we know it did not hit anything.If it was interupted then it
// probably hit something, unless we noted that the reason it was interupted was that it left the volume. // probably hit something, unless we noted that the reason it was interupted was that it left the volume.
if((result == RaycastResults::Interupted) && (raycastTestFunctor.m_bRayLeftVolume == false)) if ((result == RaycastResults::Interupted) && (raycastTestFunctor.m_bRayLeftVolume == false))
{ {
hits++; hits++;
} }
} }
// Check the number of hits. // Check the number of hits.
QCOMPARE(hits, 687494); QCOMPARE(hits, 687494);

View File

@ -32,9 +32,9 @@ using namespace PolyVox;
void TestRegion::testEquality() void TestRegion::testEquality()
{ {
Region reg1(1,2,3,4,5,6); Region reg1(1, 2, 3, 4, 5, 6);
Region reg2(0,0,0,10,20,30); Region reg2(0, 0, 0, 10, 20, 30);
Region reg3(Vector3DInt32(1,2,3), Vector3DInt32(4,5,6)); Region reg3(Vector3DInt32(1, 2, 3), Vector3DInt32(4, 5, 6));
QCOMPARE(reg1 != reg2, true); QCOMPARE(reg1 != reg2, true);
QCOMPARE(reg1 == reg3, true); QCOMPARE(reg1 == reg3, true);

View File

@ -46,17 +46,17 @@ public:
//in the future //in the future
//typedef BaseVolume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. See http://goo.gl/qu1wn //typedef BaseVolume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. See http://goo.gl/qu1wn
//class Sampler : public VolumeOfVoxelType::template Sampler< VolumeSubclass<VoxelType> > //class Sampler : public VolumeOfVoxelType::template Sampler< VolumeSubclass<VoxelType> >
#if defined(_MSC_VER) #if defined(_MSC_VER)
class Sampler : public BaseVolume<VoxelType>::Sampler< VolumeSubclass<VoxelType> > //This line works on VS2010 class Sampler : public BaseVolume<VoxelType>::Sampler< VolumeSubclass<VoxelType> > //This line works on VS2010
#else #else
class Sampler : public BaseVolume<VoxelType>::template Sampler< VolumeSubclass<VoxelType> > //This line works on GCC class Sampler : public BaseVolume<VoxelType>::template Sampler< VolumeSubclass<VoxelType> > //This line works on GCC
#endif #endif
{ {
public: public:
Sampler(VolumeSubclass<VoxelType>* volume) Sampler(VolumeSubclass<VoxelType>* volume)
:BaseVolume<VoxelType>::template Sampler< VolumeSubclass<VoxelType> >(volume) :BaseVolume<VoxelType>::template Sampler< VolumeSubclass<VoxelType> >(volume)
{ {
this->mVolume = volume; this->mVolume = volume;
} }
//~Sampler(); //~Sampler();
}; };
@ -66,7 +66,7 @@ public:
:BaseVolume<VoxelType>() :BaseVolume<VoxelType>()
, mVolumeData(regValid.getWidthInVoxels(), regValid.getHeightInVoxels(), regValid.getDepthInVoxels()) , mVolumeData(regValid.getWidthInVoxels(), regValid.getHeightInVoxels(), regValid.getDepthInVoxels())
{ {
//mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth())); //mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth()));
} }
/// Destructor /// Destructor
~VolumeSubclass() {}; ~VolumeSubclass() {};
@ -97,7 +97,7 @@ public:
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates /// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) bool setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{ {
if( (uXPos >= 0) && (uXPos < static_cast<int32_t>(mVolumeData.getDimension(0))) && if ((uXPos >= 0) && (uXPos < static_cast<int32_t>(mVolumeData.getDimension(0))) &&
(uYPos >= 0) && (uYPos < static_cast<int32_t>(mVolumeData.getDimension(1))) && (uYPos >= 0) && (uYPos < static_cast<int32_t>(mVolumeData.getDimension(1))) &&
(uZPos >= 0) && (uZPos < static_cast<int32_t>(mVolumeData.getDimension(2)))) (uZPos >= 0) && (uZPos < static_cast<int32_t>(mVolumeData.getDimension(2))))
{ {
@ -115,7 +115,7 @@ public:
/// Calculates approximatly how many bytes of memory the volume is currently using. /// Calculates approximatly how many bytes of memory the volume is currently using.
uint32_t calculateSizeInBytes(void) { return 0; } uint32_t calculateSizeInBytes(void) { return 0; }
private: private:
Array<3, VoxelType> mVolumeData; Array<3, VoxelType> mVolumeData;
}; };
@ -131,7 +131,7 @@ void TestVolumeSubclass::testExtractSurface()
for (int32_t x = 0; x < region.getWidthInVoxels(); x++) for (int32_t x = 0; x < region.getWidthInVoxels(); x++)
{ {
Material8 mat(1); Material8 mat(1);
volumeSubclass.setVoxel(Vector3DInt32(x,y,z),mat); volumeSubclass.setVoxel(Vector3DInt32(x, y, z), mat);
} }
} }
} }

View File

@ -39,14 +39,14 @@ Vector3DFloat incrementVector(Vector3DFloat input)
void TestVector::testLength() void TestVector::testLength()
{ {
Vector3DInt8 vec(3, 4, 5); Vector3DInt8 vec(3, 4, 5);
QCOMPARE(vec.lengthSquared(), int32_t(3*3+4*4+5*5)); // QCOMPARE is strict on types. For an int8 vector, the OperationType is int32_t. QCOMPARE(vec.lengthSquared(), int32_t(3 * 3 + 4 * 4 + 5 * 5)); // QCOMPARE is strict on types. For an int8 vector, the OperationType is int32_t.
} }
void TestVector::testDotProduct() void TestVector::testDotProduct()
{ {
Vector3DInt8 vecxy(3, 4, 0); Vector3DInt8 vecxy(3, 4, 0);
Vector3DInt8 vecz(0, 0, 1); Vector3DInt8 vecz(0, 0, 1);
QCOMPARE(vecxy.dot(vecz), int32_t(0)); // QCOMPARE is strict on types. For an int8 vector, the OperationType is int32_t . QCOMPARE(vecxy.dot(vecz), int32_t(0)); // QCOMPARE is strict on types. For an int8 vector, the OperationType is int32_t .
} }
@ -54,7 +54,7 @@ void TestVector::testEquality()
{ {
Vector3DInt8 vecxy(3, 4, 0); Vector3DInt8 vecxy(3, 4, 0);
Vector3DInt8 vecz(0, 0, 1); Vector3DInt8 vecz(0, 0, 1);
QCOMPARE(vecxy != vecz, true); QCOMPARE(vecxy != vecz, true);
} }
@ -64,13 +64,13 @@ void TestVector::testPerformance()
QBENCHMARK QBENCHMARK
{ {
for(uint32_t ct = 0; ct < 10000000; ct++) for (uint32_t ct = 0; ct < 10000000; ct++)
{ {
vec = incrementVector(vec); vec = incrementVector(vec);
} }
} }
// Use the result so the calls don't get optimized away. // Use the result so the calls don't get optimized away.
QCOMPARE(vec.lengthSquared() > 0.0f, true); QCOMPARE(vec.lengthSquared() > 0.0f, true);
} }

View File

@ -39,7 +39,7 @@ using namespace PolyVox;
// make sure we get the expected result from a series of volume accesses. // make sure we get the expected result from a series of volume accesses.
inline int32_t cantorTupleFunction(int32_t previousResult, int32_t value) inline int32_t cantorTupleFunction(int32_t previousResult, int32_t value)
{ {
return (( previousResult + value ) * ( previousResult + value + 1 ) + value ) / 2; return ((previousResult + value) * (previousResult + value + 1) + value) / 2;
} }
/* /*
@ -60,16 +60,16 @@ int32_t testDirectAccessWithWrappingForwards(const VolumeType* volume, Region re
for (int x = region.getLowerX(); x <= region.getUpperX(); x++) for (int x = region.getLowerX(); x <= region.getUpperX(); x++)
{ {
//Three level loop now processes 27 voxel neighbourhood //Three level loop now processes 27 voxel neighbourhood
for(int innerZ = -1; innerZ <=1; innerZ++) for (int innerZ = -1; innerZ <= 1; innerZ++)
{ {
for(int innerY = -1; innerY <=1; innerY++) for (int innerY = -1; innerY <= 1; innerY++)
{ {
for(int innerX = -1; innerX <=1; innerX++) for (int innerX = -1; innerX <= 1; innerX++)
{ {
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ)); result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
} }
} }
} }
//End of inner loops //End of inner loops
} }
} }
@ -149,16 +149,16 @@ int32_t testDirectAccessWithWrappingBackwards(const VolumeType* volume, Region r
for (int x = region.getUpperX(); x >= region.getLowerX(); x--) for (int x = region.getUpperX(); x >= region.getLowerX(); x--)
{ {
//Three level loop now processes 27 voxel neighbourhood //Three level loop now processes 27 voxel neighbourhood
for(int innerZ = -1; innerZ <=1; innerZ++) for (int innerZ = -1; innerZ <= 1; innerZ++)
{ {
for(int innerY = -1; innerY <=1; innerY++) for (int innerY = -1; innerY <= 1; innerY++)
{ {
for(int innerX = -1; innerX <=1; innerX++) for (int innerX = -1; innerX <= 1; innerX++)
{ {
result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ)); result = cantorTupleFunction(result, volume->getVoxel(x + innerX, y + innerY, z + innerZ));
} }
} }
} }
//End of inner loops //End of inner loops
} }
} }
@ -249,7 +249,7 @@ int32_t testDirectRandomAccess(const VolumeType* volume)
TestVolume::TestVolume() TestVolume::TestVolume()
{ {
m_regVolume = Region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size m_regVolume = Region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
m_regInternal = m_regVolume; m_regInternal = m_regVolume;
m_regInternal.shiftLowerCorner(4, 2, 2); m_regInternal.shiftLowerCorner(4, 2, 2);
m_regInternal.shiftUpperCorner(-3, -1, -2); m_regInternal.shiftUpperCorner(-3, -1, -2);