33 template <
typename VoxelType>
38 initialise(regValid,uBlockSideLength);
48 template <
typename VoxelType>
57 template <
typename VoxelType>
70 template <
typename VoxelType>
82 template <
typename VoxelType>
87 const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
88 const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
89 const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
91 const uint16_t xOffset =
static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
92 const uint16_t yOffset =
static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
93 const uint16_t zOffset =
static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
97 return pUncompressedBlock->
getVoxelAt(xOffset,yOffset,zOffset);
104 template <
typename VoxelType>
107 return getVoxel(v3dPos.
getX(), v3dPos.
getY(), v3dPos.
getZ());
116 template <
typename VoxelType>
119 if(this->m_regValidRegion.containsPoint(
Vector3DInt32(uXPos, uYPos, uZPos)))
121 const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
122 const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
123 const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
125 const uint16_t xOffset =
static_cast<uint16_t>(uXPos - (blockX << m_uBlockSideLengthPower));
126 const uint16_t yOffset =
static_cast<uint16_t>(uYPos - (blockY << m_uBlockSideLengthPower));
127 const uint16_t zOffset =
static_cast<uint16_t>(uZPos - (blockZ << m_uBlockSideLengthPower));
131 return pUncompressedBlock->
getVoxelAt(xOffset,yOffset,zOffset);
135 return this->getBorderValue();
143 template <
typename VoxelType>
146 return getVoxelAt(v3dPos.
getX(), v3dPos.
getY(), v3dPos.
getZ());
155 template <
typename VoxelType>
163 uXPos = (std::max)(uXPos, this->m_regValidRegion.getLowerX());
164 uYPos = (std::max)(uYPos, this->m_regValidRegion.getLowerY());
165 uZPos = (std::max)(uZPos, this->m_regValidRegion.getLowerZ());
166 uXPos = (std::min)(uXPos, this->m_regValidRegion.getUpperX());
167 uYPos = (std::min)(uYPos, this->m_regValidRegion.getUpperY());
168 uZPos = (std::min)(uZPos, this->m_regValidRegion.getUpperZ());
171 return getVoxel(uXPos, uYPos, uZPos);
176 if(this->m_regValidRegion.containsPoint(uXPos, uYPos, uZPos))
178 return getVoxel(uXPos, uYPos, uZPos);
199 template <
typename VoxelType>
202 return getVoxelWithWrapping(v3dPos.
getX(), v3dPos.
getY(), v3dPos.
getZ(), eWrapMode, tBorder);
212 template <
typename VoxelType>
217 const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
218 const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
219 const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
221 const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
222 const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
223 const uint16_t zOffset = uZPos - (blockZ << m_uBlockSideLengthPower);
227 pUncompressedBlock->setVoxelAt(xOffset,yOffset,zOffset, tValue);
238 template <
typename VoxelType>
241 return setVoxelAt(v3dPos.
getX(), v3dPos.
getY(), v3dPos.
getZ(), tValue);
247 template <
typename VoxelType>
251 POLYVOX_ASSERT(uBlockSideLength >= 8,
"Block side length should be at least 8");
252 POLYVOX_ASSERT(uBlockSideLength <= 256,
"Block side length should not be more than 256");
256 if(uBlockSideLength < 8)
258 POLYVOX_THROW(std::invalid_argument,
"Block side length should be at least 8");
260 if(uBlockSideLength > 256)
262 POLYVOX_THROW(std::invalid_argument,
"Block side length should not be more than 256");
266 POLYVOX_THROW(std::invalid_argument,
"Block side length must be a power of two.");
269 this->m_regValidRegion = regValidRegion;
272 m_uBlockSideLength = uBlockSideLength;
273 m_uBlockSideLengthPower =
logBase2(m_uBlockSideLength);
274 m_uNoOfVoxelsPerBlock = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength;
276 m_regValidRegionInBlocks.setLowerX(this->m_regValidRegion.getLowerX() >> m_uBlockSideLengthPower);
277 m_regValidRegionInBlocks.setLowerY(this->m_regValidRegion.getLowerY() >> m_uBlockSideLengthPower);
278 m_regValidRegionInBlocks.setLowerZ(this->m_regValidRegion.getLowerZ() >> m_uBlockSideLengthPower);
279 m_regValidRegionInBlocks.setUpperX(this->m_regValidRegion.getUpperX() >> m_uBlockSideLengthPower);
280 m_regValidRegionInBlocks.setUpperY(this->m_regValidRegion.getUpperY() >> m_uBlockSideLengthPower);
281 m_regValidRegionInBlocks.setUpperZ(this->m_regValidRegion.getUpperZ() >> m_uBlockSideLengthPower);
284 m_uWidthInBlocks = m_regValidRegionInBlocks.getUpperX() - m_regValidRegionInBlocks.getLowerX() + 1;
285 m_uHeightInBlocks = m_regValidRegionInBlocks.getUpperY() - m_regValidRegionInBlocks.getLowerY() + 1;
286 m_uDepthInBlocks = m_regValidRegionInBlocks.getUpperZ() - m_regValidRegionInBlocks.getLowerZ() + 1;
287 m_uNoOfBlocksInVolume = m_uWidthInBlocks * m_uHeightInBlocks * m_uDepthInBlocks;
290 m_pBlocks =
new Block[m_uNoOfBlocksInVolume];
291 for(
uint32_t i = 0; i < m_uNoOfBlocksInVolume; ++i)
293 m_pBlocks[i].initialise(m_uBlockSideLength);
297 this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth());
298 this->m_uShortestSideLength = (std::min)((std::min)(this->getWidth(),this->getHeight()),this->getDepth());
299 this->m_fDiagonalLength = sqrtf(static_cast<float>(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth()));
302 template <
typename VoxelType>
307 uBlockX -= m_regValidRegionInBlocks.getLowerX();
308 uBlockY -= m_regValidRegionInBlocks.getLowerY();
309 uBlockZ -= m_regValidRegionInBlocks.getLowerZ();
311 POLYVOX_ASSERT(uBlockX >= 0,
"Block coordinate must not be negative.");
312 POLYVOX_ASSERT(uBlockY >= 0,
"Block coordinate must not be negative.");
313 POLYVOX_ASSERT(uBlockZ >= 0,
"Block coordinate must not be negative.");
318 uBlockY * m_uWidthInBlocks +
319 uBlockZ * m_uWidthInBlocks * m_uHeightInBlocks;
322 return &(m_pBlocks[uBlockIndex]);
330 template <
typename VoxelType>
338 uSizeInBytes += uSizeOfBlockInBytes * (m_uNoOfBlocksInVolume);