Stuff related to valid regions is being moved from BaseVolum to RawVolume, as PagedVolume is now infinite.

This commit is contained in:
David Williams 2015-03-04 22:42:14 +01:00
parent d3618ca688
commit bd6efe8c3c
11 changed files with 185 additions and 189 deletions

View File

@ -98,7 +98,7 @@ namespace PolyVox
return m_pElements[z * m_uDimensions[0] * m_uDimensions[1] + y * m_uDimensions[0] + x]; return m_pElements[z * m_uDimensions[0] * m_uDimensions[1] + y * m_uDimensions[0] + x];
} }
uint32_t getDimension(uint32_t dimension) uint32_t getDimension(uint32_t dimension) const
{ {
return m_uDimensions[dimension]; return m_uDimensions[dimension];
} }

View File

@ -70,8 +70,6 @@ namespace PolyVox
Vector3DInt32 getPosition(void) const; Vector3DInt32 getPosition(void) const;
inline VoxelType getVoxel(void) const; inline VoxelType getVoxel(void) const;
bool isCurrentPositionValid(void) const;
void setPosition(const Vector3DInt32& v3dNewPos); void setPosition(const Vector3DInt32& v3dNewPos);
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
inline bool setVoxel(VoxelType tValue); inline bool setVoxel(VoxelType tValue);
@ -127,32 +125,10 @@ namespace PolyVox
WrapMode m_eWrapMode; WrapMode m_eWrapMode;
VoxelType m_tBorder; VoxelType m_tBorder;
//Whether the current position is inside the volume
//FIXME - Replace these with flags
bool m_bIsCurrentPositionValidInX;
bool m_bIsCurrentPositionValidInY;
bool m_bIsCurrentPositionValidInZ;
}; };
#endif #endif
public: public:
/// Gets the value used for voxels which are outside the volume
VoxelType getBorderValue(void) const;
/// Gets a Region representing the extents of the Volume.
const Region& getEnclosingRegion(void) const;
/// Gets the width of the volume in voxels.
int32_t getWidth(void) const;
/// Gets the height of the volume in voxels.
int32_t getHeight(void) const;
/// Gets the depth of the volume in voxels.
int32_t getDepth(void) const;
/// Gets the length of the longest side in voxels
int32_t getLongestSideLength(void) const;
/// Gets the length of the shortest side in voxels
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 /// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
template <WrapMode eWrapMode> template <WrapMode eWrapMode>
@ -166,8 +142,6 @@ namespace PolyVox
/// Gets a voxel at the position given by a 3D vector /// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) const; VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode = WrapModes::Validate, VoxelType tBorder = VoxelType()) 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 /// 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); 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 /// Sets the voxel at the position given by a 3D vector
@ -177,8 +151,8 @@ namespace PolyVox
uint32_t calculateSizeInBytes(void); uint32_t calculateSizeInBytes(void);
protected: protected:
/// Constructor for creating a fixed size volume. /// Constructor for creating a volume.
BaseVolume(const Region& regValid); BaseVolume();
/// Copy constructor /// Copy constructor
BaseVolume(const BaseVolume& rhs); BaseVolume(const BaseVolume& rhs);
@ -188,17 +162,6 @@ namespace PolyVox
/// Assignment operator /// Assignment operator
BaseVolume& operator=(const BaseVolume& rhs); BaseVolume& operator=(const BaseVolume& rhs);
//The size of the volume
Region m_regValidRegion;
//Some useful sizes
int32_t m_uLongestSideLength;
int32_t m_uShortestSideLength;
float m_fDiagonalLength;
//The border value
VoxelType m_tBorderValue;
}; };
} }

View File

@ -29,9 +29,7 @@ namespace PolyVox
/// \sa RawVolume, PagedVolume /// \sa RawVolume, PagedVolume
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> template <typename VoxelType>
BaseVolume<VoxelType>::BaseVolume(const Region& regValid) BaseVolume<VoxelType>::BaseVolume()
:m_regValidRegion(regValid)
,m_tBorderValue()
{ {
} }
@ -69,90 +67,6 @@ namespace PolyVox
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons."); POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
} }
////////////////////////////////////////////////////////////////////////////////
/// The border value is returned whenever an attempt is made to read a voxel which
/// is outside the extents of the volume.
/// \return The value used for voxels outside of the volume
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType BaseVolume<VoxelType>::getBorderValue(void) const
{
return m_tBorderValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \return A Region representing the extent of the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
const Region& BaseVolume<VoxelType>::getEnclosingRegion(void) const
{
return m_regValidRegion;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The width of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the width is 64.
/// \sa getHeight(), getDepth()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t BaseVolume<VoxelType>::getWidth(void) const
{
return m_regValidRegion.getUpperX() - m_regValidRegion.getLowerX() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The height of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the height is 64.
/// \sa getWidth(), getDepth()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t BaseVolume<VoxelType>::getHeight(void) const
{
return m_regValidRegion.getUpperY() - m_regValidRegion.getLowerY() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The depth of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the depth is 64.
/// \sa getWidth(), getHeight()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t BaseVolume<VoxelType>::getDepth(void) const
{
return m_regValidRegion.getUpperZ() - m_regValidRegion.getLowerZ() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the shortest side in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return 256.
/// \sa getLongestSideLength(), getDiagonalLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t BaseVolume<VoxelType>::getShortestSideLength(void) const
{
return m_uShortestSideLength;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the longest side in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return 1024.
/// \sa getShortestSideLength(), getDiagonalLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t BaseVolume<VoxelType>::getLongestSideLength(void) const
{
return m_uLongestSideLength;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the diagonal in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return sqrt(256*256+512*512+1024*1024)
/// = 1173.139. This value is computed on volume creation so retrieving it is fast.
/// \sa getShortestSideLength(), getLongestSideLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
float BaseVolume<VoxelType>::getDiagonalLength(void) const
{
return m_fDiagonalLength;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// This version of the function requires the wrap mode to be specified as a /// This version of the function requires the wrap mode to be specified as a
/// template parameter, which can provide better performance. /// template parameter, which can provide better performance.
@ -221,15 +135,6 @@ namespace PolyVox
return VoxelType(); return VoxelType();
} }
////////////////////////////////////////////////////////////////////////////////
/// \param tBorder The value to use for voxels outside the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void BaseVolume<VoxelType>::setBorderValue(const VoxelType& tBorder)
{
m_tBorderValue = tBorder;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel /// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel /// \param uYPos the \c y position of the voxel

View File

@ -34,9 +34,6 @@ namespace PolyVox
,mZPosInVolume(0) ,mZPosInVolume(0)
,m_eWrapMode(WrapModes::Border) ,m_eWrapMode(WrapModes::Border)
,m_tBorder() ,m_tBorder()
,m_bIsCurrentPositionValidInX(false)
,m_bIsCurrentPositionValidInY(false)
,m_bIsCurrentPositionValidInZ(false)
{ {
} }
@ -60,13 +57,6 @@ namespace PolyVox
return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume); return mVolume->getVoxel(mXPosInVolume, mYPosInVolume, mZPosInVolume);
} }
template <typename VoxelType>
template <typename DerivedVolumeType>
bool inline BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::isCurrentPositionValid(void) const
{
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
}
template <typename VoxelType> template <typename VoxelType>
template <typename DerivedVolumeType> template <typename DerivedVolumeType>
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::setPosition(const Vector3DInt32& v3dNewPos) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::setPosition(const Vector3DInt32& v3dNewPos)
@ -81,10 +71,6 @@ namespace PolyVox
mXPosInVolume = xPos; mXPosInVolume = xPos;
mYPosInVolume = yPos; mYPosInVolume = yPos;
mZPosInVolume = zPos; mZPosInVolume = zPos;
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(xPos);
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(yPos);
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(zPos);
} }
template <typename VoxelType> template <typename VoxelType>
@ -107,7 +93,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveX(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveX(void)
{ {
mXPosInVolume++; mXPosInVolume++;
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -115,7 +100,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveY(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveY(void)
{ {
mYPosInVolume++; mYPosInVolume++;
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -123,7 +107,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveZ(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::movePositiveZ(void)
{ {
mZPosInVolume++; mZPosInVolume++;
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -131,7 +114,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeX(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeX(void)
{ {
mXPosInVolume--; mXPosInVolume--;
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -139,7 +121,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeY(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeY(void)
{ {
mYPosInVolume--; mYPosInVolume--;
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>
@ -147,7 +128,6 @@ namespace PolyVox
void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeZ(void) void BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::moveNegativeZ(void)
{ {
mZPosInVolume--; mZPosInVolume--;
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
} }
template <typename VoxelType> template <typename VoxelType>

View File

@ -320,7 +320,7 @@ namespace PolyVox
uint32_t m_uChunkCountLimit; uint32_t m_uChunkCountLimit;
// The size of the volume // The size of the volume
Region m_regValidRegionInChunks; //Region m_regValidRegionInChunks;
// The size of the chunks // The size of the chunks
uint16_t m_uChunkSideLength; uint16_t m_uChunkSideLength;

View File

@ -42,7 +42,7 @@ namespace PolyVox
Pager* pPager, Pager* pPager,
uint16_t uChunkSideLength uint16_t uChunkSideLength
) )
:BaseVolume<VoxelType>(Region::MaxRegion()) :BaseVolume<VoxelType>()
{ {
m_uChunkSideLength = uChunkSideLength; m_uChunkSideLength = uChunkSideLength;
m_pPager = pPager; m_pPager = pPager;
@ -203,11 +203,6 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void PagedVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) void PagedVolume<VoxelType>::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{ {
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
{
POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
}
const int32_t chunkX = uXPos >> m_uChunkSideLengthPower; const int32_t chunkX = uXPos >> m_uChunkSideLengthPower;
const int32_t chunkY = uYPos >> m_uChunkSideLengthPower; const int32_t chunkY = uYPos >> m_uChunkSideLengthPower;
const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower; const int32_t chunkZ = uZPos >> m_uChunkSideLengthPower;
@ -358,12 +353,12 @@ namespace PolyVox
//Compute the chunk side length //Compute the chunk side length
m_uChunkSideLengthPower = logBase2(m_uChunkSideLength); m_uChunkSideLengthPower = logBase2(m_uChunkSideLength);
m_regValidRegionInChunks.setLowerX(this->m_regValidRegion.getLowerX() >> m_uChunkSideLengthPower); /*m_regValidRegionInChunks.setLowerX(this->m_regValidRegion.getLowerX() >> m_uChunkSideLengthPower);
m_regValidRegionInChunks.setLowerY(this->m_regValidRegion.getLowerY() >> m_uChunkSideLengthPower); m_regValidRegionInChunks.setLowerY(this->m_regValidRegion.getLowerY() >> m_uChunkSideLengthPower);
m_regValidRegionInChunks.setLowerZ(this->m_regValidRegion.getLowerZ() >> m_uChunkSideLengthPower); m_regValidRegionInChunks.setLowerZ(this->m_regValidRegion.getLowerZ() >> m_uChunkSideLengthPower);
m_regValidRegionInChunks.setUpperX(this->m_regValidRegion.getUpperX() >> m_uChunkSideLengthPower); m_regValidRegionInChunks.setUpperX(this->m_regValidRegion.getUpperX() >> m_uChunkSideLengthPower);
m_regValidRegionInChunks.setUpperY(this->m_regValidRegion.getUpperY() >> m_uChunkSideLengthPower); m_regValidRegionInChunks.setUpperY(this->m_regValidRegion.getUpperY() >> m_uChunkSideLengthPower);
m_regValidRegionInChunks.setUpperZ(this->m_regValidRegion.getUpperZ() >> m_uChunkSideLengthPower); m_regValidRegionInChunks.setUpperZ(this->m_regValidRegion.getUpperZ() >> m_uChunkSideLengthPower);*/
//setMaxNumberOfChunks(m_uChunkCountLimit); //setMaxNumberOfChunks(m_uChunkCountLimit);
@ -371,9 +366,9 @@ namespace PolyVox
m_pRecentlyUsedChunks.clear(); m_pRecentlyUsedChunks.clear();
//Other properties we might find useful later //Other properties we might find useful later
this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth()); //this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth());
this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth()); //this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth());
this->m_fDiagonalLength = sqrtf(static_cast<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth())); //this->m_fDiagonalLength = sqrtf(static_cast<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth()));
} }
template <typename VoxelType> template <typename VoxelType>

View File

@ -118,16 +118,6 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
bool PagedVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue) bool PagedVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue)
{ {
/*if(m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ)
{
*mCurrentVoxel = tValue;
return true;
}
else
{
return false;
}*/
//Need to think what effect this has on any existing iterators. //Need to think what effect this has on any existing iterators.
POLYVOX_THROW(not_implemented, "This function cannot be used on PagedVolume samplers."); POLYVOX_THROW(not_implemented, "This function cannot be used on PagedVolume samplers.");
return false; return false;

View File

@ -57,7 +57,9 @@ namespace PolyVox
Sampler(RawVolume<VoxelType>* volume); Sampler(RawVolume<VoxelType>* volume);
~Sampler(); ~Sampler();
inline VoxelType getVoxel(void) const; inline VoxelType getVoxel(void) const;
bool isCurrentPositionValid(void) const;
void setPosition(const Vector3DInt32& v3dNewPos); void setPosition(const Vector3DInt32& v3dNewPos);
void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
@ -105,6 +107,12 @@ namespace PolyVox
//Other current position information //Other current position information
VoxelType* mCurrentVoxel; VoxelType* mCurrentVoxel;
//Whether the current position is inside the volume
//FIXME - Replace these with flags
bool m_bIsCurrentPositionValidInX;
bool m_bIsCurrentPositionValidInY;
bool m_bIsCurrentPositionValidInZ;
}; };
#endif #endif
@ -115,11 +123,31 @@ namespace PolyVox
/// Destructor /// Destructor
~RawVolume(); ~RawVolume();
/// Gets the value used for voxels which are outside the volume
VoxelType getBorderValue(void) const;
/// Gets a Region representing the extents of the Volume.
const Region& getEnclosingRegion(void) const;
/// Gets the width of the volume in voxels.
int32_t getWidth(void) const;
/// Gets the height of the volume in voxels.
int32_t getHeight(void) const;
/// Gets the depth of the volume in voxels.
int32_t getDepth(void) const;
/// Gets the length of the longest side in voxels
int32_t getLongestSideLength(void) const;
/// Gets the length of the shortest side in voxels
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 /// 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; VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
/// Gets a voxel at the position given by a 3D vector /// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos) const; VoxelType getVoxel(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 /// 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); void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at the position given by a 3D vector /// Sets the voxel at the position given by a 3D vector
@ -138,6 +166,17 @@ namespace PolyVox
private: private:
void initialise(const Region& regValidRegion); void initialise(const Region& regValidRegion);
//The size of the volume
Region m_regValidRegion;
//Some useful sizes
int32_t m_uLongestSideLength;
int32_t m_uShortestSideLength;
float m_fDiagonalLength;
//The border value
VoxelType m_tBorderValue;
//The voxel data //The voxel data
VoxelType* m_pData; VoxelType* m_pData;
}; };

View File

@ -29,7 +29,9 @@ namespace PolyVox
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> template <typename VoxelType>
RawVolume<VoxelType>::RawVolume(const Region& regValid) RawVolume<VoxelType>::RawVolume(const Region& regValid)
:BaseVolume<VoxelType>(regValid) :BaseVolume<VoxelType>()
, m_regValidRegion(regValid)
, m_tBorderValue()
{ {
this->setBorderValue(VoxelType()); this->setBorderValue(VoxelType());
@ -73,6 +75,90 @@ namespace PolyVox
POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons."); POLYVOX_THROW(not_implemented, "Volume assignment operator not implemented for performance reasons.");
} }
////////////////////////////////////////////////////////////////////////////////
/// The border value is returned whenever an attempt is made to read a voxel which
/// is outside the extents of the volume.
/// \return The value used for voxels outside of the volume
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getBorderValue(void) const
{
return m_tBorderValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \return A Region representing the extent of the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
const Region& RawVolume<VoxelType>::getEnclosingRegion(void) const
{
return m_regValidRegion;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The width of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the width is 64.
/// \sa getHeight(), getDepth()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t RawVolume<VoxelType>::getWidth(void) const
{
return m_regValidRegion.getUpperX() - m_regValidRegion.getLowerX() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The height of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the height is 64.
/// \sa getWidth(), getDepth()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t RawVolume<VoxelType>::getHeight(void) const
{
return m_regValidRegion.getUpperY() - m_regValidRegion.getLowerY() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The depth of the volume in voxels. Note that this value is inclusive, so that if the valid range is e.g. 0 to 63 then the depth is 64.
/// \sa getWidth(), getHeight()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t RawVolume<VoxelType>::getDepth(void) const
{
return m_regValidRegion.getUpperZ() - m_regValidRegion.getLowerZ() + 1;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the shortest side in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return 256.
/// \sa getLongestSideLength(), getDiagonalLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t RawVolume<VoxelType>::getShortestSideLength(void) const
{
return m_uShortestSideLength;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the longest side in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return 1024.
/// \sa getShortestSideLength(), getDiagonalLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
int32_t RawVolume<VoxelType>::getLongestSideLength(void) const
{
return m_uLongestSideLength;
}
////////////////////////////////////////////////////////////////////////////////
/// \return The length of the diagonal in voxels. For example, if a volume has
/// dimensions 256x512x1024 this function will return sqrt(256*256+512*512+1024*1024)
/// = 1173.139. This value is computed on volume creation so retrieving it is fast.
/// \sa getShortestSideLength(), getLongestSideLength()
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
float RawVolume<VoxelType>::getDiagonalLength(void) const
{
return m_fDiagonalLength;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// This version of the function is provided so that the wrap mode does not need /// 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. /// to be specified as a template parameter, as it may be confusing to some users.
@ -120,6 +206,15 @@ namespace PolyVox
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ()); return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
} }
////////////////////////////////////////////////////////////////////////////////
/// \param tBorder The value to use for voxels outside the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
void RawVolume<VoxelType>::setBorderValue(const VoxelType& tBorder)
{
m_tBorderValue = tBorder;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel /// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel /// \param uYPos the \c y position of the voxel
@ -185,6 +280,9 @@ namespace PolyVox
//Create the data //Create the data
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()]; m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];
// Clear to zeros
std::fill(m_pData, m_pData + this->getWidth() * this->getHeight()* this->getDepth(), VoxelType());
//Other properties we might find useful later //Other properties we might find useful later
this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth()); this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth());
this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth()); this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth());

View File

@ -34,6 +34,9 @@ namespace PolyVox
RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume) RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume)
:BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume) :BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume)
,mCurrentVoxel(0) ,mCurrentVoxel(0)
, m_bIsCurrentPositionValidInX(false)
, m_bIsCurrentPositionValidInY(false)
, m_bIsCurrentPositionValidInZ(false)
{ {
} }
@ -55,6 +58,12 @@ namespace PolyVox
} }
} }
template <typename VoxelType>
bool inline RawVolume<VoxelType>::Sampler::isCurrentPositionValid(void) const
{
return m_bIsCurrentPositionValidInX && m_bIsCurrentPositionValidInY && m_bIsCurrentPositionValidInZ;
}
template <typename VoxelType> template <typename VoxelType>
void RawVolume<VoxelType>::Sampler::setPosition(const Vector3DInt32& v3dNewPos) void RawVolume<VoxelType>::Sampler::setPosition(const Vector3DInt32& v3dNewPos)
{ {
@ -67,6 +76,10 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::setPosition(xPos, yPos, zPos); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::setPosition(xPos, yPos, zPos);
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(xPos);
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(yPos);
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(zPos);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid()) if(this->isCurrentPositionValid())
{ {
@ -111,6 +124,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveX(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveX();
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {
@ -131,6 +146,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveY(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveY();
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {
@ -151,6 +168,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveZ(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::movePositiveZ();
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {
@ -171,6 +190,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeX(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeX();
m_bIsCurrentPositionValidInX = mVolume->getEnclosingRegion().containsPointInX(mXPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {
@ -191,6 +212,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeY(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeY();
m_bIsCurrentPositionValidInY = mVolume->getEnclosingRegion().containsPointInY(mYPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {
@ -211,6 +234,8 @@ namespace PolyVox
// Base version updates position and validity flags. // Base version updates position and validity flags.
BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeZ(); BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >::moveNegativeZ();
m_bIsCurrentPositionValidInZ = mVolume->getEnclosingRegion().containsPointInZ(mZPosInVolume);
// Then we update the voxel pointer // Then we update the voxel pointer
if(this->isCurrentPositionValid() && bIsOldPositionValid ) if(this->isCurrentPositionValid() && bIsOldPositionValid )
{ {

View File

@ -62,8 +62,8 @@ public:
/// Constructor for creating a fixed size volume. /// Constructor for creating a fixed size volume.
VolumeSubclass(const Region& regValid) VolumeSubclass(const Region& regValid)
:BaseVolume<VoxelType>(regValid) :BaseVolume<VoxelType>()
, mVolumeData(this->getWidth(), this->getHeight(), this->getDepth()) , mVolumeData(regValid.getWidthInVoxels(), regValid.getHeightInVoxels(), regValid.getDepthInVoxels())
{ {
//mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth())); //mVolumeData.resize(ArraySizes(this->getWidth())(this->getHeight())(this->getDepth()));
} }
@ -73,7 +73,7 @@ public:
/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates /// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates
VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const VoxelType getVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{ {
if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos)) if ((uXPos < mVolumeData.getDimension(0)) && (uYPos < mVolumeData.getDimension(1)) && (uZPos < mVolumeData.getDimension(2)))
{ {
return mVolumeData(uXPos, uYPos, uZPos); return mVolumeData(uXPos, uYPos, uZPos);
} }
@ -94,7 +94,7 @@ public:
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates /// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
bool setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) bool setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{ {
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos))) if ((uXPos < mVolumeData.getDimension(0)) && (uYPos < mVolumeData.getDimension(1)) && (uZPos < mVolumeData.getDimension(2)))
{ {
mVolumeData(uXPos, uYPos, uZPos) = tValue; mVolumeData(uXPos, uYPos, uZPos) = tValue;
return true; return true;
@ -119,13 +119,14 @@ private:
void TestVolumeSubclass::testExtractSurface() void TestVolumeSubclass::testExtractSurface()
{ {
VolumeSubclass<Material8> volumeSubclass(Region(0,0,0,16,16,16)); Region region(0, 0, 0, 16, 16, 16);
VolumeSubclass<Material8> volumeSubclass(region);
for(int32_t z = 0; z < volumeSubclass.getDepth() / 2; z++) for (int32_t z = 0; z < region.getDepthInVoxels() / 2; z++)
{ {
for(int32_t y = 0; y < volumeSubclass.getHeight(); y++) for (int32_t y = 0; y < region.getHeightInVoxels(); y++)
{ {
for(int32_t x = 0; x < volumeSubclass.getWidth(); x++) for (int32_t x = 0; x < region.getWidthInVoxels(); x++)
{ {
Material8 mat(1); Material8 mat(1);
volumeSubclass.setVoxel(Vector3DInt32(x,y,z),mat); volumeSubclass.setVoxel(Vector3DInt32(x,y,z),mat);
@ -133,7 +134,7 @@ void TestVolumeSubclass::testExtractSurface()
} }
} }
auto result = extractCubicMesh(&volumeSubclass, volumeSubclass.getEnclosingRegion()); auto result = extractCubicMesh(&volumeSubclass, region);
QCOMPARE(result.getNoOfVertices(), static_cast<uint32_t>(8)); QCOMPARE(result.getNoOfVertices(), static_cast<uint32_t>(8));
} }