From 073c415a3885f5ad774f2ad9176138740482639d Mon Sep 17 00:00:00 2001 From: Daviw Williams Date: Wed, 29 May 2013 16:07:27 +0200 Subject: [PATCH] Work on new getVoxel() functions. --- .../include/PolyVoxCore/BaseVolume.h | 2 + .../include/PolyVoxCore/BaseVolumeSampler.inl | 5 +- .../include/PolyVoxCore/LargeVolume.inl | 5 +- .../include/PolyVoxCore/RawVolume.h | 9 ++ .../include/PolyVoxCore/RawVolume.inl | 82 ++++++++++++++----- .../include/PolyVoxCore/SimpleVolume.inl | 5 +- 6 files changed, 82 insertions(+), 26 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h index 30c34584..e055778e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h @@ -45,6 +45,8 @@ namespace PolyVox }; } typedef BoundsChecks::BoundsCheck BoundsCheck; + + template struct BoundsCheckType{}; namespace WrapModes { diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl index aabf0287..8301315e 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolumeSampler.inl @@ -374,8 +374,9 @@ namespace PolyVox } default: { - //Should never happen. We don't log because this hurts performance (preventing inlining?). - POLYVOX_THROW_DONT_LOG(std::invalid_argument, "Wrap mode parameter has an unrecognised value."); + //Should never happen. However, this assert appears to hurt performance (logging prevents inlining?). + POLYVOX_ASSERT(false, "Wrap mode parameter has an unrecognised value."); + return VoxelType(); } } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index a0c778f6..741ee1c2 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -241,8 +241,9 @@ namespace PolyVox } default: { - //Should never happen. We don't log because this hurts performance (preventing inlining?). - POLYVOX_THROW_DONT_LOG(std::invalid_argument, "Wrap mode parameter has an unrecognised value."); + //Should never happen. However, this assert appears to hurt performance (logging prevents inlining?). + POLYVOX_ASSERT(false, "Wrap mode parameter has an unrecognised value."); + return VoxelType(); } } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h index 95a770b9..d1b821ad 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h @@ -115,6 +115,10 @@ namespace PolyVox /// Destructor ~RawVolume(); + /// Gets a voxel at the position given by x,y,z coordinates + template + VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const; + /// Gets a voxel at the position given by x,y,z coordinates VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheck eBoundsCheck = BoundsChecks::Full) const; /// Gets a voxel at the position given by a 3D vector @@ -150,6 +154,11 @@ namespace PolyVox private: void initialise(const Region& regValidRegion); + template + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const; + VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const; + //The block data VoxelType* m_pData; }; diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl index 5614650d..a81799ae 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl @@ -73,6 +73,23 @@ namespace PolyVox POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons."); } + //////////////////////////////////////////////////////////////////////////////// + /// \param uXPos The \c x position of the voxel + /// \param uYPos The \c y position of the voxel + /// \param uZPos The \c z position of the voxel + /// \param eBoundsCheck Controls whether bounds checking is performed on voxel access. It's safest to + /// set this to BoundsChecks::Full (the default), but if you are certain that the voxel you are accessing + /// is inside the volume's enclosing region then you can skip this check to gain some performance. + /// \return The voxel value + //////////////////////////////////////////////////////////////////////////////// + template + template + VoxelType RawVolume::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const + { + // Simply call through to the real implementation + return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType()); + } + //////////////////////////////////////////////////////////////////////////////// /// \param uXPos The \c x position of the voxel /// \param uYPos The \c y position of the voxel @@ -89,23 +106,14 @@ namespace PolyVox // bounds, and throw an exception if they are violated. if(eBoundsCheck == BoundsChecks::Full) { - if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false) - { - POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); - } + // Call through to the real implementation + return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType()); + } + else + { + // Call through to the real implementation + return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType()); } - - const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner(); - int32_t iLocalXPos = uXPos - v3dLowerCorner.getX(); - int32_t iLocalYPos = uYPos - v3dLowerCorner.getY(); - int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); - - return m_pData - [ - iLocalXPos + - iLocalYPos * this->getWidth() + - iLocalZPos * this->getWidth() * this->getHeight() - ]; } //////////////////////////////////////////////////////////////////////////////// @@ -182,14 +190,14 @@ namespace PolyVox uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ()); //Get the voxel value - return getVoxel(uXPos, uYPos, uZPos, BoundsChecks::None); // No bounds checks as we've just validated the position. + return getVoxel(uXPos, uYPos, uZPos); // No bounds checks as we've just validated the position. //No need to break as we've returned } case WrapModes::Border: { if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) { - return getVoxel(uXPos, uYPos, uZPos, BoundsChecks::None); // No bounds checks as we've just validated the position. + return getVoxel(uXPos, uYPos, uZPos); // No bounds checks as we've just validated the position. } else { @@ -199,8 +207,9 @@ namespace PolyVox } default: { - //Should never happen. We don't log because this hurts performance (preventing inlining?). - POLYVOX_THROW_DONT_LOG(std::invalid_argument, "Wrap mode parameter has an unrecognised value."); + //Should never happen. However, this assert appears to hurt performance (logging prevents inlining?). + POLYVOX_ASSERT(false, "Wrap mode parameter has an unrecognised value."); + return VoxelType(); } } } @@ -346,5 +355,38 @@ namespace PolyVox return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType); } + template + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const + { + POLYVOX_THROW(not_implemented, "This function is not implemented and should never be called!"); + } + + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const + { + if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false) + { + POLYVOX_THROW(std::out_of_range, "Position is outside valid region"); + } + + return getVoxelImpl(uXPos, uYPos, uZPos, BoundsCheckType()); + } + + template + VoxelType RawVolume::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, BoundsCheckType) const + { + const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner(); + int32_t iLocalXPos = uXPos - v3dLowerCorner.getX(); + int32_t iLocalYPos = uYPos - v3dLowerCorner.getY(); + int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); + + return m_pData + [ + iLocalXPos + + iLocalYPos * this->getWidth() + + iLocalZPos * this->getWidth() * this->getHeight() + ]; + } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl index 7f5ff9d6..4dc5af0a 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl @@ -199,8 +199,9 @@ namespace PolyVox } default: { - //Should never happen. We don't log because this hurts performance (preventing inlining?). - POLYVOX_THROW_DONT_LOG(std::invalid_argument, "Wrap mode parameter has an unrecognised value."); + //Should never happen. However, this assert appears to hurt performance (logging prevents inlining?). + POLYVOX_ASSERT(false, "Wrap mode parameter has an unrecognised value."); + return VoxelType(); } } }