diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index e1786609..9f409571 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -359,6 +359,9 @@ namespace PolyVox Compressor* m_pCompressor; Pager* m_pPager; + // Compressed data for an empty block (sometimes needed for initialisation). + CompressedBlock* m_pCompressedEmptyBlock; + // Whether we created the compressor or whether it was provided // by the user. This controls whether we delete it on destruction. bool m_bIsOurCompressor; diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index e82bfc0f..10069d49 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -109,6 +109,8 @@ namespace PolyVox { delete m_pCompressor; } + + delete m_pCompressedEmptyBlock; } //////////////////////////////////////////////////////////////////////////////// @@ -542,6 +544,21 @@ namespace PolyVox 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_fDiagonalLength = sqrtf(static_cast(this->getWidth() * this->getWidth() + this->getHeight() * this->getHeight() + this->getDepth() * this->getDepth())); + + // This is used for initialising empty blocks. + // FIXME - Should probably build an UncompressedBlock and then call some 'fill()' method. Ideally we should set voxels to an 'empty' (default?) value rather than zeros. + VoxelType* pZeros = new VoxelType[m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength]; + uint32_t uSrcLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); + memset(pZeros, 0, uSrcLength); + uint32_t uDstLength = 100000; + uint8_t* pCompressedZeros = new uint8_t[uDstLength]; //Should be plenty as zeros compress down very small. + uint32_t uCompressedSize = m_pCompressor->compress(reinterpret_cast(pZeros), uSrcLength, reinterpret_cast(pCompressedZeros), uDstLength); + + m_pCompressedEmptyBlock = new CompressedBlock; + m_pCompressedEmptyBlock->setData(pCompressedZeros, uCompressedSize); + + delete[] pZeros; + delete[] pCompressedZeros; } template @@ -664,7 +681,14 @@ 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); - m_pPager->pageIn(reg, itBlock->second); + m_pPager->pageIn(reg, newBlock); + + // The pager may not actually have given us any data (perhaps there wasn't any) so in that case we need to create some ourselves. + if(newBlock->m_bDataModified == false) + { + // Internally this performs a memcpy() of the data. + newBlock->setData(m_pCompressedEmptyBlock->getData(), m_pCompressedEmptyBlock->getDataSizeInBytes()); + } // Paging in this new block may mean we are now using too much memory. If necessary, flush some old blocks. flushOldestExcessiveBlocks();