Merge branch 'develop' into feature/cubiquity-version
Conflicts: library/PolyVoxCore/include/PolyVoxCore/Region.h library/PolyVoxCore/source/Region.cpp
This commit is contained in:
@ -49,7 +49,6 @@ SET(CORE_INC_FILES
|
||||
include/PolyVoxCore/BaseVolume.inl
|
||||
include/PolyVoxCore/BaseVolumeSampler.inl
|
||||
include/PolyVoxCore/Compressor.h
|
||||
include/PolyVoxCore/ConstVolumeProxy.h
|
||||
include/PolyVoxCore/CubicSurfaceExtractor.h
|
||||
include/PolyVoxCore/CubicSurfaceExtractor.inl
|
||||
include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h
|
||||
@ -57,6 +56,7 @@ SET(CORE_INC_FILES
|
||||
include/PolyVoxCore/DefaultIsQuadNeeded.h
|
||||
include/PolyVoxCore/DefaultMarchingCubesController.h
|
||||
include/PolyVoxCore/Density.h
|
||||
include/PolyVoxCore/FilePager.h
|
||||
include/PolyVoxCore/GradientEstimators.h
|
||||
include/PolyVoxCore/GradientEstimators.inl
|
||||
include/PolyVoxCore/Interpolation.h
|
||||
@ -72,6 +72,7 @@ SET(CORE_INC_FILES
|
||||
include/PolyVoxCore/Material.h
|
||||
include/PolyVoxCore/MaterialDensityPair.h
|
||||
include/PolyVoxCore/MinizCompressor.h
|
||||
include/PolyVoxCore/Pager.h
|
||||
include/PolyVoxCore/PolyVoxForwardDeclarations.h
|
||||
include/PolyVoxCore/Picking.h
|
||||
include/PolyVoxCore/Picking.inl
|
||||
|
@ -73,10 +73,7 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
|
||||
{
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range");
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
@ -95,10 +92,7 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
|
||||
{
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range");
|
||||
|
||||
return
|
||||
SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
|
||||
@ -147,10 +141,7 @@ namespace PolyVox
|
||||
m_uNoOfElements = 1;
|
||||
for (uint32_t i = 0; i<noOfDims; i++)
|
||||
{
|
||||
if(pDimensions[i] == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Invalid array dimension");
|
||||
}
|
||||
POLYVOX_THROW_IF(pDimensions[i] == 0, std::out_of_range, "Invalid array dimension");
|
||||
|
||||
m_uNoOfElements *= pDimensions[i];
|
||||
m_pDimensions[i] = pDimensions[i];
|
||||
@ -197,10 +188,7 @@ namespace PolyVox
|
||||
template <uint32_t noOfDims, typename ElementType>
|
||||
uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
|
||||
{
|
||||
if(uDimension >= noOfDims)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array dimension out of range");
|
||||
}
|
||||
POLYVOX_THROW_IF(uDimension >= noOfDims, std::out_of_range, "Array dimension out of range");
|
||||
|
||||
return m_pDimensions[uDimension];
|
||||
}
|
||||
@ -266,10 +254,7 @@ namespace PolyVox
|
||||
template <typename ElementType>
|
||||
ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
|
||||
{
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range");
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
@ -277,10 +262,7 @@ namespace PolyVox
|
||||
template <typename ElementType>
|
||||
const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
|
||||
{
|
||||
if(uIndex >= m_pDimensions[0])
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Array index out of range");
|
||||
}
|
||||
POLYVOX_THROW_IF(uIndex >= m_pDimensions[0], std::out_of_range, "Array index out of range");
|
||||
|
||||
return m_pElements[uIndex];
|
||||
}
|
||||
|
@ -36,16 +36,23 @@ namespace PolyVox
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// More details to come...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace WrapModes
|
||||
{
|
||||
enum WrapMode
|
||||
{
|
||||
Clamp = 0,
|
||||
Border = 1
|
||||
Validate = 0,
|
||||
Clamp = 1,
|
||||
Border = 2,
|
||||
AssumeValid = 3
|
||||
};
|
||||
}
|
||||
typedef WrapModes::WrapMode WrapMode;
|
||||
|
||||
// Required for a trick to implement specialization of template member
|
||||
// functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode W> struct WrapModeType{};
|
||||
|
||||
template <typename _VoxelType>
|
||||
class BaseVolume
|
||||
{
|
||||
@ -109,7 +116,7 @@ namespace PolyVox
|
||||
inline VoxelType peekVoxel1px1py1pz(void) const;
|
||||
|
||||
protected:
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
|
||||
DerivedVolumeType* mVolume;
|
||||
|
||||
@ -146,22 +153,31 @@ namespace PolyVox
|
||||
int32_t getShortestSideLength(void) const;
|
||||
/// Gets the length of the diagonal in voxels
|
||||
float getDiagonalLength(void) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the value used for voxels which are outside the volume
|
||||
void setBorderValue(const VoxelType& tBorder);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
|
@ -154,26 +154,70 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& /*v3dPos*/) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \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 eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
POLYVOX_ASSERT(false, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
@ -201,30 +245,6 @@ namespace PolyVox
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType BaseVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& /*v3dPos*/, WrapMode /*eWrapMode*/, VoxelType /*tBorder*/) const
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
return VoxelType();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param tBorder The value to use for voxels outside the volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -234,6 +254,28 @@ namespace PolyVox
|
||||
m_tBorderValue = tBorder;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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 tValue the value to which the voxel will be set
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void BaseVolume<VoxelType>::setVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void BaseVolume<VoxelType>::setVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/, WrapMode /*eWrapMode*/)
|
||||
{
|
||||
POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
|
@ -57,7 +57,7 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxel(void) const
|
||||
{
|
||||
return mVolume->getVoxelAt(mXPosInVolume, mYPosInVolume, mZPosInVolume);
|
||||
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume, WrapModes::Validate); // FIXME - Use templatised version instead but watch for Linux compile errors.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -154,63 +154,63 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1ny1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx0py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1nx1py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume - 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -219,63 +219,63 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1ny1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px0py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume , mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume , mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel0px1py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume , mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -284,100 +284,83 @@ namespace PolyVox
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1ny1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume - 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px0py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume , mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1nz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume - 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py0pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume );
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::peekVoxel1px1py1pz(void) const
|
||||
{
|
||||
return getVoxelAt(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
return getVoxelImpl(mXPosInVolume + 1, mYPosInVolume + 1, mZPosInVolume + 1);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <typename DerivedVolumeType>
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
VoxelType BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
if(mVolume->getEnclosingRegion().containsPoint(uXPos, uYPos, uZPos))
|
||||
switch(m_eWrapMode)
|
||||
{
|
||||
return mVolume->getVoxelAt(uXPos, uYPos, uZPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(m_eWrapMode)
|
||||
{
|
||||
case WrapModes::Clamp:
|
||||
{
|
||||
const Vector3DInt32& lowerCorner = mVolume->m_regValidRegion.getLowerCorner();
|
||||
const Vector3DInt32& upperCorner = 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 mVolume->getVoxelAt(iClampedX, iClampedY, iClampedZ);
|
||||
//No need to break as we've returned
|
||||
}
|
||||
case WrapModes::Border:
|
||||
{
|
||||
return m_tBorder;
|
||||
//No need to break as we've returned
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
}
|
||||
}
|
||||
case WrapModes::Validate:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Validate, m_tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Clamp, m_tBorder);
|
||||
case WrapModes::Border:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::Border, m_tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return mVolume->getVoxel(uXPos, uYPos, uZPos, WrapModes::AssumeValid, m_tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*******************************************************************************
|
||||
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_ConstVolumeProxy_H__
|
||||
#define __PolyVox_ConstVolumeProxy_H__
|
||||
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
class ConstVolumeProxy
|
||||
{
|
||||
//LargeVolume is a friend so it can call the constructor.
|
||||
friend class LargeVolume<VoxelType>;
|
||||
public:
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
|
||||
}
|
||||
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
|
||||
}
|
||||
|
||||
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(m_regValid.containsPoint(v3dPos), "Position is outside valid region");
|
||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
private:
|
||||
//Private constructor, so client code can't abuse this class.
|
||||
ConstVolumeProxy(const LargeVolume<VoxelType>& pVolume, const Region& regValid)
|
||||
:m_pVolume(pVolume)
|
||||
,m_regValid(regValid)
|
||||
{
|
||||
}
|
||||
|
||||
//Private assignment operator, so client code can't abuse this class.
|
||||
ConstVolumeProxy& operator=(const ConstVolumeProxy& rhs)
|
||||
{
|
||||
}
|
||||
|
||||
const LargeVolume<VoxelType>& m_pVolume;
|
||||
const Region& m_regValid;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__PolyVox_ConstVolumeProxy_H__
|
@ -53,7 +53,7 @@ namespace PolyVox
|
||||
|
||||
uint32_t material = 0;
|
||||
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x+1,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x+1,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), static_cast<float>(material)));
|
||||
@ -63,7 +63,7 @@ namespace PolyVox
|
||||
m_meshCurrent->addTriangleCubic(v0,v2,v1);
|
||||
m_meshCurrent->addTriangleCubic(v1,v2,v3);
|
||||
}
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x+1,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x+1,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), static_cast<float>(material)));
|
||||
@ -74,7 +74,7 @@ namespace PolyVox
|
||||
m_meshCurrent->addTriangleCubic(v1,v3,v2);
|
||||
}
|
||||
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y+1,z,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y+1,z,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), static_cast<float>(material)));
|
||||
@ -84,7 +84,7 @@ namespace PolyVox
|
||||
m_meshCurrent->addTriangleCubic(v0,v1,v2);
|
||||
m_meshCurrent->addTriangleCubic(v1,v3,v2);
|
||||
}
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y+1,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y+1,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), static_cast<float>(material)));
|
||||
@ -95,7 +95,7 @@ namespace PolyVox
|
||||
m_meshCurrent->addTriangleCubic(v1,v2,v3);
|
||||
}
|
||||
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z+1,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z+1,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), static_cast<float>(material)));
|
||||
@ -105,7 +105,7 @@ namespace PolyVox
|
||||
m_meshCurrent->addTriangleCubic(v0,v2,v1);
|
||||
m_meshCurrent->addTriangleCubic(v1,v2,v3);
|
||||
}
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxelWithWrapping(x,y,z+1,m_eWrapMode,m_tBorderValue), m_volData->getVoxelWithWrapping(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
if(m_funcIsQuadNeededCallback(m_volData->getVoxel(x,y,z+1,m_eWrapMode,m_tBorderValue), m_volData->getVoxel(x,y,z,m_eWrapMode,m_tBorderValue), material))
|
||||
{
|
||||
uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), static_cast<float>(material)));
|
||||
uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), static_cast<float>(material)));
|
||||
|
132
library/PolyVoxCore/include/PolyVoxCore/FilePager.h
Normal file
132
library/PolyVoxCore/include/PolyVoxCore/FilePager.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*******************************************************************************
|
||||
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_FilePager_H__
|
||||
#define __PolyVox_FilePager_H__
|
||||
|
||||
#include "PolyVoxCore/Impl/TypeDef.h"
|
||||
|
||||
#include "PolyVoxCore/Pager.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
/**
|
||||
* Provides an interface for performing paging of data.
|
||||
*/
|
||||
template <typename VoxelType>
|
||||
class FilePager : public Pager<typename VoxelType>
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FilePager(const std::string& strFolderName)
|
||||
:Pager()
|
||||
,m_strFolderName(strFolderName)
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~FilePager() {};
|
||||
|
||||
virtual void pageIn(const Region& region, Block<VoxelType>* pBlockData)
|
||||
{
|
||||
POLYVOX_ASSERT(pBlockData, "Attempting to page in NULL block");
|
||||
POLYVOX_ASSERT(pBlockData->hasUncompressedData() == false, "Block should not have uncompressed data");
|
||||
|
||||
std::stringstream ss;
|
||||
ss << region.getLowerX() << "_" << region.getLowerY() << "_" << region.getLowerZ() << "_"
|
||||
<< region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ();
|
||||
|
||||
std::string filename = m_strFolderName + ss.str();
|
||||
|
||||
// FIXME - This should be replaced by C++ style IO, but currently this causes problems with
|
||||
// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919
|
||||
|
||||
FILE* pFile = fopen(filename.c_str(), "rb");
|
||||
if(pFile)
|
||||
{
|
||||
logTrace() << "Paging in data for " << region;
|
||||
|
||||
fseek(pFile, 0L, SEEK_END);
|
||||
size_t fileSizeInBytes = ftell(pFile);
|
||||
fseek(pFile, 0L, SEEK_SET);
|
||||
|
||||
uint8_t* buffer = new uint8_t[fileSizeInBytes];
|
||||
fread(buffer, sizeof(uint8_t), fileSizeInBytes, pFile);
|
||||
pBlockData->setCompressedData(buffer, fileSizeInBytes);
|
||||
delete[] buffer;
|
||||
|
||||
if(ferror(pFile))
|
||||
{
|
||||
POLYVOX_THROW(std::runtime_error, "Error reading in block data, even though a file exists.");
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
logTrace() << "No data found for " << region << " during paging in.";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void pageOut(const Region& region, Block<VoxelType>* pBlockData)
|
||||
{
|
||||
POLYVOX_ASSERT(pBlockData, "Attempting to page out NULL block");
|
||||
POLYVOX_ASSERT(pBlockData->hasUncompressedData() == false, "Block should not have uncompressed data");
|
||||
|
||||
logTrace() << "Paging out data for " << region;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << region.getLowerX() << "_" << region.getLowerY() << "_" << region.getLowerZ() << "_"
|
||||
<< region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ();
|
||||
|
||||
std::string filename = m_strFolderName + ss.str();
|
||||
|
||||
// FIXME - This should be replaced by C++ style IO, but currently this causes problems with
|
||||
// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919
|
||||
|
||||
FILE* pFile = fopen(filename.c_str(), "wb");
|
||||
if(!pFile)
|
||||
{
|
||||
POLYVOX_THROW(std::runtime_error, "Unable to open file to write out block data.");
|
||||
}
|
||||
|
||||
fwrite(pBlockData->getCompressedData(), sizeof(uint8_t), pBlockData->getCompressedDataLength(), pFile);
|
||||
|
||||
if(ferror(pFile))
|
||||
{
|
||||
POLYVOX_THROW(std::runtime_error, "Error writing out block data.");
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_strFolderName;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__PolyVox_FilePager_H__
|
@ -52,14 +52,14 @@ namespace PolyVox
|
||||
const int32_t z = volIter.getPosition().getZ();
|
||||
|
||||
//FIXME - bitwise way of doing this?
|
||||
typename VolumeType::VoxelType voxel1nx = volIter.getVoxelAt(x-2, y ,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1px = volIter.getVoxelAt(x-2, y ,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1nx = volIter.getVoxel(x-2, y ,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1px = volIter.getVoxel(x-2, y ,z ) > 0 ? 1: 0;
|
||||
|
||||
typename VolumeType::VoxelType voxel1ny = volIter.getVoxelAt(x , y-2,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1py = volIter.getVoxelAt(x , y-2,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1ny = volIter.getVoxel(x , y-2,z ) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1py = volIter.getVoxel(x , y-2,z ) > 0 ? 1: 0;
|
||||
|
||||
typename VolumeType::VoxelType voxel1nz = volIter.getVoxelAt(x , y ,z-2) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1pz = volIter.getVoxelAt(x , y ,z-2) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1nz = volIter.getVoxel(x , y ,z-2) > 0 ? 1: 0;
|
||||
typename VolumeType::VoxelType voxel1pz = volIter.getVoxel(x , y ,z-2) > 0 ? 1: 0;
|
||||
|
||||
return Vector3DFloat
|
||||
(
|
||||
|
@ -37,41 +37,36 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
class Block
|
||||
{
|
||||
template <typename LengthType>
|
||||
struct RunlengthEntry
|
||||
{
|
||||
LengthType length;
|
||||
VoxelType value;
|
||||
|
||||
//We can parametise the length on anything up to uint32_t.
|
||||
//This lets us experiment with the optimal size in the future.
|
||||
static uint32_t maxRunlength(void) {return (std::numeric_limits<LengthType>::max)();}
|
||||
};
|
||||
|
||||
public:
|
||||
Block(uint16_t uSideLength = 0);
|
||||
Block(uint16_t uSideLength, Compressor* pCompressor);
|
||||
|
||||
const uint8_t* const getCompressedData(void) const;
|
||||
const uint32_t getCompressedDataLength(void) const;
|
||||
uint16_t getSideLength(void) const;
|
||||
VoxelType getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
|
||||
VoxelType getVoxelAt(const Vector3DUint16& v3dPos) const;
|
||||
VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
|
||||
VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
|
||||
|
||||
bool hasUncompressedData(void) const;
|
||||
|
||||
void setCompressedData(const uint8_t* const data, uint32_t dataLength);
|
||||
void setVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
||||
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||
|
||||
void initialise(uint16_t uSideLength);
|
||||
void createUncompressedData(void);
|
||||
void destroyUncompressedData(void);
|
||||
|
||||
uint32_t calculateSizeInBytes(void);
|
||||
|
||||
public:
|
||||
void compress(Compressor* pCompressor);
|
||||
void uncompress(Compressor* pCompressor);
|
||||
|
||||
Compressor* m_pCompressor;
|
||||
uint8_t* m_pCompressedData;
|
||||
uint32_t m_uCompressedDataLength;
|
||||
VoxelType* m_tUncompressedData;
|
||||
uint16_t m_uSideLength;
|
||||
uint8_t m_uSideLengthPower;
|
||||
bool m_bIsCompressed;
|
||||
bool m_bIsUncompressedDataModified;
|
||||
|
||||
uint32_t timestamp;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -36,19 +36,56 @@ freely, subject to the following restrictions:
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
Block<VoxelType>::Block(uint16_t uSideLength)
|
||||
:m_pCompressedData(0)
|
||||
Block<VoxelType>::Block(uint16_t uSideLength, Compressor* pCompressor)
|
||||
:m_pCompressor(pCompressor)
|
||||
,m_pCompressedData(0)
|
||||
,m_uCompressedDataLength(0)
|
||||
,m_tUncompressedData(0)
|
||||
,m_uSideLength(0)
|
||||
,m_uSideLengthPower(0)
|
||||
,m_bIsCompressed(false)
|
||||
,m_bIsUncompressedDataModified(true)
|
||||
{
|
||||
if(uSideLength != 0)
|
||||
if(uSideLength == 0)
|
||||
{
|
||||
initialise(uSideLength);
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");
|
||||
}
|
||||
|
||||
if(!isPowerOf2(uSideLength))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two.");
|
||||
}
|
||||
|
||||
if(pCompressor == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block must be provided with a valid compressor.");
|
||||
}
|
||||
|
||||
//Compute the side length
|
||||
m_uSideLength = uSideLength;
|
||||
m_uSideLengthPower = logBase2(uSideLength);
|
||||
|
||||
//Temporarily create the block data. This is just so we can compress it an discard it.
|
||||
// FIXME - this is a temporary solution.
|
||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||
m_tUncompressedData = new VoxelType[uNoOfVoxels];
|
||||
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, VoxelType());
|
||||
m_bIsUncompressedDataModified = true;
|
||||
|
||||
destroyUncompressedData();
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
const uint8_t* const Block<VoxelType>::getCompressedData(void) const
|
||||
{
|
||||
POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL");
|
||||
return m_pCompressedData;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
const uint32_t Block<VoxelType>::getCompressedDataLength(void) const
|
||||
{
|
||||
POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL");
|
||||
return m_uCompressedDataLength;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -58,12 +95,13 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType Block<VoxelType>::getVoxelAt(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||
VoxelType Block<VoxelType>::getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
||||
{
|
||||
// This is internal code not directly called by the user. For efficiency we assert rather than throwing.
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(hasUncompressedData(), "The block must have uncompressed data to call getVoxel()");
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||
|
||||
return m_tUncompressedData
|
||||
@ -75,9 +113,28 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType Block<VoxelType>::getVoxelAt(const Vector3DUint16& v3dPos) const
|
||||
VoxelType Block<VoxelType>::getVoxel(const Vector3DUint16& v3dPos) const
|
||||
{
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool Block<VoxelType>::hasUncompressedData(void) const
|
||||
{
|
||||
return m_tUncompressedData != 0;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::setCompressedData(const uint8_t* const data, uint32_t dataLength)
|
||||
{
|
||||
POLYVOX_ASSERT(m_pCompressedData, "Compressed data is NULL");
|
||||
POLYVOX_ASSERT(m_pCompressedData != data, "Attempting to copy data onto itself");
|
||||
|
||||
delete[] m_pCompressedData;
|
||||
|
||||
m_uCompressedDataLength = dataLength;
|
||||
m_pCompressedData = new uint8_t[dataLength];
|
||||
memcpy(m_pCompressedData, data, dataLength);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -87,6 +144,7 @@ namespace PolyVox
|
||||
POLYVOX_ASSERT(uXPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uYPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the block");
|
||||
POLYVOX_ASSERT(hasUncompressedData(), "The block must have uncompressed data to call setVoxelAt()");
|
||||
POLYVOX_ASSERT(m_tUncompressedData, "No uncompressed data - block must be decompressed before accessing voxels.");
|
||||
|
||||
m_tUncompressedData
|
||||
@ -106,46 +164,11 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::initialise(uint16_t uSideLength)
|
||||
void Block<VoxelType>::destroyUncompressedData()
|
||||
{
|
||||
//Release mode validation
|
||||
if(!isPowerOf2(uSideLength))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two.");
|
||||
}
|
||||
|
||||
//Compute the side length
|
||||
m_uSideLength = uSideLength;
|
||||
m_uSideLengthPower = logBase2(uSideLength);
|
||||
|
||||
//Create the block data
|
||||
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
|
||||
|
||||
//Clear it (should we bother?)
|
||||
const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
|
||||
std::fill(m_tUncompressedData, m_tUncompressedData + uNoOfVoxels, VoxelType());
|
||||
m_bIsUncompressedDataModified = true;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
uint32_t Block<VoxelType>::calculateSizeInBytes(void)
|
||||
{
|
||||
//FIXME - This function is incomplete.
|
||||
uint32_t uSizeInBytes = sizeof(Block<VoxelType>);
|
||||
return uSizeInBytes;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::compress(Compressor* pCompressor)
|
||||
{
|
||||
if(m_bIsCompressed)
|
||||
if(!hasUncompressedData())
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Attempted to compress block which is already flagged as compressed.");
|
||||
}
|
||||
|
||||
if(!pCompressor)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||
POLYVOX_THROW(invalid_operation, "No uncompressed data to compress.");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
|
||||
@ -169,7 +192,7 @@ namespace PolyVox
|
||||
|
||||
try
|
||||
{
|
||||
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
// Create new compressed data and copy across
|
||||
m_pCompressedData = new uint8_t[uCompressedLength];
|
||||
@ -181,7 +204,9 @@ namespace PolyVox
|
||||
// It is possible for the compression to fail. A common cause for this would be if the destination
|
||||
// buffer is not big enough. So now we try again using a buffer that is definitely big enough.
|
||||
// Note that ideally we will choose our earlier buffer size so that this almost never happens.
|
||||
uint32_t uMaxCompressedSize = pCompressor->getMaxCompressedSize(uSrcLength);
|
||||
logWarning() << "The compressor failed to compress the block, proabaly due to the buffer being too small.";
|
||||
logWarning() << "The compression will be tried again with a larger buffer";
|
||||
uint32_t uMaxCompressedSize = m_pCompressor->getMaxCompressedSize(uSrcLength);
|
||||
uint8_t* buffer = new uint8_t[ uMaxCompressedSize ];
|
||||
|
||||
pDstData = reinterpret_cast<void*>( buffer );
|
||||
@ -189,7 +214,7 @@ namespace PolyVox
|
||||
|
||||
try
|
||||
{
|
||||
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
// Create new compressed data and copy across
|
||||
m_pCompressedData = new uint8_t[uCompressedLength];
|
||||
@ -211,20 +236,14 @@ namespace PolyVox
|
||||
//Flag the uncompressed data as no longer being used.
|
||||
delete[] m_tUncompressedData;
|
||||
m_tUncompressedData = 0;
|
||||
m_bIsCompressed = true;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void Block<VoxelType>::uncompress(Compressor* pCompressor)
|
||||
void Block<VoxelType>::createUncompressedData()
|
||||
{
|
||||
if(!m_bIsCompressed)
|
||||
if(hasUncompressedData())
|
||||
{
|
||||
POLYVOX_THROW(invalid_operation, "Attempted to uncompress block which is not flagged as compressed.");
|
||||
}
|
||||
|
||||
if(!pCompressor)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "A valid compressor must be provided");
|
||||
POLYVOX_THROW(invalid_operation, "Uncompressed data already exists.");
|
||||
}
|
||||
|
||||
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
|
||||
@ -238,13 +257,20 @@ namespace PolyVox
|
||||
|
||||
//MinizCompressor compressor;
|
||||
//RLECompressor<VoxelType, uint16_t> compressor;
|
||||
uint32_t uUncompressedLength = pCompressor->decompress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
uint32_t uUncompressedLength = m_pCompressor->decompress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
|
||||
POLYVOX_ASSERT(uUncompressedLength == m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType), "Destination length has changed.");
|
||||
|
||||
//m_tUncompressedData = reinterpret_cast<VoxelType*>(uncompressedResult.ptr);
|
||||
|
||||
m_bIsCompressed = false;
|
||||
m_bIsUncompressedDataModified = false;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
uint32_t Block<VoxelType>::calculateSizeInBytes(void)
|
||||
{
|
||||
//FIXME - This function is incomplete.
|
||||
uint32_t uSizeInBytes = sizeof(Block<VoxelType>);
|
||||
return uSizeInBytes;
|
||||
}
|
||||
}
|
||||
|
@ -255,9 +255,36 @@ namespace PolyVox
|
||||
* ...
|
||||
*/
|
||||
#ifdef POLYVOX_THROW_ENABLED
|
||||
|
||||
#define POLYVOX_THROW_IF(condition, type, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
PolyVox::logError() << (message); \
|
||||
throw type((message)); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_THROW(type, message) \
|
||||
PolyVox::logError() << (message); \
|
||||
throw type((message))
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
PolyVox::logError() << (message); \
|
||||
throw type((message)); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#else
|
||||
namespace PolyVox
|
||||
{
|
||||
@ -267,10 +294,37 @@ namespace PolyVox
|
||||
void setThrowHandler(ThrowHandler newHandler);
|
||||
}
|
||||
|
||||
#define POLYVOX_THROW_IF(condition, type, message) \
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
if ((condition)) \
|
||||
{ \
|
||||
PolyVox::logError() << (message); \
|
||||
type except = (type)((message)); \
|
||||
getThrowHandler()((except), __FILE__, __LINE__); \
|
||||
} \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#define POLYVOX_THROW(type, message) \
|
||||
PolyVox::logError() << (message); \
|
||||
type except = (type)((message)); \
|
||||
getThrowHandler()((except), __FILE__, __LINE__)
|
||||
/* We use the do...while(0) construct in our macros (for reasons see here: http://stackoverflow.com/a/154138) \
|
||||
but Visual Studio gives unhelpful 'conditional expression is constant' warnings. The recommended solution \
|
||||
(http://stackoverflow.com/a/1946485) is to disable these warnings. */ \
|
||||
POLYVOX_MSC_WARNING_PUSH \
|
||||
POLYVOX_DISABLE_MSC_WARNING(4127) \
|
||||
do \
|
||||
{ \
|
||||
PolyVox::logError() << (message); \
|
||||
type except = (type)((message)); \
|
||||
getThrowHandler()((except), __FILE__, __LINE__); \
|
||||
} while(0) \
|
||||
POLYVOX_MSC_WARNING_POP
|
||||
|
||||
#endif
|
||||
|
||||
namespace PolyVox
|
||||
|
@ -27,6 +27,7 @@ freely, subject to the following restrictions:
|
||||
#include "PolyVoxCore/BaseVolume.h"
|
||||
#include "Impl/Block.h"
|
||||
#include "PolyVoxCore/Compressor.h"
|
||||
#include "PolyVoxCore/Pager.h"
|
||||
#include "PolyVoxCore/Region.h"
|
||||
#include "PolyVoxCore/Vector.h"
|
||||
|
||||
@ -41,8 +42,6 @@ freely, subject to the following restrictions:
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType> class ConstVolumeProxy;
|
||||
|
||||
/// The LargeVolume class provides a memory efficient method of storing voxel data while also allowing fast access and modification.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// A LargeVolume is essentially a 3D array in which each element (or <i>voxel</i>) is identified by a three dimensional (x,y,z) coordinate.
|
||||
@ -227,62 +226,52 @@ namespace PolyVox
|
||||
VoxelType* mCurrentVoxel;
|
||||
};
|
||||
|
||||
// Make the ConstVolumeProxy a friend
|
||||
friend class ConstVolumeProxy<VoxelType>;
|
||||
|
||||
struct LoadedBlock
|
||||
{
|
||||
public:
|
||||
LoadedBlock(uint16_t uSideLength = 0)
|
||||
:block(uSideLength)
|
||||
,timestamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
Block<VoxelType> block;
|
||||
uint32_t timestamp;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// Constructor for creating a very large paging volume.
|
||||
public:
|
||||
/// Constructor for creating a fixed size volume.
|
||||
LargeVolume
|
||||
(
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
|
||||
uint16_t uBlockSideLength = 32
|
||||
const Region& regValid,
|
||||
uint16_t uBlockSideLength = 32
|
||||
);
|
||||
/// Constructor for creating a fixed size volume.
|
||||
LargeVolume
|
||||
(
|
||||
const Region& regValid,
|
||||
Compressor* pCompressor = 0,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
|
||||
bool bPagingEnabled = false,
|
||||
Compressor* pCompressor,
|
||||
Pager<VoxelType>* pPager ,
|
||||
uint16_t uBlockSideLength = 32
|
||||
);
|
||||
/// Destructor
|
||||
~LargeVolume();
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the number of blocks for which uncompressed data is stored
|
||||
void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks);
|
||||
/// Sets the number of blocks which can be in memory before the paging system starts unloading them
|
||||
void setMaxNumberOfBlocksInMemory(uint32_t uMaxNumberOfBlocksInMemory);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
|
||||
@ -324,48 +313,47 @@ namespace PolyVox
|
||||
return false;
|
||||
}
|
||||
};
|
||||
void initialise(const Region& regValidRegion, uint16_t uBlockSideLength);
|
||||
void initialise();
|
||||
|
||||
/// gets called when a new region is allocated and needs to be filled
|
||||
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
||||
/// is absolutely unsafe
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> m_funcDataRequiredHandler;
|
||||
/// gets called when a Region needs to be stored by the user, because LargeVolume will erase it right after
|
||||
/// this function returns
|
||||
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
||||
/// is absolutely unsafe
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> m_funcDataOverflowHandler;
|
||||
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
|
||||
|
||||
Block<VoxelType>* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const;
|
||||
void eraseBlock(typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itBlock) const;
|
||||
/// this function can be called by m_funcDataRequiredHandler without causing any weird effects
|
||||
bool setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const;
|
||||
void eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock) const;
|
||||
|
||||
//The block data
|
||||
mutable std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare> m_pBlocks;
|
||||
// The block data
|
||||
mutable std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare> m_pBlocks;
|
||||
|
||||
//The cache of uncompressed blocks. The uncompressed block data and the timestamps are stored here rather
|
||||
//than in the Block class. This is so that in the future each VolumeIterator might to maintain its own cache
|
||||
//of blocks. However, this could mean the same block data is uncompressed and modified in more than one
|
||||
//location in memory... could be messy with threading.
|
||||
mutable std::vector< LoadedBlock* > m_vecUncompressedBlockCache;
|
||||
// The cache of uncompressed blocks. The uncompressed block data and the timestamps are stored here rather
|
||||
// than in the Block class. This is so that in the future each VolumeIterator might to maintain its own cache
|
||||
// of blocks. However, this could mean the same block data is uncompressed and modified in more than one
|
||||
// location in memory... could be messy with threading.
|
||||
mutable std::vector< Block<VoxelType>* > m_vecBlocksWithUncompressedData;
|
||||
mutable uint32_t m_uTimestamper;
|
||||
mutable Vector3DInt32 m_v3dLastAccessedBlockPos;
|
||||
mutable Block<VoxelType>* m_pLastAccessedBlock;
|
||||
uint32_t m_uMaxNumberOfUncompressedBlocks;
|
||||
uint32_t m_uMaxNumberOfBlocksInMemory;
|
||||
|
||||
//The size of the volume
|
||||
// The size of the volume
|
||||
Region m_regValidRegionInBlocks;
|
||||
|
||||
//The size of the blocks
|
||||
// The size of the blocks
|
||||
uint16_t m_uBlockSideLength;
|
||||
uint8_t m_uBlockSideLengthPower;
|
||||
|
||||
//The compressor used by the Blocks to compress their data if required.
|
||||
// The compressor used by the Blocks to compress their data if required.
|
||||
Compressor* m_pCompressor;
|
||||
Pager<VoxelType>* m_pPager;
|
||||
|
||||
bool m_bPagingEnabled;
|
||||
// Whether we created the compressor or whether it was provided
|
||||
// by the user. This controls whether we delete it on destruction.
|
||||
bool m_bIsOurCompressor;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,7 @@ freely, subject to the following restrictions:
|
||||
|
||||
#include "PolyVoxCore/Impl/ErrorHandling.h"
|
||||
|
||||
//Included here rather than in the .h because it refers to LargeVolume (avoids forward declaration)
|
||||
#include "PolyVoxCore/ConstVolumeProxy.h"
|
||||
#include "PolyVoxCore/MinizCompressor.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
@ -37,17 +36,19 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
LargeVolume<VoxelType>::LargeVolume
|
||||
(
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
|
||||
uint16_t uBlockSideLength
|
||||
const Region& regValid,
|
||||
uint16_t uBlockSideLength
|
||||
)
|
||||
:BaseVolume<VoxelType>(Region::MaxRegion)
|
||||
:BaseVolume<VoxelType>(regValid)
|
||||
{
|
||||
m_funcDataRequiredHandler = dataRequiredHandler;
|
||||
m_funcDataOverflowHandler = dataOverflowHandler;
|
||||
m_bPagingEnabled = true;
|
||||
//Create a volume of the right size.
|
||||
initialise(Region::MaxRegion,uBlockSideLength);
|
||||
m_uBlockSideLength = uBlockSideLength;
|
||||
|
||||
m_pCompressor = new MinizCompressor();
|
||||
m_bIsOurCompressor = true;
|
||||
|
||||
m_pPager = 0;
|
||||
|
||||
initialise();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -64,20 +65,20 @@ namespace PolyVox
|
||||
(
|
||||
const Region& regValid,
|
||||
Compressor* pCompressor,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
|
||||
bool bPagingEnabled,
|
||||
Pager<VoxelType>* pPager,
|
||||
uint16_t uBlockSideLength
|
||||
)
|
||||
:BaseVolume<VoxelType>(regValid)
|
||||
,m_pCompressor(pCompressor)
|
||||
{
|
||||
m_funcDataRequiredHandler = dataRequiredHandler;
|
||||
m_funcDataOverflowHandler = dataOverflowHandler;
|
||||
m_bPagingEnabled = bPagingEnabled;
|
||||
|
||||
//Create a volume of the right size.
|
||||
initialise(regValid,uBlockSideLength);
|
||||
m_uBlockSideLength = uBlockSideLength;
|
||||
|
||||
m_pCompressor = pCompressor;
|
||||
m_bIsOurCompressor = false;
|
||||
|
||||
m_pPager = pPager;
|
||||
|
||||
initialise();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -100,6 +101,12 @@ namespace PolyVox
|
||||
LargeVolume<VoxelType>::~LargeVolume()
|
||||
{
|
||||
flushAll();
|
||||
|
||||
// Only delete the compressor if it was created by us (in the constructor), not by the user.
|
||||
if(m_bIsOurCompressor)
|
||||
{
|
||||
delete m_pCompressor;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -116,38 +123,83 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
|
||||
|
||||
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
|
||||
// Simply call through to the real implementation
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \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 eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
|
||||
case WrapModes::Border:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -171,7 +223,7 @@ namespace PolyVox
|
||||
|
||||
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
|
||||
return pUncompressedBlock->getVoxel(xOffset,yOffset,zOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -189,61 +241,6 @@ namespace PolyVox
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Clamp:
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
//Get the voxel value
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
//No need to break as we've returned
|
||||
}
|
||||
case WrapModes::Border:
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
//No need to break as we've returned
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Increasing the size of the block cache will increase memory but may improve performance.
|
||||
/// You may want to set this to a large value (e.g. 1024) when you are first loading your
|
||||
@ -272,6 +269,56 @@ namespace PolyVox
|
||||
m_uMaxNumberOfBlocksInMemory = uMaxNumberOfBlocksInMemory;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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 tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
|
||||
}
|
||||
|
||||
// This validation is skipped if the wrap mode is 'DontCheck'
|
||||
if(eWrapMode == WrapModes::Validate)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
|
||||
|
||||
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param uXPos the \c x position of the voxel
|
||||
/// \param uYPos the \c y position of the voxel
|
||||
@ -346,7 +393,7 @@ namespace PolyVox
|
||||
for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++)
|
||||
{
|
||||
Vector3DInt32 pos(x,y,z);
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(pos);
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(pos);
|
||||
|
||||
if(itBlock != m_pBlocks.end())
|
||||
{
|
||||
@ -377,7 +424,7 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::flushAll()
|
||||
{
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator i;
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator i;
|
||||
//Replaced the for loop here as the call to
|
||||
//eraseBlock was invalidating the iterator.
|
||||
while(m_pBlocks.size() > 0)
|
||||
@ -411,7 +458,7 @@ namespace PolyVox
|
||||
for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++)
|
||||
{
|
||||
Vector3DInt32 pos(x,y,z);
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(pos);
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(pos);
|
||||
if(itBlock == m_pBlocks.end())
|
||||
{
|
||||
// not loaded, not unloading
|
||||
@ -434,44 +481,42 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::clearBlockCache(void)
|
||||
{
|
||||
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
||||
for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
m_vecUncompressedBlockCache[ct]->block.compress(m_pCompressor);
|
||||
m_vecBlocksWithUncompressedData[ct]->destroyUncompressedData();
|
||||
}
|
||||
m_vecUncompressedBlockCache.clear();
|
||||
m_vecBlocksWithUncompressedData.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This function should probably be made internal...
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength)
|
||||
void LargeVolume<VoxelType>::initialise()
|
||||
{
|
||||
//Validate parameters
|
||||
if(uBlockSideLength == 0)
|
||||
if(m_uBlockSideLength == 0)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length cannot be zero.");
|
||||
}
|
||||
if(!isPowerOf2(uBlockSideLength))
|
||||
|
||||
if(!isPowerOf2(m_uBlockSideLength))
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two.");
|
||||
}
|
||||
|
||||
if(!m_pCompressor)
|
||||
{
|
||||
POLYVOX_THROW(std::invalid_argument, "You must provide a compressor for the LargeVolume to use.");
|
||||
POLYVOX_THROW(std::invalid_argument, "You must provide a valid compressor for the LargeVolume to use.");
|
||||
}
|
||||
|
||||
m_uTimestamper = 0;
|
||||
m_uMaxNumberOfUncompressedBlocks = 16;
|
||||
m_uBlockSideLength = uBlockSideLength;
|
||||
m_uMaxNumberOfBlocksInMemory = 1024;
|
||||
m_v3dLastAccessedBlockPos = Vector3DInt32(0,0,0); //There are no invalid positions, but initially the m_pLastAccessedBlock pointer will be null;
|
||||
m_pLastAccessedBlock = 0;
|
||||
|
||||
this->m_regValidRegion = regValidRegion;
|
||||
|
||||
//Compute the block side length
|
||||
m_uBlockSideLength = uBlockSideLength;
|
||||
m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
|
||||
|
||||
m_regValidRegionInBlocks.setLowerX(this->m_regValidRegion.getLowerX() >> m_uBlockSideLengthPower);
|
||||
@ -496,63 +541,40 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void LargeVolume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itBlock) const
|
||||
void LargeVolume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock) const
|
||||
{
|
||||
if(m_funcDataOverflowHandler)
|
||||
if(itBlock->second.hasUncompressedData())
|
||||
{
|
||||
itBlock->second.destroyUncompressedData();
|
||||
}
|
||||
|
||||
if(m_pPager)
|
||||
{
|
||||
Vector3DInt32 v3dPos = itBlock->first;
|
||||
Vector3DInt32 v3dLower(v3dPos.getX() << m_uBlockSideLengthPower, v3dPos.getY() << m_uBlockSideLengthPower, v3dPos.getZ() << m_uBlockSideLengthPower);
|
||||
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1);
|
||||
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
ConstVolumeProxy<VoxelType> ConstVolumeProxy(*this, reg);
|
||||
|
||||
m_funcDataOverflowHandler(ConstVolumeProxy, reg);
|
||||
m_pPager->pageOut(reg, &(itBlock->second));
|
||||
}
|
||||
if(m_pCompressor)
|
||||
|
||||
for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
||||
// find the block in the uncompressed cache
|
||||
if(m_vecBlocksWithUncompressedData[ct] == &(itBlock->second))
|
||||
{
|
||||
// find the block in the uncompressed cache
|
||||
if(m_vecUncompressedBlockCache[ct] == &(itBlock->second))
|
||||
{
|
||||
// TODO: compression is unneccessary? or will not compressing this cause a memleak?
|
||||
itBlock->second.block.compress(m_pCompressor);
|
||||
// put last object in cache here
|
||||
m_vecUncompressedBlockCache[ct] = m_vecUncompressedBlockCache.back();
|
||||
// decrease cache size by one since last element is now in here twice
|
||||
m_vecUncompressedBlockCache.resize(m_vecUncompressedBlockCache.size()-1);
|
||||
break;
|
||||
}
|
||||
// put last object in cache here
|
||||
m_vecBlocksWithUncompressedData[ct] = m_vecBlocksWithUncompressedData.back();
|
||||
// decrease cache size by one since last element is now in here twice
|
||||
m_vecBlocksWithUncompressedData.resize(m_vecBlocksWithUncompressedData.size()-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pBlocks.erase(itBlock);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool LargeVolume<VoxelType>::setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
{
|
||||
//We don't have any range checks in this function because it
|
||||
//is a private function only called by the ConstVolumeProxy. The
|
||||
//ConstVolumeProxy takes care of ensuring the range is appropriate.
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
|
||||
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
|
||||
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
|
||||
|
||||
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
||||
|
||||
//Return true to indicate that we modified a voxel.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename VoxelType>
|
||||
Block<VoxelType>* LargeVolume<VoxelType>::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const
|
||||
{
|
||||
@ -564,25 +586,25 @@ namespace PolyVox
|
||||
//This check should also provide a significant speed boost as usually it is true.
|
||||
if((v3dBlockPos == m_v3dLastAccessedBlockPos) && (m_pLastAccessedBlock != 0))
|
||||
{
|
||||
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||
POLYVOX_ASSERT(m_pLastAccessedBlock->hasUncompressedData(), "Last accessed block has no uncompressed data.");
|
||||
return m_pLastAccessedBlock;
|
||||
}
|
||||
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(v3dBlockPos);
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itBlock = m_pBlocks.find(v3dBlockPos);
|
||||
// check whether the block is already loaded
|
||||
if(itBlock == m_pBlocks.end())
|
||||
{
|
||||
//The block is not in the map, so we will have to create a new block and add it.
|
||||
//Before we do so, we might want to dump some existing data to make space. We
|
||||
//Only do this if paging is enabled.
|
||||
if(m_bPagingEnabled)
|
||||
if(m_pPager)
|
||||
{
|
||||
// check wether another block needs to be unloaded before this one can be loaded
|
||||
if(m_pBlocks.size() == m_uMaxNumberOfBlocksInMemory)
|
||||
{
|
||||
// find the least recently used block
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator i;
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator itUnloadBlock = m_pBlocks.begin();
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator i;
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator itUnloadBlock = m_pBlocks.begin();
|
||||
for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++)
|
||||
{
|
||||
if(i->second.timestamp < itUnloadBlock->second.timestamp)
|
||||
@ -595,20 +617,17 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
// create the new block
|
||||
LoadedBlock newBlock(m_uBlockSideLength);
|
||||
Block<VoxelType> newBlock(m_uBlockSideLength, m_pCompressor);
|
||||
|
||||
// Blocks start out compressed - should we change this?
|
||||
// Or maybe we should just 'seed' them with compressed data,
|
||||
// rather than creating an empty block and then compressing?
|
||||
newBlock.block.compress(m_pCompressor);
|
||||
|
||||
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
||||
auto retVal = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock));
|
||||
itBlock = retVal.first;
|
||||
POLYVOX_ASSERT(retVal.second == true, "Element was not supposed to exist!");
|
||||
|
||||
//We have created the new block. If paging is enabled it should be used to
|
||||
//fill in the required data. Otherwise it is just left in the default state.
|
||||
if(m_bPagingEnabled)
|
||||
if(m_pPager)
|
||||
{
|
||||
if(m_funcDataRequiredHandler)
|
||||
//if(m_funcDataRequiredHandler)
|
||||
{
|
||||
// "load" will actually call setVoxel, which will in turn call this function again but the block will be found
|
||||
// so this if(itBlock == m_pBlocks.end()) never is entered
|
||||
@ -616,26 +635,25 @@ namespace PolyVox
|
||||
Vector3DInt32 v3dLower(v3dBlockPos.getX() << m_uBlockSideLengthPower, v3dBlockPos.getY() << m_uBlockSideLengthPower, v3dBlockPos.getZ() << m_uBlockSideLengthPower);
|
||||
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1);
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
ConstVolumeProxy<VoxelType> ConstVolumeProxy(*this, reg);
|
||||
m_funcDataRequiredHandler(ConstVolumeProxy, reg);
|
||||
|
||||
m_pPager->pageIn(reg, &(itBlock->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Get the block and mark that we accessed it
|
||||
LoadedBlock& loadedBlock = itBlock->second;
|
||||
loadedBlock.timestamp = ++m_uTimestamper;
|
||||
Block<VoxelType>& block = itBlock->second;
|
||||
block.timestamp = ++m_uTimestamper;
|
||||
m_v3dLastAccessedBlockPos = v3dBlockPos;
|
||||
m_pLastAccessedBlock = &(loadedBlock.block);
|
||||
m_pLastAccessedBlock = █
|
||||
|
||||
if(loadedBlock.block.m_bIsCompressed == false)
|
||||
if(block.hasUncompressedData())
|
||||
{
|
||||
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||
return m_pLastAccessedBlock;
|
||||
}
|
||||
|
||||
//If we are allowed to compress then check whether we need to
|
||||
if((m_pCompressor) && (m_vecUncompressedBlockCache.size() == m_uMaxNumberOfUncompressedBlocks))
|
||||
if(m_vecBlocksWithUncompressedData.size() == m_uMaxNumberOfUncompressedBlocks)
|
||||
{
|
||||
int32_t leastRecentlyUsedBlockIndex = -1;
|
||||
uint32_t uLeastRecentTimestamp = (std::numeric_limits<uint32_t>::max)();
|
||||
@ -643,30 +661,30 @@ namespace PolyVox
|
||||
//Currently we find the oldest block by iterating over the whole array. Of course we could store the blocks sorted by
|
||||
//timestamp (set, priority_queue, etc) but then we'll need to move them around as the timestamp changes. Can come back
|
||||
//to this if it proves to be a bottleneck (compraed to the cost of actually doing the compression/decompression).
|
||||
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
|
||||
for(uint32_t ct = 0; ct < m_vecBlocksWithUncompressedData.size(); ct++)
|
||||
{
|
||||
if(m_vecUncompressedBlockCache[ct]->timestamp < uLeastRecentTimestamp)
|
||||
if(m_vecBlocksWithUncompressedData[ct]->timestamp < uLeastRecentTimestamp)
|
||||
{
|
||||
uLeastRecentTimestamp = m_vecUncompressedBlockCache[ct]->timestamp;
|
||||
uLeastRecentTimestamp = m_vecBlocksWithUncompressedData[ct]->timestamp;
|
||||
leastRecentlyUsedBlockIndex = ct;
|
||||
}
|
||||
}
|
||||
|
||||
//Compress the least recently used block.
|
||||
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex]->block.compress(m_pCompressor);
|
||||
m_vecBlocksWithUncompressedData[leastRecentlyUsedBlockIndex]->destroyUncompressedData();
|
||||
|
||||
//We don't actually remove any elements from this vector, we
|
||||
//simply change the pointer to point at the new uncompressed bloack.
|
||||
m_vecUncompressedBlockCache[leastRecentlyUsedBlockIndex] = &loadedBlock;
|
||||
m_vecBlocksWithUncompressedData[leastRecentlyUsedBlockIndex] = █
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vecUncompressedBlockCache.push_back(&loadedBlock);
|
||||
m_vecBlocksWithUncompressedData.push_back(&block);
|
||||
}
|
||||
|
||||
loadedBlock.block.uncompress(m_pCompressor);
|
||||
block.createUncompressedData();
|
||||
|
||||
m_pLastAccessedBlock = &(loadedBlock.block);
|
||||
m_pLastAccessedBlock = &(block);
|
||||
POLYVOX_ASSERT(m_pLastAccessedBlock->m_tUncompressedData, "Block has no uncompressed data");
|
||||
return m_pLastAccessedBlock;
|
||||
}
|
||||
@ -691,19 +709,80 @@ namespace PolyVox
|
||||
uint32_t uSizeInBytes = sizeof(LargeVolume);
|
||||
|
||||
//Memory used by the blocks
|
||||
typename std::map<Vector3DInt32, LoadedBlock, BlockPositionCompare>::iterator i;
|
||||
typename std::map<Vector3DInt32, Block<VoxelType>, BlockPositionCompare>::iterator i;
|
||||
for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++)
|
||||
{
|
||||
//Inaccurate - account for rest of loaded block.
|
||||
uSizeInBytes += i->second.block.calculateSizeInBytes();
|
||||
uSizeInBytes += i->second.calculateSizeInBytes();
|
||||
}
|
||||
|
||||
//Memory used by the block cache.
|
||||
uSizeInBytes += m_vecUncompressedBlockCache.capacity() * sizeof(LoadedBlock);
|
||||
uSizeInBytes += m_vecUncompressedBlockCache.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
|
||||
uSizeInBytes += m_vecBlocksWithUncompressedData.capacity() * sizeof(Block<VoxelType>);
|
||||
uSizeInBytes += m_vecBlocksWithUncompressedData.size() * m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
|
||||
|
||||
return uSizeInBytes;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
|
||||
{
|
||||
// This function should never be called because one of the specialisations should always match.
|
||||
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType LargeVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
|
||||
{
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
|
||||
|
||||
Block<VoxelType>* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
return pUncompressedBlock->getVoxel(xOffset,yOffset,zOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ namespace PolyVox
|
||||
}
|
||||
else
|
||||
{
|
||||
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -296,7 +296,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -306,7 +306,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -316,7 +316,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -326,7 +326,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -336,7 +336,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -346,7 +346,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -356,7 +356,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -366,7 +366,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -378,7 +378,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -388,7 +388,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -398,7 +398,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -408,7 +408,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -418,7 +418,7 @@ namespace PolyVox
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -428,7 +428,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -438,7 +438,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -448,7 +448,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -458,7 +458,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -470,7 +470,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -480,7 +480,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -490,7 +490,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -500,7 +500,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -510,7 +510,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -520,7 +520,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -530,7 +530,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -540,7 +540,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -550,7 +550,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,8 +192,8 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y-1,z));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z));
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z, WrapModes::Border));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, WrapModes::Border));
|
||||
|
||||
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
|
||||
}
|
||||
@ -206,8 +206,8 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
|
||||
{
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z-1));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxelAt(x,y,z));
|
||||
AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1, WrapModes::Border));
|
||||
AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z, WrapModes::Border));
|
||||
|
||||
satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
|
||||
}
|
||||
@ -234,14 +234,14 @@ namespace PolyVox
|
||||
int32_t satUpperY = iSrcY + border;
|
||||
int32_t satUpperZ = iSrcZ + border;
|
||||
|
||||
AccumulationType a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ);
|
||||
AccumulationType b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ);
|
||||
AccumulationType c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ);
|
||||
AccumulationType d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ);
|
||||
AccumulationType e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ);
|
||||
AccumulationType f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ);
|
||||
AccumulationType g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ);
|
||||
AccumulationType h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ);
|
||||
AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ, WrapModes::Border);
|
||||
AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ, WrapModes::Border);
|
||||
AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ, WrapModes::Border);
|
||||
|
||||
AccumulationType sum = h+c-d-g-f-a+b+e;
|
||||
uint32_t sideLength = border * 2 + 1;
|
||||
|
49
library/PolyVoxCore/include/PolyVoxCore/Pager.h
Normal file
49
library/PolyVoxCore/include/PolyVoxCore/Pager.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*******************************************************************************
|
||||
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_Pager_H__
|
||||
#define __PolyVox_Pager_H__
|
||||
|
||||
#include "PolyVoxCore/Impl/Block.h"
|
||||
#include "PolyVoxCore/Impl/TypeDef.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
/**
|
||||
* Provides an interface for performing paging of data.
|
||||
*/
|
||||
template <typename VoxelType>
|
||||
class Pager
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
Pager() {};
|
||||
/// Destructor
|
||||
virtual ~Pager() {};
|
||||
|
||||
virtual void pageIn(const Region& region, Block<VoxelType>* pBlockData) = 0;
|
||||
virtual void pageOut(const Region& region, Block<VoxelType>* pBlockData) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__PolyVox_Pager_H__
|
@ -116,18 +116,26 @@ namespace PolyVox
|
||||
~RawVolume();
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
@ -146,6 +154,14 @@ namespace PolyVox
|
||||
private:
|
||||
void initialise(const Region& regValidRegion);
|
||||
|
||||
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
|
||||
|
||||
//The block data
|
||||
VoxelType* m_pData;
|
||||
};
|
||||
|
@ -74,38 +74,83 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
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()
|
||||
];
|
||||
// Simply call through to the real implementation
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \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 eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
|
||||
case WrapModes::Border:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -148,58 +193,53 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
/// \return The voxel value
|
||||
/// \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 tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
void RawVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
switch(eWrapMode)
|
||||
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
|
||||
{
|
||||
case WrapModes::Clamp:
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
|
||||
}
|
||||
|
||||
//Get the voxel value
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
//No need to break as we've returned
|
||||
}
|
||||
case WrapModes::Border:
|
||||
// This validation is skipped if the wrap mode is 'DontCheck'
|
||||
if(eWrapMode == WrapModes::Validate)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
//No need to break as we've returned
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
m_pData
|
||||
[
|
||||
iLocalXPos +
|
||||
iLocalYPos * this->getWidth() +
|
||||
iLocalZPos * this->getWidth() * this->getHeight()
|
||||
] = tValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
void RawVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -285,5 +325,66 @@ namespace PolyVox
|
||||
return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
|
||||
{
|
||||
// This function should never be called because one of the specialisations should always match.
|
||||
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) 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()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace PolyVox
|
||||
}
|
||||
else
|
||||
{
|
||||
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -239,7 +239,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -249,7 +249,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -259,7 +259,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -269,7 +269,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -279,7 +279,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -289,7 +289,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -299,7 +299,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -309,7 +309,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -321,7 +321,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -331,7 +331,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -341,7 +341,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -351,7 +351,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -361,7 +361,7 @@ namespace PolyVox
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -371,7 +371,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -381,7 +381,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -391,7 +391,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -401,7 +401,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -413,7 +413,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -423,7 +423,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -433,7 +433,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -443,7 +443,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -453,7 +453,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -463,7 +463,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -473,7 +473,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -483,7 +483,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -493,7 +493,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight());
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,9 @@ namespace PolyVox
|
||||
/// Tests whether the given position is contained in the 'z' range of this Region.
|
||||
bool containsPointInZ(int32_t pos, int8_t boundary = 0) const;
|
||||
|
||||
/// Tests whether the given Region is contained in this Region.
|
||||
bool containsRegion(const Region& reg, uint8_t boundary = 0) const;
|
||||
|
||||
/// Enlarges the Region so that it contains the specified position.
|
||||
void accumulate(int32_t iX, int32_t iY, int32_t iZ);
|
||||
/// Enlarges the Region so that it contains the specified position.
|
||||
|
@ -155,18 +155,26 @@ namespace PolyVox
|
||||
~SimpleVolume();
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos) const;
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Border, VoxelType tBorder = VoxelType()) const;
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const;
|
||||
|
||||
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
|
||||
/// Gets a voxel at the position given by a 3D vector
|
||||
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
|
||||
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
|
||||
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
|
||||
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
|
||||
/// Sets the voxel at the position given by a 3D vector
|
||||
@ -185,6 +193,14 @@ namespace PolyVox
|
||||
private:
|
||||
void initialise(const Region& regValidRegion, uint16_t uBlockSideLength);
|
||||
|
||||
// A trick to implement specialization of template member functions in template classes. See http://stackoverflow.com/a/4951057
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const;
|
||||
VoxelType getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType tBorder) const;
|
||||
|
||||
Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const;
|
||||
|
||||
//The block data
|
||||
|
@ -74,38 +74,83 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tBorder) const
|
||||
{
|
||||
// PolyVox does not throw an exception when a voxel is out of range. Please see 'Error Handling' in the User Manual.
|
||||
POLYVOX_ASSERT(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)), "Position is outside valid region");
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
|
||||
|
||||
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
|
||||
// Simply call through to the real implementation
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<eWrapMode>(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// This version of the function requires the wrap mode to be specified as a
|
||||
/// template parameter, which can provide better performance.
|
||||
/// \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
|
||||
/// \tparam eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos) const
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
// Simply call through to the real implementation
|
||||
return getVoxel<eWrapMode>(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \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 eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
switch(eWrapMode)
|
||||
{
|
||||
case WrapModes::Validate:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Validate>(), tBorder);
|
||||
case WrapModes::Clamp:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Clamp>(), tBorder);
|
||||
case WrapModes::Border:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::Border>(), tBorder);
|
||||
case WrapModes::AssumeValid:
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder);
|
||||
default:
|
||||
// Should never happen
|
||||
POLYVOX_ASSERT(false, "Invalid wrap mode");
|
||||
return VoxelType();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This version of the function is provided so that the wrap mode does not need
|
||||
/// to be specified as a template parameter, as it may be confusing to some users.
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// \param tBorder The border value to use if the wrap mode is set to 'Border'.
|
||||
/// \return The voxel value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
{
|
||||
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -148,58 +193,53 @@ namespace PolyVox
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
/// \return The voxel value
|
||||
/// \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 tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelWithWrapping(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
void SimpleVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
switch(eWrapMode)
|
||||
if((eWrapMode != WrapModes::Validate) && (eWrapMode != WrapModes::AssumeValid))
|
||||
{
|
||||
case WrapModes::Clamp:
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
POLYVOX_THROW(std::invalid_argument, "Invalid wrap mode in call to setVoxel(). It must be 'None' or 'DontCheck'.");
|
||||
}
|
||||
|
||||
//Get the voxel value
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
//No need to break as we've returned
|
||||
}
|
||||
case WrapModes::Border:
|
||||
// This validation is skipped if the wrap mode is 'DontCheck'
|
||||
if(eWrapMode == WrapModes::Validate)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxel(uXPos, uYPos, uZPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
//No need to break as we've returned
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Should never happen
|
||||
POLYVOX_THROW(std::invalid_argument, "Wrap mode parameter has an unrecognised value.");
|
||||
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
|
||||
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
|
||||
const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
|
||||
|
||||
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The 3D position of the voxel
|
||||
/// \return The voxel value
|
||||
/// \param v3dPos the 3D position of the voxel
|
||||
/// \param tValue the value to which the voxel will be set
|
||||
/// \param eWrapMode Specifies the behaviour when the requested position is outside of the volume.
|
||||
/// This must be set to 'None' or 'DontCheck'. Other wrap modes cannot be used when writing to volume data.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelWithWrapping(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder) const
|
||||
void SimpleVolume<VoxelType>::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, WrapMode eWrapMode)
|
||||
{
|
||||
return getVoxelWithWrapping(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, tBorder);
|
||||
setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eWrapMode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -336,5 +376,66 @@ namespace PolyVox
|
||||
return uSizeInBytes;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
template <WrapMode eWrapMode>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<eWrapMode>, VoxelType tBorder) const
|
||||
{
|
||||
// This function should never be called because one of the specialisations should always match.
|
||||
POLYVOX_ASSERT(false, "This function is not implemented and should never be called!");
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Validate>, VoxelType tBorder) 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, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Clamp>, VoxelType tBorder) const
|
||||
{
|
||||
//Perform clamping
|
||||
uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
|
||||
uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
|
||||
uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
|
||||
uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
|
||||
uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
|
||||
uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
|
||||
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::Border>, VoxelType tBorder) const
|
||||
{
|
||||
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
|
||||
{
|
||||
return getVoxelImpl(uXPos, uYPos, uZPos, WrapModeType<WrapModes::AssumeValid>(), tBorder); // No wrapping as we've just validated the position.
|
||||
}
|
||||
else
|
||||
{
|
||||
return tBorder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType SimpleVolume<VoxelType>::getVoxelImpl(int32_t uXPos, int32_t uYPos, int32_t uZPos, WrapModeType<WrapModes::AssumeValid>, VoxelType /*tBorder*/) const
|
||||
{
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
|
||||
const uint16_t xOffset = static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
|
||||
const uint16_t yOffset = static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
|
||||
const uint16_t zOffset = static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
|
||||
|
||||
typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
|
||||
|
||||
return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ namespace PolyVox
|
||||
}
|
||||
else
|
||||
{
|
||||
return getVoxelAt(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
return getVoxelImpl(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -315,7 +315,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -325,7 +325,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -335,7 +335,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -345,7 +345,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -355,7 +355,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -365,7 +365,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -375,7 +375,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -385,7 +385,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -397,7 +397,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -407,7 +407,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -417,7 +417,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -427,7 +427,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -437,7 +437,7 @@ namespace PolyVox
|
||||
{
|
||||
return *mCurrentVoxel;
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -447,7 +447,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -457,7 +457,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -467,7 +467,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -477,7 +477,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -489,7 +489,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -499,7 +499,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -509,7 +509,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -519,7 +519,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -529,7 +529,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -539,7 +539,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -549,7 +549,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -559,7 +559,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@ -569,7 +569,7 @@ namespace PolyVox
|
||||
{
|
||||
return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
|
||||
}
|
||||
return this->mVolume->getVoxelWithWrapping(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1,this->m_eWrapMode, this->m_tBorder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ namespace PolyVox
|
||||
{
|
||||
for(int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++,dx++)
|
||||
{
|
||||
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxelAt(sx,sy,sz);
|
||||
const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz, WrapModes::AssumeValid); // FIXME use templatised version of getVoxel(), but watch out for Linux compile issues.
|
||||
const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel);
|
||||
m_pVolDst->setVoxelAt(dx,dy,dz,tDstVoxel);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ namespace PolyVox
|
||||
{
|
||||
// Passing zero to the stream constructor guarentees it will discard all input. See
|
||||
// here http://stackoverflow.com/a/8244052 and here http://stackoverflow.com/a/6240980
|
||||
static std::ostream s_NullStream = std::ostream(0);
|
||||
static std::ostream s_NullStream(0);
|
||||
return &s_NullStream;
|
||||
}
|
||||
|
||||
|
@ -301,6 +301,23 @@ namespace PolyVox
|
||||
&& (pos >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* that a region is considered to be inside of itself.
|
||||
* \param reg The region to test.
|
||||
* \param boundary The desired boundary value.
|
||||
*/
|
||||
bool Region::containsRegion(const Region& reg, uint8_t boundary) const
|
||||
{
|
||||
return (reg.m_iUpperX <= m_iUpperX - boundary)
|
||||
&& (reg.m_iUpperY <= m_iUpperY - boundary)
|
||||
&& (reg.m_iUpperZ <= m_iUpperZ - boundary)
|
||||
&& (reg.m_iLowerX >= m_iLowerX + boundary)
|
||||
&& (reg.m_iLowerY >= m_iLowerY + boundary)
|
||||
&& (reg.m_iLowerZ >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* After calling this functions, the extents of this Region are given by the intersection
|
||||
* of this Region and the one it was cropped to.
|
||||
@ -470,6 +487,7 @@ namespace PolyVox
|
||||
{
|
||||
shrink(v3dAmount.getX(), v3dAmount.getY(), v3dAmount.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function only returns true if the regions are really intersecting and not simply touching.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user