• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

PolyVoxCore/include/PolyVoxCore/LargeVolume.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 Copyright (c) 2005-2009 David Williams
00003 
00004 This software is provided 'as-is', without any express or implied
00005 warranty. In no event will the authors be held liable for any damages
00006 arising from the use of this software.
00007 
00008 Permission is granted to anyone to use this software for any purpose,
00009 including commercial applications, and to alter it and redistribute it
00010 freely, subject to the following restrictions:
00011 
00012     1. The origin of this software must not be misrepresented; you must not
00013     claim that you wrote the original software. If you use this software
00014     in a product, an acknowledgment in the product documentation would be
00015     appreciated but is not required.
00016 
00017     2. Altered source versions must be plainly marked as such, and must not be
00018     misrepresented as being the original software.
00019 
00020     3. This notice may not be removed or altered from any source
00021     distribution.   
00022 *******************************************************************************/
00023 
00024 #ifndef __PolyVox_LargeVolume_H__
00025 #define __PolyVox_LargeVolume_H__
00026 
00027 #include "PolyVoxCore/BaseVolume.h"
00028 #include "PolyVoxImpl/Block.h"
00029 #include "PolyVoxCore/Log.h"
00030 #include "PolyVoxCore/Region.h"
00031 #include "PolyVoxCore/Vector.h"
00032 
00033 #include <limits>
00034 #include <cassert>
00035 #include <cstdlib> //For abort()
00036 #include <cstring> //For memcpy
00037 #include <list>
00038 #include <map>
00039 #include <memory>
00040 #include <stdexcept> //For invalid_argument
00041 #include <vector>
00042 
00043 namespace PolyVox
00044 {
00149 
00150     template <typename VoxelType> class ConstVolumeProxy;
00151 
00152     template <typename VoxelType>
00153     class LargeVolume : public BaseVolume<VoxelType>
00154     {
00155     public:
00156         //There seems to be some descrepency between Visual Studio and GCC about how the following class should be declared.
00157         //There is a work around (see also See http://goo.gl/qu1wn) given below which appears to work on VS2010 and GCC, but
00158         //which seems to cause internal compiler errors on VS2008 when building with the /Gm 'Enable Minimal Rebuild' compiler
00159         //option. For now it seems best to 'fix' it with the preprocessor insstead, but maybe the workaround can be reinstated
00160         //in the future
00161         //typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences.
00162         //class Sampler : public VolumeOfVoxelType::template Sampler< LargeVolume<VoxelType> >
00163 #if defined(_MSC_VER)
00164         class Sampler : public BaseVolume<VoxelType>::Sampler< LargeVolume<VoxelType> > //This line works on VS2010
00165 #else
00166                 class Sampler : public BaseVolume<VoxelType>::template Sampler< LargeVolume<VoxelType> > //This line works on GCC
00167 #endif
00168         {
00169         public:
00170             Sampler(LargeVolume<VoxelType>* volume);
00171             ~Sampler();
00172 
00173             Sampler& operator=(const Sampler& rhs) throw();
00174 
00175             int32_t getPosX(void) const;
00176             int32_t getPosY(void) const;
00177             int32_t getPosZ(void) const;
00178             VoxelType getSubSampledVoxel(uint8_t uLevel) const;
00179             inline VoxelType getVoxel(void) const;          
00180 
00181             void setPosition(const Vector3DInt32& v3dNewPos);
00182             void setPosition(int32_t xPos, int32_t yPos, int32_t zPos);
00183             inline bool setVoxel(VoxelType tValue);
00184 
00185             void movePositiveX(void);
00186             void movePositiveY(void);
00187             void movePositiveZ(void);
00188 
00189             void moveNegativeX(void);
00190             void moveNegativeY(void);
00191             void moveNegativeZ(void);
00192 
00193             inline VoxelType peekVoxel1nx1ny1nz(void) const;
00194             inline VoxelType peekVoxel1nx1ny0pz(void) const;
00195             inline VoxelType peekVoxel1nx1ny1pz(void) const;
00196             inline VoxelType peekVoxel1nx0py1nz(void) const;
00197             inline VoxelType peekVoxel1nx0py0pz(void) const;
00198             inline VoxelType peekVoxel1nx0py1pz(void) const;
00199             inline VoxelType peekVoxel1nx1py1nz(void) const;
00200             inline VoxelType peekVoxel1nx1py0pz(void) const;
00201             inline VoxelType peekVoxel1nx1py1pz(void) const;
00202 
00203             inline VoxelType peekVoxel0px1ny1nz(void) const;
00204             inline VoxelType peekVoxel0px1ny0pz(void) const;
00205             inline VoxelType peekVoxel0px1ny1pz(void) const;
00206             inline VoxelType peekVoxel0px0py1nz(void) const;
00207             inline VoxelType peekVoxel0px0py0pz(void) const;
00208             inline VoxelType peekVoxel0px0py1pz(void) const;
00209             inline VoxelType peekVoxel0px1py1nz(void) const;
00210             inline VoxelType peekVoxel0px1py0pz(void) const;
00211             inline VoxelType peekVoxel0px1py1pz(void) const;
00212 
00213             inline VoxelType peekVoxel1px1ny1nz(void) const;
00214             inline VoxelType peekVoxel1px1ny0pz(void) const;
00215             inline VoxelType peekVoxel1px1ny1pz(void) const;
00216             inline VoxelType peekVoxel1px0py1nz(void) const;
00217             inline VoxelType peekVoxel1px0py0pz(void) const;
00218             inline VoxelType peekVoxel1px0py1pz(void) const;
00219             inline VoxelType peekVoxel1px1py1nz(void) const;
00220             inline VoxelType peekVoxel1px1py0pz(void) const;
00221             inline VoxelType peekVoxel1px1py1pz(void) const;
00222 
00223         private:
00224             //Other current position information
00225             VoxelType* mCurrentVoxel;
00226         };
00227 
00228         // Make the ConstVolumeProxy a friend
00229         friend class ConstVolumeProxy<VoxelType>;
00230 
00231         struct LoadedBlock
00232         {
00233         public:
00234             LoadedBlock(uint16_t uSideLength = 0)
00235                 :block(uSideLength)
00236                 ,timestamp(0)
00237             {
00238             }
00239 
00240             Block<VoxelType> block;
00241             uint32_t timestamp;
00242         };
00243 
00244     public:     
00246         LargeVolume
00247         (
00248             polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler,
00249             polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler,
00250             uint16_t uBlockSideLength = 32
00251         );
00253         LargeVolume
00254         (
00255             const Region& regValid,
00256             polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler = 0,
00257             polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler = 0,
00258             bool bPagingEnabled = false,
00259             uint16_t uBlockSideLength = 32
00260         );
00262         LargeVolume
00263         (
00264             int32_t dont_use_this_constructor_1, int32_t dont_use_this_constructor_2, int32_t dont_use_this_constructor_3
00265         );
00267         ~LargeVolume();
00268 
00270         VoxelType getBorderValue(void) const;
00272         VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const;
00274         VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
00275 
00276         //Sets whether or not blocks are compressed in memory
00277         void setCompressionEnabled(bool bCompressionEnabled);
00279         void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks);
00281         void setMaxNumberOfBlocksInMemory(uint32_t uMaxNumberOfBlocksInMemory);
00283         void setBorderValue(const VoxelType& tBorder);
00285         bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
00287         bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
00289         void prefetch(Region regPrefetch);
00291         void flush(Region regFlush);
00293         void flushAll();
00294 
00296         void clearBlockCache(void);
00298         float calculateCompressionRatio(void);
00300         uint32_t calculateSizeInBytes(void);
00301 
00303         void resize(const Region& regValidRegion, uint16_t uBlockSideLength);
00304 
00305 private:
00309         polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> m_funcDataRequiredHandler;
00314         polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> m_funcDataOverflowHandler;
00315     
00316         Block<VoxelType>* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const;
00317         void eraseBlock(typename std::map<Vector3DInt32, LoadedBlock >::iterator itBlock) const;
00319         bool setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const;
00320 
00321         //The block data
00322         mutable std::map<Vector3DInt32, LoadedBlock > m_pBlocks;
00323 
00324         //The cache of uncompressed blocks. The uncompressed block data and the timestamps are stored here rather
00325         //than in the Block class. This is so that in the future each VolumeIterator might to maintain its own cache
00326         //of blocks. However, this could mean the same block data is uncompressed and modified in more than one
00327         //location in memory... could be messy with threading.
00328         mutable std::vector< LoadedBlock* > m_vecUncompressedBlockCache;
00329         mutable uint32_t m_uTimestamper;
00330         mutable Vector3DInt32 m_v3dLastAccessedBlockPos;
00331         mutable Block<VoxelType>* m_pLastAccessedBlock;
00332         uint32_t m_uMaxNumberOfUncompressedBlocks;
00333         uint32_t m_uMaxNumberOfBlocksInMemory;
00334 
00335         //We don't store an actual Block for the border, just the uncompressed data. This is partly because the border
00336         //block does not have a position (so can't be passed to getUncompressedBlock()) and partly because there's a
00337         //good chance we'll often hit it anyway. It's a chunk of homogenous data (rather than a single value) so that
00338         //the VolumeIterator can do it's usual pointer arithmetic without needing to know it's gone outside the volume.
00339         VoxelType* m_pUncompressedBorderData;
00340 
00341         //The size of the volume
00342         Region m_regValidRegionInBlocks;
00343 
00344         //The size of the blocks
00345         uint16_t m_uBlockSideLength;
00346         uint8_t m_uBlockSideLengthPower;
00347 
00348         bool m_bCompressionEnabled;
00349         bool m_bPagingEnabled;
00350     };
00351 }
00352 
00353 #include "PolyVoxCore/LargeVolume.inl"
00354 #include "PolyVoxCore/LargeVolumeSampler.inl"
00355 
00356 #endif //__PolyVox_LargeVolume_H__

Generated on Sat Nov 19 2011 00:27:30 for PolyVox by  doxygen 1.7.1