3rdparty/polyvox, impl/voxel_volume: Optimize

master
Perttu Ahola 2014-10-12 21:10:49 +03:00
parent a0ea7feea8
commit 19cb1abe32
4 changed files with 62 additions and 24 deletions

View File

@ -139,6 +139,11 @@ namespace PolyVox
/// Calculates approximatly how many bytes of memory the volume is currently using.
uint32_t calculateSizeInBytes(void);
//The block data
VoxelType* m_pData;
size_t m_dataSize;
protected:
/// Copy constructor
RawVolume(const RawVolume& rhs);
@ -149,9 +154,6 @@ namespace PolyVox
private:
void initialise(const Region& regValidRegion);
//The block data
VoxelType* m_pData;
//The border value
VoxelType m_tBorderValue;
};

View File

@ -93,7 +93,24 @@ namespace PolyVox
template <typename VoxelType>
VoxelType RawVolume<VoxelType>::getVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos) const
{
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
// NOTE: Crazy-optimized version; probably behaves wrongly in corner
// cases which Buildat does not cause.
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
size_t i =
iLocalXPos +
iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight();
if(i >= m_dataSize)
return this->getBorderValue();
else
return m_pData[i];
// Original implementation
/*if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
{
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
@ -110,7 +127,7 @@ namespace PolyVox
else
{
return this->getBorderValue();
}
}*/
}
////////////////////////////////////////////////////////////////////////////////
@ -142,7 +159,25 @@ namespace PolyVox
template <typename VoxelType>
bool RawVolume<VoxelType>::setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue)
{
if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
// NOTE: Crazy-optimized version; probably behaves wrongly in corner
// cases which Buildat does not cause.
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
int32_t iLocalYPos = uYPos - v3dLowerCorner.getY();
int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ();
size_t i =
iLocalXPos +
iLocalYPos * this->getWidth() +
iLocalZPos * this->getWidth() * this->getHeight();
if(i >= m_dataSize)
return false;
m_pData[i] = tValue;
return true;
// Original implementation
/*if(this->m_regValidRegion.containsPoint(Vector3DInt32(uXPos, uYPos, uZPos)))
{
const Vector3DInt32& v3dLowerCorner = this->m_regValidRegion.getLowerCorner();
int32_t iLocalXPos = uXPos - v3dLowerCorner.getX();
@ -162,7 +197,7 @@ namespace PolyVox
else
{
return false;
}
}*/
}
////////////////////////////////////////////////////////////////////////////////
@ -191,6 +226,8 @@ namespace PolyVox
//Create the data
m_pData = new VoxelType[this->getWidth() * this->getHeight()* this->getDepth()];
// Store this so it doesn't need to be calculated again
m_dataSize = this->getWidth() * this->getHeight() * this->getDepth();
//Other properties we might find useful later
this->m_uLongestSideLength = (std::max)((std::max)(this->getWidth(),this->getHeight()),this->getDepth());
@ -204,7 +241,7 @@ namespace PolyVox
template <typename VoxelType>
uint32_t RawVolume<VoxelType>::calculateSizeInBytes(void)
{
return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType);
return m_dataSize * sizeof(VoxelType);
}
}

View File

@ -12,3 +12,9 @@ Stripped out floody messages from CMakeLists.txt
Various changes in CMakeLists.txt on various subdirectory levels.
Perforamnce tweaks:
- public RawVolume::m_pData
- add RawVolume::m_dataSize
- optimize RawVolume::getVoxelAt() and RawVolume::setVoxelAt() in a way that
does not handle edge cases properly

View File

@ -19,12 +19,10 @@ ss_ serialize_volume_simple(const pv::RawVolume<VoxelInstance> &volume)
auto region = volume.getEnclosingRegion();
auto lc = region.getLowerCorner();
auto uc = region.getUpperCorner();
for(int z = lc.getZ(); z <= uc.getZ(); z++){
for(int y = lc.getY(); y <= uc.getY(); y++){
for(int x = lc.getX(); x <= uc.getX(); x++){
ar((uint32_t)volume.getVoxelAt(x, y, z).data);
}
}
size_t size = volume.getWidth() * volume.getHeight() * volume.getDepth();
for(size_t i=0; i<size; i++){
const VoxelInstance &v = volume.m_pData[i];
ar((uint32_t)v.data);
}
}
return os.str();
@ -53,16 +51,11 @@ up_<pv::RawVolume<VoxelInstance>> deserialize_volume(const ss_ &data)
pv::Region region(0, 0, 0, w-1, h-1, d-1);
up_<pv::RawVolume<VoxelInstance>> volume(
new pv::RawVolume<VoxelInstance>(region));
auto lc = region.getLowerCorner();
auto uc = region.getUpperCorner();
for(int z = lc.getZ(); z <= uc.getZ(); z++){
for(int y = lc.getY(); y <= uc.getY(); y++){
for(int x = lc.getX(); x <= uc.getX(); x++){
uint32_t v;
ar(v);
volume->setVoxelAt(x, y, z, VoxelInstance(v));
}
}
size_t size = volume->getWidth() * volume->getHeight() * volume->getDepth();
for(size_t i=0; i<size; i++){
uint32_t v;
ar(v);
volume->m_pData[i].data = v;
}
return volume;
}