From c98f65c9a52c5b822a9a41bea8bff57a7d7bf33b Mon Sep 17 00:00:00 2001 From: David Williams Date: Tue, 27 Nov 2012 22:31:50 +0100 Subject: [PATCH] Added setWrapMode to BaseVolume::Sampler. Added initial border/clamping to RawVolumeSampler. --- .../include/PolyVoxCore/BaseVolume.h | 14 ++ .../include/PolyVoxCore/BaseVolumeSampler.inl | 10 ++ .../include/PolyVoxCore/Impl/Utility.h | 90 +++++----- .../include/PolyVoxCore/MaterialDensityPair.h | 4 + .../include/PolyVoxCore/RawVolume.h | 4 + .../include/PolyVoxCore/RawVolumeSampler.inl | 163 ++++++++++++------ 6 files changed, 191 insertions(+), 94 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h index 1b8211ae..8397a30c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h @@ -38,6 +38,16 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// More details to come... //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + namespace WrapModes + { + enum WrapMode + { + Clamp = 0, + Border = 1 + }; + } + typedef WrapModes::WrapMode WrapMode; + template class BaseVolume { @@ -58,6 +68,7 @@ namespace PolyVox void setPosition(const Vector3DInt32& v3dNewPos); void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); inline bool setVoxel(VoxelType tValue); + void setWrapMode(WrapMode eWrapMode, VoxelType tBorder = VoxelType(0)); void movePositiveX(void); void movePositiveY(void); @@ -104,6 +115,9 @@ namespace PolyVox int32_t mXPosInVolume; int32_t mYPosInVolume; int32_t mZPosInVolume; + + WrapMode m_eWrapMode; + VoxelType m_tBorder; }; #endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl index d1a12a77..e6d01ba2 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl @@ -30,6 +30,8 @@ namespace PolyVox ,mXPosInVolume(0) ,mYPosInVolume(0) ,mZPosInVolume(0) + ,m_eWrapMode(WrapModes::Clamp/*CHANGE*/) //FIXME - Default to border as it's faster? + ,m_tBorder(0) { } @@ -78,6 +80,14 @@ namespace PolyVox return mVolume->setVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume, tValue); } + template + template + void BaseVolume::Sampler::setWrapMode(WrapMode eWrapMode, VoxelType tBorder) + { + m_eWrapMode = eWrapMode; + m_tBorder = tBorder; + } + template template void BaseVolume::Sampler::movePositiveX(void) diff --git a/library/PolyVoxCore/include/PolyVoxCore/Impl/Utility.h b/library/PolyVoxCore/include/PolyVoxCore/Impl/Utility.h index 915c20ab..73fa2b50 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Impl/Utility.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Impl/Utility.h @@ -1,41 +1,43 @@ -/******************************************************************************* -Copyright (c) 2005-2009 David Williams - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*******************************************************************************/ - -#ifndef __PolyVox_Utility_H__ -#define __PolyVox_Utility_H__ - -#include "PolyVoxCore/Impl/TypeDef.h" - -#include - -namespace PolyVox -{ - POLYVOX_API uint8_t logBase2(uint32_t uInput); - POLYVOX_API bool isPowerOf2(uint32_t uInput); - +/******************************************************************************* +Copyright (c) 2005-2009 David Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#ifndef __PolyVox_Utility_H__ +#define __PolyVox_Utility_H__ + +#include "PolyVoxCore/Impl/TypeDef.h" + +#include + +namespace PolyVox +{ + POLYVOX_API uint8_t logBase2(uint32_t uInput); + POLYVOX_API bool isPowerOf2(uint32_t uInput); + int32_t roundTowardsNegInf(float r); - int32_t roundToInteger(float r); - + int32_t roundToInteger(float r); + template + Type clamp(const Type& value, const Type& low, const Type& high); + inline int32_t roundTowardsNegInf(float r) { return (r > 0.0) ? static_cast(r) : static_cast(r - 1.0f); @@ -44,7 +46,13 @@ namespace PolyVox inline int32_t roundToNearestInteger(float r) { return (r > 0.0) ? static_cast(r + 0.5f) : static_cast(r - 0.5f); - } -} - -#endif + } + + template + inline Type clamp(const Type& value, const Type& low, const Type& high) + { + return std::min(high, std::max(low, value)); + } +} + +#endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h index f53ce79c..ac3b3a81 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MaterialDensityPair.h @@ -42,6 +42,10 @@ namespace PolyVox { public: MaterialDensityPair() : m_uMaterial(0), m_uDensity(0) {} + + // FIXME - This is a bit odd... we need to allow the MaterialDensityPair to be initialised with a single integer + // and PolyVox often initialises voxels by calling VoxelType(0). Is there a better way we should handle this? + MaterialDensityPair(Type tValue) : m_uMaterial(tValue), m_uDensity(tValue) {} MaterialDensityPair(Type uMaterial, Type uDensity) : m_uMaterial(uMaterial), m_uDensity(uDensity) {} bool operator==(const MaterialDensityPair& rhs) const diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index dd2bc235..c740a384 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -104,6 +104,10 @@ namespace PolyVox inline VoxelType peekVoxel1px1py1pz(void) const; private: + VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const; + bool isCurrentPositionValid(void) const; + + //Other current position information VoxelType* mCurrentVoxel; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl index 758e578d..907ffe7e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolumeSampler.inl @@ -21,6 +21,8 @@ freely, subject to the following restrictions: distribution. *******************************************************************************/ +#include "PolyVoxCore\Impl\Utility.h" + #define BORDER_LOWX(val) (val > this->mVolume->getEnclosingRegion().getLowerCorner().getX()) #define BORDER_HIGHX(val) (val < this->mVolume->getEnclosingRegion().getUpperCorner().getX()) #define BORDER_LOWY(val) (val > this->mVolume->getEnclosingRegion().getLowerCorner().getY()) @@ -48,7 +50,14 @@ namespace PolyVox template VoxelType RawVolume::Sampler::getVoxel(void) const { - return (m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ) ? *mCurrentVoxel : this->mVolume->getBorderValue(); + if(isCurrentPositionValid()) + { + return *mCurrentVoxel; + } + else + { + return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume); + } } template @@ -146,91 +155,91 @@ namespace PolyVox template VoxelType RawVolume::Sampler::peekVoxel1nx1ny1nz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1nx1ny0pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) ) { return *(mCurrentVoxel - 1 - this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1nx1ny1pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel1nx0py1nz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1nx0py0pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) ) { return *(mCurrentVoxel - 1); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1nx0py1pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel1nx1py1nz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1nx1py0pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1nx1py1pz(void) const { - if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); } ////////////////////////////////////////////////////////////////////////// @@ -238,87 +247,91 @@ namespace PolyVox template VoxelType RawVolume::Sampler::peekVoxel0px1ny1nz(void) const { - if( BORDER_LOWX(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWX(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel0px1ny0pz(void) const { - if( BORDER_LOWY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWY(this->mYPosInVolume) ) { return *(mCurrentVoxel - this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel0px1ny1pz(void) const { - if( BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel0px0py1nz(void) const { - if( BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel0px0py0pz(void) const { + if((this->isCurrentPositionValid())) + { return *mCurrentVoxel; + } + return this->getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel0px0py1pz(void) const { - if( BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel0px1py1nz(void) const { - if( BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel0px1py0pz(void) const { - if( BORDER_HIGHY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHY(this->mYPosInVolume) ) { return *(mCurrentVoxel + this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel0px1py1pz(void) const { - if( BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); } ////////////////////////////////////////////////////////////////////////// @@ -326,91 +339,135 @@ namespace PolyVox template VoxelType RawVolume::Sampler::peekVoxel1px1ny1nz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1px1ny0pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) ) { return *(mCurrentVoxel + 1 - this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1px1ny1pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel1px0py1nz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1px0py0pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) ) { return *(mCurrentVoxel + 1); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1px0py1pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); } template VoxelType RawVolume::Sampler::peekVoxel1px1py1nz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); } template VoxelType RawVolume::Sampler::peekVoxel1px1py0pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) ) { return *(mCurrentVoxel + 1 + this->mVolume->getWidth()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); } template VoxelType RawVolume::Sampler::peekVoxel1px1py1pz(void) const { - if( BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) + if((this->isCurrentPositionValid()) && BORDER_HIGHX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_HIGHZ(this->mZPosInVolume) ) { return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); } - return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); + return this->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); + } + + template + VoxelType RawVolume::Sampler::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const + { + if(this->mVolume->getEnclosingRegion().containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))) //Would be better if we didn't have to build the Vector but could pass seperate params. + { + return this->mVolume->getVoxelAt(uXPos, uYPos, uZPos); + } + else + { + switch(m_eWrapMode) + { + case WrapModes::Clamp: + { + const Vector3DInt32& lowerCorner = this->mVolume->m_regValidRegion.getLowerCorner(); + const Vector3DInt32& upperCorner = this->mVolume->m_regValidRegion.getUpperCorner(); + + int32_t iClampedX = clamp(uXPos, lowerCorner.getX(), upperCorner.getX()); + int32_t iClampedY = clamp(uYPos, lowerCorner.getY(), upperCorner.getY()); + int32_t iClampedZ = clamp(uZPos, lowerCorner.getZ(), upperCorner.getZ()); + + return this->mVolume->getVoxelAt(iClampedX, iClampedY, iClampedZ); + //No need to break as we've returned + } + case WrapModes::Border: + { + return this->m_tBorder; + //No need to break as we've returned + } + default: + { + //Should never happen + assert(false); + return VoxelType(0); + } + } + } + } + + template + bool RawVolume::Sampler::isCurrentPositionValid(void) const + { + return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ; } }