Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace PolyVox
00025 {
00029 template <typename VoxelType>
00030 SimpleVolume<VoxelType>::SimpleVolume
00031 (
00032 int32_t dont_use_this_constructor_1, int32_t dont_use_this_constructor_2, int32_t dont_use_this_constructor_3
00033 )
00034 {
00035
00036
00037
00038
00039
00040
00041
00042
00043 assert(false);
00044 abort();
00045 }
00046
00055 template <typename VoxelType>
00056 SimpleVolume<VoxelType>::SimpleVolume
00057 (
00058 const Region& regValid,
00059 uint16_t uBlockSideLength
00060 )
00061 :BaseVolume<VoxelType>(regValid)
00062 {
00063
00064 resize(regValid,uBlockSideLength);
00065 }
00066
00070 template <typename VoxelType>
00071 SimpleVolume<VoxelType>::~SimpleVolume()
00072 {
00073 delete[] m_pBlocks;
00074 delete[] m_pUncompressedBorderData;
00075 }
00076
00082 template <typename VoxelType>
00083 VoxelType SimpleVolume<VoxelType>::getBorderValue(void) const
00084 {
00085 return *m_pUncompressedBorderData;
00086 }
00087
00094 template <typename VoxelType>
00095 VoxelType SimpleVolume<VoxelType>::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
00096 {
00097 if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
00098 {
00099 const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
00100 const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
00101 const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
00102
00103 const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
00104 const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
00105 const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
00106
00107 typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
00108
00109 return pUncompressedBlock->getVoxelAt(xOffset,yOffset,zOffset);
00110 }
00111 else
00112 {
00113 return getBorderValue();
00114 }
00115 }
00116
00121 template <typename VoxelType>
00122 VoxelType SimpleVolume<VoxelType>::getVoxelAt(const Vector3DInt32& v3dPos) const
00123 {
00124 return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
00125 }
00126
00130 template <typename VoxelType>
00131 void SimpleVolume<VoxelType>::setBorderValue(const VoxelType& tBorder)
00132 {
00133
00134
00135 std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uNoOfVoxelsPerBlock, tBorder);
00136 }
00137
00145 template <typename VoxelType>
00146 bool SimpleVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
00147 {
00148 assert(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
00149
00150 const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
00151 const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
00152 const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
00153
00154 const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
00155 const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
00156 const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
00157
00158 typename SimpleVolume<VoxelType>::Block* pUncompressedBlock = getUncompressedBlock(blockX, blockY, blockZ);
00159
00160 pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
00161
00162
00163 return true;
00164 }
00165
00171 template <typename VoxelType>
00172 bool SimpleVolume<VoxelType>::setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue)
00173 {
00174 return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
00175 }
00176
00180 template <typename VoxelType>
00181 void SimpleVolume<VoxelType>::resize(const Region& regValidRegion, uint16_t uBlockSideLength)
00182 {
00183
00184 assert(uBlockSideLength > 0);
00185
00186
00187 if(uBlockSideLength == 0)
00188 {
00189 throw std::invalid_argument("Block side length cannot be zero.");
00190 }
00191 if(!isPowerOf2(uBlockSideLength))
00192 {
00193 throw std::invalid_argument("Block side length must be a power of two.");
00194 }
00195
00196 m_uBlockSideLength = uBlockSideLength;
00197 m_uNoOfVoxelsPerBlock = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength;
00198 m_pUncompressedBorderData = 0;
00199
00200 this->m_regValidRegion = regValidRegion;
00201
00202 m_regValidRegionInBlocks.setLowerCorner(this->m_regValidRegion.getLowerCorner() / static_cast<int32_t>(uBlockSideLength));
00203 m_regValidRegionInBlocks.setUpperCorner(this->m_regValidRegion.getUpperCorner() / static_cast<int32_t>(uBlockSideLength));
00204
00205
00206 m_uBlockSideLength = uBlockSideLength;
00207 m_uBlockSideLengthPower = logBase2(m_uBlockSideLength);
00208
00209
00210 m_uWidthInBlocks = m_regValidRegionInBlocks.getUpperCorner().getX() - m_regValidRegionInBlocks.getLowerCorner().getX() + 1;
00211 m_uHeightInBlocks = m_regValidRegionInBlocks.getUpperCorner().getY() - m_regValidRegionInBlocks.getLowerCorner().getY() + 1;
00212 m_uDepthInBlocks = m_regValidRegionInBlocks.getUpperCorner().getZ() - m_regValidRegionInBlocks.getLowerCorner().getZ() + 1;
00213 m_uNoOfBlocksInVolume = m_uWidthInBlocks * m_uHeightInBlocks * m_uDepthInBlocks;
00214
00215
00216 m_pBlocks = new Block[m_uNoOfBlocksInVolume];
00217 for(uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
00218 {
00219 m_pBlocks[i].initialise(m_uBlockSideLength);
00220 }
00221
00222
00223 m_pUncompressedBorderData = new VoxelType[m_uNoOfVoxelsPerBlock];
00224 std::fill(m_pUncompressedBorderData, m_pUncompressedBorderData + m_uNoOfVoxelsPerBlock, VoxelType());
00225
00226
00227 this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth());
00228 this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth());
00229 this->m_fDiagonalLength = sqrtf(static_cast<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth()));
00230 }
00231
00232 template <typename VoxelType>
00233 typename SimpleVolume<VoxelType>::Block* SimpleVolume<VoxelType>::getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const
00234 {
00235
00236
00237 uBlockX -= m_regValidRegionInBlocks.getLowerCorner().getX();
00238 uBlockY -= m_regValidRegionInBlocks.getLowerCorner().getY();
00239 uBlockZ -= m_regValidRegionInBlocks.getLowerCorner().getZ();
00240
00241
00242 uint32_t uBlockIndex =
00243 uBlockX +
00244 uBlockY * m_uWidthInBlocks +
00245 uBlockZ * m_uWidthInBlocks * m_uHeightInBlocks;
00246
00247
00248 return &(m_pBlocks[uBlockIndex]);
00249 }
00250
00254 template <typename VoxelType>
00255 uint32_t SimpleVolume<VoxelType>::calculateSizeInBytes(void)
00256 {
00257 uint32_t uSizeInBytes = sizeof(SimpleVolume);
00258
00259 uint32_t uSizeOfBlockInBytes = m_uNoOfVoxelsPerBlock * sizeof(VoxelType);
00260
00261
00262 uSizeInBytes += uSizeOfBlockInBytes * (m_uNoOfBlocksInVolume + 1);
00263
00264 return uSizeInBytes;
00265 }
00266
00267 }
00268