diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h
index d188f8ac..30c34584 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h
+++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.h
@@ -172,6 +172,10 @@ namespace PolyVox
/// Sets the value used for voxels which are outside the volume
void setBorderValue(const VoxelType& tBorder);
/// Sets the voxel at the position given by x,y,z coordinates
+ void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by a 3D vector
+ void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by x,y,z 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);
diff --git a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl
index dfe0fbb7..87dfc1fe 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl
+++ b/library/PolyVoxCore/include/PolyVoxCore/BaseVolume.inl
@@ -234,6 +234,32 @@ 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void BaseVolume::setVoxel(int32_t /*uXPos*/, int32_t /*uYPos*/, int32_t /*uZPos*/, VoxelType /*tValue*/, BoundsCheck /*eBoundsCheck*/)
+ {
+ POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
+ return false;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ /// \param v3dPos the 3D position of the voxel
+ /// \param tValue the value to which the voxel will be set
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void BaseVolume::setVoxel(const Vector3DInt32& /*v3dPos*/, VoxelType /*tValue*/, BoundsCheck /*eBoundsCheck*/)
+ {
+ POLYVOX_THROW(not_implemented, "You should never call the base class version of this function.");
+ return false;
+ }
+
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel
diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h
index 9d4acba4..0ce3bfc7 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h
+++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h
@@ -283,6 +283,10 @@ namespace PolyVox
/// 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 x,y,z coordinates
+ void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by a 3D vector
+ void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by x,y,z 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);
diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl
index 1b5bdb15..9f2c4119 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl
+++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl
@@ -280,6 +280,50 @@ 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void LargeVolume::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ // If bounds checking is enabled then we validate the
+ // bounds, and throw an exception if they are violated.
+ if(eBoundsCheck == BoundsChecks::Full)
+ {
+ if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
+ {
+ POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
+ }
+ }
+
+ 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(uXPos - (blockX << m_uBlockSideLengthPower));
+ const uint16_t yOffset = static_cast(uYPos - (blockY << m_uBlockSideLengthPower));
+ const uint16_t zOffset = static_cast(uZPos - (blockZ << m_uBlockSideLengthPower));
+
+ Block* 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void LargeVolume::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eBoundsCheck);
+ }
+
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel
diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h
index 165b6ba4..95a770b9 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h
+++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.h
@@ -128,6 +128,10 @@ namespace PolyVox
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const;
+ /// Sets the voxel at the position given by x,y,z coordinates
+ void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by a 3D vector
+ void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
/// Sets the voxel at the position given by x,y,z 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
diff --git a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl
index f09e76de..b7029dcf 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl
+++ b/library/PolyVoxCore/include/PolyVoxCore/RawVolume.inl
@@ -210,6 +210,50 @@ namespace PolyVox
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void RawVolume::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ // If bounds checking is enabled then we validate the
+ // bounds, and throw an exception if they are violated.
+ if(eBoundsCheck == BoundsChecks::Full)
+ {
+ if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
+ {
+ POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
+ }
+ }
+
+ 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
+ /// \param tValue the value to which the voxel will be set
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void RawVolume::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eBoundsCheck);
+ }
+
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel
diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h
index 0abd3b30..2bd0a366 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h
+++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.h
@@ -167,6 +167,10 @@ namespace PolyVox
/// Gets a voxel at the position given by a 3D vector
VoxelType getVoxel(const Vector3DInt32& v3dPos, WrapMode eWrapMode, VoxelType tBorder = VoxelType()) const;
+ /// Sets the voxel at the position given by x,y,z coordinates
+ void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
+ /// Sets the voxel at the position given by a 3D vector
+ void setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck = BoundsChecks::Full);
/// Sets the voxel at the position given by x,y,z 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
diff --git a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl
index 5a9c8f00..7403dc74 100644
--- a/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl
+++ b/library/PolyVoxCore/include/PolyVoxCore/SimpleVolume.inl
@@ -210,6 +210,50 @@ namespace PolyVox
return getVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), eWrapMode, 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void SimpleVolume::setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ // If bounds checking is enabled then we validate the
+ // bounds, and throw an exception if they are violated.
+ if(eBoundsCheck == BoundsChecks::Full)
+ {
+ if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)) == false)
+ {
+ POLYVOX_THROW(std::out_of_range, "Position is outside valid region");
+ }
+ }
+
+ 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::Block* 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
+ /// \return whether the requested position is inside the volume
+ ////////////////////////////////////////////////////////////////////////////////
+ template
+ void SimpleVolume::setVoxel(const Vector3DInt32& v3dPos, VoxelType tValue, BoundsCheck eBoundsCheck)
+ {
+ setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue, eBoundsCheck);
+ }
+
////////////////////////////////////////////////////////////////////////////////
/// \param uXPos the \c x position of the voxel
/// \param uYPos the \c y position of the voxel