diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index c6cb68c3..7534e8bb 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -614,7 +614,12 @@ namespace PolyVox Vector3DInt32 v3dBlockPos = itUncompressedBlock->first; CompressedBlock* pCompressedBlock = getCompressedBlock(v3dBlockPos.getX(), v3dBlockPos.getY(), v3dBlockPos.getZ()); - void* pSrcData = reinterpret_cast(pUncompressedBlock->m_tData); + m_pBlockCompressor->compress(pUncompressedBlock, pCompressedBlock); + + // The compressed data has been updated, so the uncompressed data is no longer modified with respect to it. + pUncompressedBlock->m_bDataModified = false; + + /*void* pSrcData = reinterpret_cast(pUncompressedBlock->m_tData); uint32_t uSrcLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); uint8_t tempBuffer[10000]; @@ -667,7 +672,7 @@ namespace PolyVox } delete[] buffer; - } + }*/ } delete itUncompressedBlock->second; @@ -712,43 +717,6 @@ namespace PolyVox return pBlock; } - - - - - - /*typename CompressedBlockMap::iterator itBlock = m_pBlocks.find(v3dBlockPos); - // check whether the block is already loaded - if(itBlock == m_pBlocks.end()) - { - //The block is not in the map, so we will have to create a new block and add it. - CompressedBlock* newBlock = new CompressedBlock; - newBlock->m_uBlockLastAccessed = ++m_uTimestamper; - itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first; - - // Now use the pager to fill the block with it's initial data. - 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, 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(); - } - - //Get the block and mark that we accessed it - CompressedBlock* block = itBlock->second; - block->m_uBlockLastAccessed = ++m_uTimestamper; - //m_v3dLastAccessedBlockPos = v3dBlockPos; - - return block;*/ } template @@ -797,17 +765,6 @@ namespace PolyVox // FIXME - multiple getCompressedBlock() calls (including the one above) CompressedBlock* pBlock = getCompressedBlock(uBlockX, uBlockY, uBlockZ); - /*const void* pSrcData = reinterpret_cast(pBlock->getData()); - void* pDstData = reinterpret_cast(pUncompressedBlock->m_tData); - uint32_t uSrcLength = pBlock->getDataSizeInBytes(); - uint32_t uDstLength = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); - - //MinizCompressor compressor; - //RLECompressor compressor; - uint32_t uUncompressedLength = m_pCompressor->decompress(pSrcData, uSrcLength, pDstData, uDstLength); - - POLYVOX_ASSERT(uUncompressedLength == m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType), "Destination length has changed.");*/ - m_pBlockCompressor->decompress(pBlock, pUncompressedBlock); } diff --git a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl index 69f6b2e9..67501ea9 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.inl @@ -38,6 +38,54 @@ namespace PolyVox template void MinizBlockCompressor::compress(UncompressedBlock* pSrcBlock, CompressedBlock* pDstBlock) { + void* pSrcData = reinterpret_cast(pSrcBlock->getData()); + uint32_t uSrcLength = pSrcBlock->getDataSizeInBytes(); + + uint8_t tempBuffer[10000]; + uint8_t* pDstData = reinterpret_cast( tempBuffer ); + uint32_t uDstLength = 10000; + + uint32_t uCompressedLength = 0; + + try + { + // Perform the compression + uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength); + + // Copy the resulting compressed data into the compressed block + pDstBlock->setData(pDstData, uDstLength); + } + catch(std::exception&) + { + // It is possible for the compression to fail. A common cause for this would be if the destination + // buffer is not big enough. So now we try again using a buffer that is definitely big enough. + // Note that ideally we will choose our earlier buffer size so that this almost never happens. + logWarning() << "The compressor failed to compress the block, probabaly due to the buffer being too small."; + logWarning() << "The compression will be tried again with a larger buffer"; + uint32_t uMaxCompressedSize = m_pCompressor->getMaxCompressedSize(uSrcLength); + uint8_t* buffer = new uint8_t[ uMaxCompressedSize ]; + + pDstData = reinterpret_cast( buffer ); + uDstLength = uMaxCompressedSize; + + try + { + // Perform the compression + uCompressedLength = m_pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength); + + // Copy the resulting compressed data into the compressed block + pDstBlock->setData(pDstData, uDstLength); + } + catch(std::exception&) + { + // At this point it didn't work even with a bigger buffer. + // Not much more we can do so just rethrow the exception. + delete[] buffer; + POLYVOX_THROW(std::runtime_error, "Failed to compress block data"); + } + + delete[] buffer; + } } template