diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index f79df326..11951b0d 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -48,6 +48,7 @@ SET(CORE_INC_FILES include/PolyVoxCore/BaseVolume.h include/PolyVoxCore/BaseVolume.inl include/PolyVoxCore/BaseVolumeSampler.inl + include/PolyVoxCore/BlockCompressor.h include/PolyVoxCore/Compressor.h include/PolyVoxCore/CubicSurfaceExtractor.h include/PolyVoxCore/CubicSurfaceExtractor.inl diff --git a/library/PolyVoxCore/include/PolyVoxCore/BlockCompressor.h b/library/PolyVoxCore/include/PolyVoxCore/BlockCompressor.h new file mode 100644 index 00000000..21338de7 --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/BlockCompressor.h @@ -0,0 +1,46 @@ +/******************************************************************************* +Copyright (c) 2005-2013 David Williams and Matthew Williams + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*******************************************************************************/ + +#ifndef __PolyVox_BlockCompressor_H__ +#define __PolyVox_BlockCompressor_H__ + +#include "PolyVoxCore/Impl/Block.h" + +namespace PolyVox +{ + /** + * Provides an interface for performing compression of blocks. + */ + template + class BlockCompressor + { + public: + BlockCompressor() {}; + virtual ~BlockCompressor() {}; + + virtual void compress(UncompressedBlock* pSrcBlock, CompressedBlock* pDstBlock) = 0; + virtual void decompress(CompressedBlock* pSrcBlock, UncompressedBlock* pDstBlock) = 0; + }; +} + +#endif //__PolyVox_BlockCompressor_H__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index e5095c3f..986bcf2b 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -25,9 +25,8 @@ freely, subject to the following restrictions: #define __PolyVox_LargeVolume_H__ #include "PolyVoxCore/BaseVolume.h" -#include "Impl/Block.h" -#include "PolyVoxCore/Compressor.h" -#include "PolyVoxCore/MinizBlockCompressor.h" //Shouldn't include the implementation here. +#include "PolyVoxCore/Impl/Block.h" +#include "PolyVoxCore/BlockCompressor.h" #include "PolyVoxCore/Pager.h" #include "PolyVoxCore/Region.h" #include "PolyVoxCore/Vector.h" @@ -240,7 +239,7 @@ namespace PolyVox LargeVolume ( const Region& regValid, - Compressor* pCompressor, + BlockCompressor* pBlockCompressor, Pager* pPager , uint16_t uBlockSideLength = 32 ); @@ -357,12 +356,11 @@ namespace PolyVox uint8_t m_uBlockSideLengthPower; // The compressor used by the Blocks to compress their data if required. - Compressor* m_pCompressor; - MinizBlockCompressor* m_pBlockCompressor; + BlockCompressor* m_pBlockCompressor; Pager* m_pPager; // Compressed data for an empty block (sometimes needed for initialisation). - CompressedBlock* m_pCompressedEmptyBlock; + //CompressedBlock* m_pCompressedEmptyBlock; // Whether we created the compressor or whether it was provided // by the user. This controls whether we delete it on destruction. diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index 7534e8bb..7be743fd 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -23,7 +23,7 @@ freely, subject to the following restrictions: #include "PolyVoxCore/Impl/ErrorHandling.h" -#include "PolyVoxCore/MinizCompressor.h" +#include "PolyVoxCore/MinizBlockCompressor.h" // For creating a default compressor when none is provided. #include @@ -45,7 +45,7 @@ namespace PolyVox { m_uBlockSideLength = uBlockSideLength; - m_pCompressor = new MinizCompressor(); + m_pBlockCompressor = new MinizBlockCompressor(); m_bIsOurCompressor = true; m_pPager = 0; @@ -56,7 +56,7 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// /// This constructor creates a volume with a fixed size which is specified as a parameter. By default this constructor will not enable paging but you can override this if desired. If you do wish to enable paging then you are required to provide the call back function (see the other LargeVolume constructor). /// \param regValid Specifies the minimum and maximum valid voxel positions. - /// \param pCompressor An implementation of the Compressor interface which is used to compress blocks in memory. + /// \param pBlockCompressor An implementation of the Compressor interface which is used to compress blocks in memory. /// \param dataRequiredHandler The callback function which will be called when PolyVox tries to use data which is not currently in momory. /// \param dataOverflowHandler The callback function which will be called when PolyVox has too much data and needs to remove some from memory. /// \param bPagingEnabled Controls whether or not paging is enabled for this LargeVolume. @@ -66,16 +66,15 @@ namespace PolyVox LargeVolume::LargeVolume ( const Region& regValid, - Compressor* pCompressor, + BlockCompressor* pBlockCompressor, Pager* pPager, uint16_t uBlockSideLength ) :BaseVolume(regValid) { - m_uBlockSideLength = uBlockSideLength; - m_pCompressor = pCompressor; + m_pBlockCompressor = pBlockCompressor; m_bIsOurCompressor = false; m_pPager = pPager; @@ -107,10 +106,10 @@ namespace PolyVox // Only delete the compressor if it was created by us (in the constructor), not by the user. if(m_bIsOurCompressor) { - delete m_pCompressor; + delete m_pBlockCompressor; } - delete m_pCompressedEmptyBlock; + //delete m_pCompressedEmptyBlock; } //////////////////////////////////////////////////////////////////////////////// @@ -511,7 +510,7 @@ namespace PolyVox POLYVOX_THROW(std::invalid_argument, "Block side length must be a power of two."); } - if(!m_pCompressor) + if(!m_pBlockCompressor) { POLYVOX_THROW(std::invalid_argument, "You must provide a valid compressor for the LargeVolume to use."); } @@ -544,23 +543,6 @@ 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; - - m_pBlockCompressor = new MinizBlockCompressor; } template @@ -618,61 +600,6 @@ namespace PolyVox // 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]; - 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 - pCompressedBlock->setData(pDstData, uDstLength); - - // The compressed data has been updated, so the uncompressed data is no longer modified with respect to it. - pUncompressedBlock->m_bDataModified = false; - } - 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 - pCompressedBlock->setData(pDstData, uDstLength); - - // The compressed data has been updated, so the uncompressed data is no longer modified with respect to it. - pUncompressedBlock->m_bDataModified = false; - } - 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; - }*/ } delete itUncompressedBlock->second; diff --git a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h index b6053fbc..e4b57cf6 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MinizBlockCompressor.h @@ -24,7 +24,7 @@ freely, subject to the following restrictions: #ifndef __PolyVox_MinizBlockCompressor_H__ #define __PolyVox_MinizBlockCompressor_H__ -#include "PolyVoxCore/Impl/Block.h" +#include "PolyVoxCore/BlockCompressor.h" #include "PolyVoxCore/MinizCompressor.h" @@ -34,7 +34,7 @@ namespace PolyVox * Provides an interface for performing paging of data. */ template - class MinizBlockCompressor + class MinizBlockCompressor : public BlockCompressor { public: MinizBlockCompressor(); diff --git a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h index 05092ab1..2eef3077 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -60,6 +60,11 @@ namespace PolyVox typedef Array<3,int32_t> Array3DInt32; typedef Array<3,uint32_t> Array3DUint32; + //////////////////////////////////////////////////////////////////////////////// + // BlockCompressor + //////////////////////////////////////////////////////////////////////////////// + template class BlockCompressor; + //////////////////////////////////////////////////////////////////////////////// // Compressor //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/testvolume.cpp b/tests/testvolume.cpp index 77ad1063..d15e1fcc 100644 --- a/tests/testvolume.cpp +++ b/tests/testvolume.cpp @@ -25,7 +25,7 @@ freely, subject to the following restrictions: #include "PolyVoxCore/FilePager.h" #include "PolyVoxCore/LargeVolume.h" -#include "PolyVoxCore/MinizCompressor.h" +#include "PolyVoxCore/MinizBlockCompressor.h" #include "PolyVoxCore/RawVolume.h" #include "PolyVoxCore/RLECompressor.h" #include "PolyVoxCore/SimpleVolume.h" @@ -273,13 +273,13 @@ TestVolume::TestVolume() Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size //m_pCompressor = new RLECompressor; - m_pCompressor = new MinizCompressor; + m_pBlockCompressor = new MinizBlockCompressor; m_pFilePager = new FilePager("./"); //Create the volumes m_pRawVolume = new RawVolume(region); m_pSimpleVolume = new SimpleVolume(region); - m_pLargeVolume = new LargeVolume(region, m_pCompressor, m_pFilePager, 32); + m_pLargeVolume = new LargeVolume(region, m_pBlockCompressor, m_pFilePager, 32); m_pLargeVolume->setMaxNumberOfBlocksInMemory(32); m_pLargeVolume->setMaxNumberOfUncompressedBlocks(16); @@ -307,7 +307,7 @@ TestVolume::~TestVolume() delete m_pLargeVolume; delete m_pFilePager; - delete m_pCompressor; + delete m_pBlockCompressor; } /* diff --git a/tests/testvolume.h b/tests/testvolume.h index 8a3e46d7..9db5f7a0 100644 --- a/tests/testvolume.h +++ b/tests/testvolume.h @@ -65,7 +65,7 @@ private slots: void testLargeVolumeSamplersWithExternalBackwards(); private: - PolyVox::Compressor* m_pCompressor; + PolyVox::BlockCompressor* m_pBlockCompressor; PolyVox::FilePager* m_pFilePager; PolyVox::RawVolume* m_pRawVolume;