Added ConstVolumeProxy to work around const setVoxelAt awkwardness.
This commit is contained in:
parent
7c3e63b2ed
commit
0b1659bdef
@ -506,7 +506,7 @@ void createSphereInVolume(Volume<MaterialDensityPair44>& volData, Vector3DFloat
|
||||
}
|
||||
}
|
||||
|
||||
void load(const Volume<MaterialDensityPair44>& volume, PolyVox::Region reg)
|
||||
void load(const ConstVolumeProxy<MaterialDensityPair44>& volume, const PolyVox::Region& reg)
|
||||
{
|
||||
Perlin perlin(2,2,1,234);
|
||||
|
||||
@ -541,12 +541,12 @@ void load(const Volume<MaterialDensityPair44>& volume, PolyVox::Region reg)
|
||||
voxel.setDensity(MaterialDensityPair44::getMinDensity());
|
||||
}
|
||||
|
||||
volume.load_setVoxelAt(x, y, z, voxel);
|
||||
volume.setVoxelAt(x, y, z, voxel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void unload(const Volume<MaterialDensityPair44>& vol, PolyVox::Region reg)
|
||||
void unload(const ConstVolumeProxy<MaterialDensityPair44>& vol, const PolyVox::Region& reg)
|
||||
{
|
||||
std::cout << "warning unloading region: " << reg.getLowerCorner() << " -> " << reg.getUpperCorner() << std::endl;
|
||||
}
|
||||
@ -564,10 +564,10 @@ int main(int argc, char *argv[])
|
||||
//If these two lines don't compile, please try commenting them out and using the two lines after
|
||||
//(you will need Boost for this). If you have to do this then please let us know in the forums as
|
||||
//we rely on community feedback to keep the Boost version running.
|
||||
volData.m_LoadCallback = &load;
|
||||
volData.m_UnloadCallback = &unload;
|
||||
//volData.m_LoadCallback = polyvox_bind(&load, polyvox_placeholder_1, polyvox_placeholder_2);
|
||||
//volData.m_UnloadCallback = polyvox_bind(&unload, polyvox_placeholder_1, polyvox_placeholder_2);
|
||||
volData.dataRequiredHandler = &load;
|
||||
volData.dataOverflowHandler = &unload;
|
||||
//volData.dataRequiredHandler = polyvox_bind(&load, polyvox_placeholder_1, polyvox_placeholder_2);
|
||||
//volData.dataOverflowHandler = polyvox_bind(&unload, polyvox_placeholder_1, polyvox_placeholder_2);
|
||||
|
||||
volData.setBlockCacheSize(4096);
|
||||
//createSphereInVolume(volData, 30);
|
||||
|
@ -22,6 +22,7 @@ SET(CORE_INC_FILES
|
||||
include/ArraySizes.h
|
||||
include/AStarPathfinder.h
|
||||
include/AStarPathfinder.inl
|
||||
include/ConstVolumeProxy.h
|
||||
include/CubicSurfaceExtractor.h
|
||||
include/CubicSurfaceExtractor.inl
|
||||
include/CubicSurfaceExtractorWithNormals.h
|
||||
|
73
library/PolyVoxCore/include/ConstVolumeProxy.h
Normal file
73
library/PolyVoxCore/include/ConstVolumeProxy.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*******************************************************************************
|
||||
Copyright (c) 2005-2009 David 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_ConstVolumeProxy_H__
|
||||
#define __PolyVox_ConstVolumeProxy_H__
|
||||
|
||||
#include "PolyVoxForwardDeclarations.h"
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
template <typename VoxelType>
|
||||
class ConstVolumeProxy
|
||||
{
|
||||
//Volume is a friend so it can call the constructor.
|
||||
friend class Volume<VoxelType>;
|
||||
public:
|
||||
VoxelType getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
|
||||
{
|
||||
assert(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
||||
return m_pVolume.getVoxelAt(uXPos, uYPos, uZPos);
|
||||
}
|
||||
|
||||
VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const
|
||||
{
|
||||
assert(m_regValid.containsPoint(v3dPos));
|
||||
return getVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
void setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
{
|
||||
assert(m_regValid.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)));
|
||||
m_pVolume.setVoxelAtConst(uXPos, uYPos, uZPos, tValue);
|
||||
}
|
||||
|
||||
void setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue) const
|
||||
{
|
||||
assert(m_regValid.containsPoint(v3dPos));
|
||||
setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
|
||||
}
|
||||
private:
|
||||
//Private constructor, so client code can't abuse this class.
|
||||
ConstVolumeProxy(const Volume<VoxelType>& pVolume, const Region& regValid)
|
||||
:m_pVolume(pVolume)
|
||||
,m_regValid(regValid)
|
||||
{
|
||||
}
|
||||
|
||||
const Volume<VoxelType>& m_pVolume;
|
||||
const Region& m_regValid;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__PolyVox_ConstVolumeProxy_H__
|
@ -60,6 +60,8 @@ namespace PolyVox
|
||||
|
||||
template <typename VoxelType> class Block;
|
||||
|
||||
template <typename VoxelType> class ConstVolumeProxy;
|
||||
|
||||
//---------- Volume ----------
|
||||
template <typename VoxelType> class Volume;
|
||||
typedef Volume<float> FloatVolume;
|
||||
|
@ -112,6 +112,8 @@ namespace PolyVox
|
||||
{
|
||||
// Make VolumeSampler a friend
|
||||
friend class VolumeSampler<VoxelType>;
|
||||
// Make the ConstVolumeProxy a friend
|
||||
friend class ConstVolumeProxy<VoxelType>;
|
||||
|
||||
struct UncompressedBlock
|
||||
{
|
||||
@ -171,17 +173,17 @@ namespace PolyVox
|
||||
/// gets called when a new region is allocated and needs to be filled
|
||||
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
||||
/// is absolutely unsafe
|
||||
polyvox_function<void(const Volume<VoxelType>&, Region)> m_LoadCallback;
|
||||
/// this function can be called by m_LoadCallback without causing any weird effects
|
||||
bool load_setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const;
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataRequiredHandler;
|
||||
/// gets called when a Region needs to be stored by the user, because Volume will erase it right after
|
||||
/// this function returns
|
||||
/// NOTE: accessing ANY voxels outside this region during the process of this function
|
||||
/// is absolutely unsafe
|
||||
polyvox_function<void(const Volume<VoxelType>&, Region)> m_UnloadCallback;
|
||||
polyvox_function<void(const ConstVolumeProxy<VoxelType>&, const Region&)> dataOverflowHandler;
|
||||
private:
|
||||
Block<VoxelType>* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const;
|
||||
void eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itBlock) const;
|
||||
/// this function can be called by dataRequiredHandler without causing any weird effects
|
||||
bool setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const;
|
||||
|
||||
//The block data
|
||||
mutable std::map<Vector3DInt32, Block<VoxelType> > m_pBlocks;
|
||||
@ -195,7 +197,6 @@ namespace PolyVox
|
||||
mutable uint32_t m_uTimestamper;
|
||||
mutable Vector3DInt32 m_v3dLastAccessedBlockPos;
|
||||
mutable Block<VoxelType>* m_pLastAccessedBlock;
|
||||
mutable Vector3DInt32 m_v3dLoadBlockPos;
|
||||
uint32_t m_uMaxUncompressedBlockCacheSize;
|
||||
uint32_t m_uMaxBlocksLoaded;
|
||||
|
||||
|
@ -21,6 +21,7 @@ freely, subject to the following restrictions:
|
||||
distribution.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ConstVolumeProxy.h"
|
||||
#include "PolyVoxImpl/Block.h"
|
||||
#include "Log.h"
|
||||
#include "VolumeSampler.h"
|
||||
@ -399,28 +400,30 @@ namespace PolyVox
|
||||
template <typename VoxelType>
|
||||
void Volume<VoxelType>::eraseBlock(typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itBlock) const
|
||||
{
|
||||
Vector3DInt32 v3dPos = itBlock->first;
|
||||
Vector3DInt32 v3dLower(v3dPos.getX() << m_uBlockSideLengthPower, v3dPos.getY() << m_uBlockSideLengthPower, v3dPos.getZ() << m_uBlockSideLengthPower);
|
||||
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1);
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
if(m_UnloadCallback) {
|
||||
m_UnloadCallback(std::ref(*this), reg);
|
||||
if(dataOverflowHandler)
|
||||
{
|
||||
Vector3DInt32 v3dPos = itBlock->first;
|
||||
Vector3DInt32 v3dLower(v3dPos.getX() << m_uBlockSideLengthPower, v3dPos.getY() << m_uBlockSideLengthPower, v3dPos.getZ() << m_uBlockSideLengthPower);
|
||||
Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uBlockSideLength-1, m_uBlockSideLength-1, m_uBlockSideLength-1);
|
||||
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
ConstVolumeProxy<VoxelType> ConstVolumeProxy(*this, reg);
|
||||
|
||||
dataOverflowHandler(ConstVolumeProxy, reg);
|
||||
}
|
||||
m_pBlocks.erase(itBlock);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
bool Volume<VoxelType>::load_setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
bool Volume<VoxelType>::setVoxelAtConst(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue) const
|
||||
{
|
||||
//We don't have any range checks in this function because it
|
||||
//is a private function only called by the ConstVolumeProxy. The
|
||||
//ConstVolumeProxy takes care of ensuring the range is appropriate.
|
||||
|
||||
const int32_t blockX = uXPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockY = uYPos >> m_uBlockSideLengthPower;
|
||||
const int32_t blockZ = uZPos >> m_uBlockSideLengthPower;
|
||||
assert(blockX == m_v3dLoadBlockPos.getX());
|
||||
assert(blockY == m_v3dLoadBlockPos.getY());
|
||||
assert(blockZ == m_v3dLoadBlockPos.getZ());
|
||||
if(blockX != m_v3dLoadBlockPos.getX() && blockY != m_v3dLoadBlockPos.getY() && blockZ != m_v3dLoadBlockPos.getZ()) {
|
||||
throw(std::invalid_argument("you are not allowed to write to any voxels outside the designated region"));
|
||||
}
|
||||
|
||||
const uint16_t xOffset = uXPos - (blockX << m_uBlockSideLengthPower);
|
||||
const uint16_t yOffset = uYPos - (blockY << m_uBlockSideLengthPower);
|
||||
@ -462,7 +465,8 @@ namespace PolyVox
|
||||
typename std::map<Vector3DInt32, Block<VoxelType> >::iterator itUnloadBlock = m_pBlocks.begin();
|
||||
for(i = m_pBlocks.begin(); i != m_pBlocks.end(); i++)
|
||||
{
|
||||
if(i->second.m_uTimestamp < itUnloadBlock->second.m_uTimestamp) {
|
||||
if(i->second.m_uTimestamp < itUnloadBlock->second.m_uTimestamp)
|
||||
{
|
||||
itUnloadBlock = i;
|
||||
}
|
||||
}
|
||||
@ -470,20 +474,21 @@ 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);
|
||||
|
||||
// create the new block
|
||||
Block<VoxelType> newBlock(m_uBlockSideLength);
|
||||
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
||||
|
||||
// fill it with data (well currently fill it with nothingness)
|
||||
// "load" will actually call setVoxel, which will in turn call this function again but the block will be found
|
||||
// so this if(itBlock == m_pBlocks.end()) never is entered
|
||||
// so this if(itBlock == m_pBlocks.end()) never is entered
|
||||
|
||||
m_v3dLoadBlockPos = v3dBlockPos;
|
||||
if(m_LoadCallback) {
|
||||
m_LoadCallback(std::ref(*this), reg);
|
||||
if(dataRequiredHandler)
|
||||
{
|
||||
Region reg(v3dLower, v3dUpper);
|
||||
ConstVolumeProxy<VoxelType> ConstVolumeProxy(*this, reg);
|
||||
dataRequiredHandler(ConstVolumeProxy, reg);
|
||||
}
|
||||
m_v3dLoadBlockPos = Vector3DInt32((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)());
|
||||
}
|
||||
|
||||
m_v3dLastAccessedBlockPos = v3dBlockPos;
|
||||
|
Loading…
x
Reference in New Issue
Block a user